diff options
| author | navewindre <nw@moneybot.cc> | 2024-07-12 00:55:39 +0200 |
|---|---|---|
| committer | navewindre <nw@moneybot.cc> | 2024-07-12 00:55:39 +0200 |
| commit | 2ebf959ec02048c15323e1bbfc63faedcf5067b6 (patch) | |
| tree | 18862ba5d3b4be44294c0a81317d31eace7ee150 /src | |
| parent | ecca2728f1a583ea484f8bdcda390a30e4906f1d (diff) | |
ha haaa
Diffstat (limited to 'src')
47 files changed, 6517 insertions, 0 deletions
diff --git a/src/asmutil.h b/src/asmutil.h new file mode 100644 index 0000000..8e13b98 --- /dev/null +++ b/src/asmutil.h @@ -0,0 +1,23 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#define db( x ) __asm _emit x + +#define heavens_gate_enter() \ +db( 0x6a ) db( 0x33 ) /*push 0x33*/ \ +db( 0xe8 ) db( 0x0 ) db( 0x0 ) db( 0x0 ) db( 0x0 ) /*call rel32 0x0*/ \ +db( 0x83 ) db( 0x4 ) db( 0x24 ) db( 0x5 ) /*add dword ptr[ esp ], 0x5*/ \ +db( 0xcb ) /*retf - pop ip and cs*/ + +#define heavens_gate_exit() \ +db( 0xe8 ) db( 0x0 ) db( 0x0 ) db( 0x0 ) db( 0x0 ) /*call rel32 0x0*/ \ +db( 0xc7 ) db( 0x44 ) db( 0x24 ) db( 0x4 ) \ +db( 0x23 ) db( 0x0 ) db( 0x0 ) db( 0x0 ) /*mov dword ptr[ rsp + 0x4 ], 0x23 - return address hack (come back to wow64 cs)*/\ +db( 0x83 ) db( 0x4 ) db( 0x24 ) db( 0xd ) /*add dword ptr[ rsp ], 0xd*/ \ +db( 0xcb ) /*retf*/ + +#define rex_w db( 0x48 ) __asm +#define rex_wb db( 0x49 ) __asm +#define rex_wr db( 0x4c ) __asm +#define x64_push( x ) db( 0x48 | ( ( x ) >> 3 ) ) db( 0x50 | ( ( x ) & 7 ) ) +#define x64_pop( x ) db( 0x48 | ( ( x ) >> 3 ) ) db( 0x58 | ( ( x ) & 7 ) ) diff --git a/src/conin.cpp b/src/conin.cpp new file mode 100644 index 0000000..85c34fb --- /dev/null +++ b/src/conin.cpp @@ -0,0 +1,242 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include <windows.h> +#include "conin.h" +#include <cstdio> +#include "mathutil.h" +#include "process.h" +#include "csgo/csgoplayer.h" +#include "csgo/hack.h" + +U8* con_key_states = (U8*)malloc( 256 ); +bool con_capturing_input = false; + +U32 con_captured_key = NULL; +bool con_capturing_key = false; +bool con_enable_hook = false; +HHOOK con_keybdhook = NULL; +HHOOK con_mousehook = NULL; + +void con_update_hotkey( U8 line , I32 &hk) { + con_capturing_key = true; + con_enable_hook = true; + + con_set_line_subtext( + line, + "[...]", + true, + CONFG_LIGHTRED ); + + while( con_capturing_key ) { + Sleep( 100 ); + } + + if( con_captured_key!=0x1B ) + hk = con_captured_key; + + con_set_line_subtext( + line, + key_titles[hk], + true, + CONFG_LIGHTBLUE ); +} + +I8 con_find_nearest_line( I8 cur, bool reverse ) { + if( reverse ) { + if( cur <= 0 ) + return -1; + + for( I8 i = cur - 1; i >= 0; --i ) { + if( con_lines[i].line_num != -1 ) + return i; + } + } + else { + if( cur >= CON_MAX_HEIGHT ) + return -1; + + for( I8 i = cur + 1; i < CON_MAX_HEIGHT; ++i ) { + if( con_lines[i].line_num != -1 ) + return i; + } + } + + return -1; +} + +void con_line_change_callback( U8 prev, U8 current ) { + con_lines[prev].active = false; + con_lines[current].active = true; + + con_print_line( prev ); + con_print_line( current ); +} + +void con_handle_ui_event( CON_EVENT e ) { + if( !con_capturing_input ) + return; + + if( con_key_states[e.keycode] || !e.state ) + return; + + I8 prev_line = con_selected_line; + I8 line = -1; + + switch( e.keycode ) { + case VK_UP: + if( ( line = con_find_nearest_line( (I8)con_selected_line, true ) ) == -1 ) + return; + + con_line_change_callback( prev_line, con_selected_line = line ); + return; + case VK_DOWN: + if( ( line = con_find_nearest_line( (I8)con_selected_line, false ) ) == -1 ) + return; + + con_line_change_callback( prev_line, con_selected_line = line ); + return; + case VK_LEFT: + case VK_RIGHT: + case VK_RETURN: + { + CON_LINE* line = &con_lines[con_selected_line]; + if( !line->callback || line->line_num == -1 ) + return; + + U8 con_event = (e.keycode == VK_RETURN)? LINE_ACTION_ENTER : + (e.keycode == VK_LEFT)? LINE_ACTION_LEFTARROW : LINE_ACTION_RIGHTARROW; + + line->callback( line, con_event ); + } + } +} + +void con_parse_event( CON_EVENT e ) { + switch( e.keycode ) { + case VK_UP: + case VK_DOWN: + case VK_LEFT: + case VK_RIGHT: + case VK_RETURN: + con_handle_ui_event( e ); + default: + con_key_states[e.keycode] = e.state; break; + } +} + +void con_parse_events( HANDLE stdi ) { + INPUT_RECORD records[64]; + ULONG count; + + if( !ReadConsoleInputA( stdi, records, 64, &count ) ) + return; + + for( U32 i = 0; i < count; ++i ) { + INPUT_RECORD* r = &records[i]; + + if( r->EventType != KEY_EVENT ) + continue; + + CON_EVENT e; + + e.state = !r->Event.KeyEvent.bKeyDown; + e.keycode = r->Event.KeyEvent.wVirtualKeyCode; + + con_parse_event( e ); + } +} + +ULONG __stdcall con_handler( void* ) { + HANDLE stdi = GetStdHandle( STD_INPUT_HANDLE ); + for( ;; ) { + con_parse_events( stdi ); + + Sleep( 1 ); + } +} + +LRESULT CALLBACK con_khook_callback( int n,WPARAM w,LPARAM l ) +{ + KBDLLHOOKSTRUCT key = *((KBDLLHOOKSTRUCT *) l); + if( con_capturing_key && w == WM_KEYDOWN ) { + if( key.vkCode == 0x0D || + key.vkCode == 0x26 || + key.vkCode == 0x28 ) { + return 1; + } + + con_capturing_key = false; + con_captured_key = key.vkCode; + PostQuitMessage( 0 ); + } + return CallNextHookEx( con_keybdhook, n, w, l ); +} + +LRESULT CALLBACK con_mhook_callback( int n,WPARAM w,LPARAM l ) +{ + MSLLHOOKSTRUCT mos = *((MSLLHOOKSTRUCT *) l); + if( con_capturing_key ) { + switch( w ) { + case WM_LBUTTONDOWN: + con_captured_key = 1; + con_capturing_key = false; + break; + + case WM_RBUTTONDOWN: + con_captured_key = 2; + con_capturing_key = false; + break; + + case WM_MBUTTONDOWN: + con_captured_key = 4; + con_capturing_key = false; + break; + + case WM_XBUTTONDOWN: + MSLLHOOKSTRUCT *info = reinterpret_cast<MSLLHOOKSTRUCT *>( l ); + I16 xb = HIWORD( info->mouseData ); + con_captured_key = xb + 0x4; + con_capturing_key = false; + break; + } + if( !con_capturing_key ) + PostQuitMessage( 0 ); + } + return CallNextHookEx( con_mousehook, n, w, l ); +} + +ULONG __stdcall con_hook_handler( void* ) { + HINSTANCE con_hinstance = GetModuleHandle( NULL ); + MSG con_inputMsg; + + for( ;;) { + if( con_enable_hook ) { + + con_keybdhook = SetWindowsHookExW( + WH_KEYBOARD_LL, + con_khook_callback, + con_hinstance, + 0 ); + + con_mousehook = SetWindowsHookExW( + WH_MOUSE_LL, + con_mhook_callback, + con_hinstance, + 0 ); + + while( GetMessage( &con_inputMsg,NULL,0,0 ) ) + { + TranslateMessage( &con_inputMsg ); + DispatchMessageA( &con_inputMsg ); + } + + UnhookWindowsHookEx( con_keybdhook ); + UnhookWindowsHookEx( con_mousehook ); + con_enable_hook = false; + } + Sleep( 1 ); + } + + return 0; +} diff --git a/src/conin.h b/src/conin.h new file mode 100644 index 0000000..26cf625 --- /dev/null +++ b/src/conin.h @@ -0,0 +1,304 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once + +#include "conout.h" + +enum ConEventType_t { + EVENT_NONE = -1, + EVENT_KEYDOWN = 0, + EVENT_KEYUP = 1, +}; + +struct CON_EVENT { + I32 keycode; + I32 state; +}; + +extern U8* con_key_states; +extern bool con_capturing_input; + +extern void con_update_hotkey( U8 line , I32 &var ); + +extern ULONG __stdcall con_handler( void* ); +extern ULONG __stdcall con_hook_handler( void * ); + +static const I8 *key_titles[]={ + // 8 bytes - index maps to keycode + "[ 0x0 ]", //0x00 + + "[ M-1 ]",//0x01 + "[ M-2 ]", + "[?????]", + "[ M-3 ]", + "[ M-4 ]", + "[ M-5 ]", + "[?????]", + "[BKSPC]", + "[ TAB ]", + "[?????]", //0x0A + "[?????]", + "[CLEAR]", + "[ENTER]", + "[?????]", + "[?????]", + "[SHIFT]", + "[ CTL ]", + "[ ALT ]", + "[PAUSE]", + "[ CAP ]", + + "[?????]",//0x15 - 0x1A + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + + "[ ESC ]", + + "[?????]",//0x1B - 0x1F + "[?????]", + "[?????]", + "[?????]", + + "[SPACE]", + "[PG UP]", + "[PG DN]", + "[ END ]", + "[ HOM ]", + "[aLEFT]", + "[ aUP ]", + "[aRGHT]", + "[aDOWN]", + "[ SEL ]", + "[PRINT]", + "[?????]", + "[PRTSC]", + "[ INS ]", + "[ DEL ]", + "[?????]", + + "[ 0 ]",//0x30 + "[ 1 ]", + "[ 2 ]", + "[ 3 ]", + "[ 4 ]", + "[ 5 ]", + "[ 6 ]", + "[ 7 ]", + "[ 8 ]", + "[ 9 ]", + + "[?????]",//0x3A + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + + "[ A ]",//0x41 + "[ B ]", + "[ C ]", + "[ D ]", + "[ E ]", + "[ F ]", + "[ G ]", + "[ H ]", + "[ I ]", + "[ J ]", + "[ K ]", + "[ L ]", + "[ M ]", + "[ N ]", + "[ O ]", + "[ P ]", + "[ Q ]", + "[ R ]", + "[ S ]", + "[ T ]", + "[ U ]", + "[ V ]", + "[ W ]", + "[ X ]", + "[ Y ]", + "[ Z ]", + + "[L WIN]",//0x5B + "[R WIN]", + "[?????]", + "[?????]", + "[?????]", + + "[NUM 0]", + "[NUM 1]", + "[NUM 2]", + "[NUM 3]", + "[NUM 4]", + "[NUM 5]", + "[NUM 6]", + "[NUM 7]", + "[NUM 8]", + "[NUM 9]", + "[NUM *]", + "[NUM +]", + "[?????]", + "[NUM -]", + "[NUM .]", + "[NUM /]", + + "[ F.1 ]",//0x70 + "[ F.2 ]", + "[ F.3 ]", + "[ F.4 ]", + "[ F.5 ]", + "[ F.6 ]", + "[ F.7 ]", + "[ F.8 ]", + "[ F.9 ]", + "[ F10 ]", + "[ F11 ]", + "[ F12 ]", + "[ F13 ]", + "[ F14 ]", + "[ F15 ]", + "[ F16 ]", + "[ F17 ]", + "[ F18 ]", + "[ F19 ]", + "[ F20 ]", + "[ F21 ]", + "[ F22 ]", + "[ F23 ]", + "[ F24 ]", + + "[?????]",//0x88-0x8F + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + + "[NUMLK]", + "[SCRLK]", + + "[?????]",//0x92-0x9F + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + + "[LSHFT]", + "[RSHFT]", + "[LCTRL]", + "[RCTRL]", + "[L ALT]", + "[R ALT]", + + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + + "[ ; ]", + "[ = ]", + "[ , ]", + "[ - ]", + "[ . ]", + "[ / ]", + "[ ~ ]", + + "[?????]",//0xC1 - 0xDA + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + + "[ [ ]", + "[ | ]", + "[ ] ]", + "[ ' ]", + + "[?????]",//0xDF - 0xFE + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]", + "[?????]" +}; diff --git a/src/conout.cpp b/src/conout.cpp new file mode 100644 index 0000000..7fb461b --- /dev/null +++ b/src/conout.cpp @@ -0,0 +1,333 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include <windows.h> +#include <stdio.h> +#include <malloc.h> + +#include "mathutil.h" +#include "util.h" +#include "conout.h" + + +CRITICAL_SECTION con_mutex; +CON_LINE* con_lines = (CON_LINE*)malloc( sizeof( CON_LINE ) * ( CON_MAX_HEIGHT + 1 ) ); +U8 con_selected_line = 0; +bool con_assert = false; + +void con_init() { + AllocConsole(); + freopen( "CONOUT$","w",stdout ); + + if( !con_mutex.SpinCount ) { + InitializeCriticalSectionAndSpinCount( &con_mutex, 0x100 ); + } + + HWND con_handle = GetConsoleWindow(); + SetConsoleMode( + con_handle, + DISABLE_NEWLINE_AUTO_RETURN|ENABLE_WINDOW_INPUT|ENABLE_VIRTUAL_TERMINAL_INPUT + ); + + SetConsoleTitleA( "heaven's gate" ); + + for( U8 i = 0; i < CON_MAX_HEIGHT; ++i ) { + con_lines[i].line_num = -1; + } + + con_setpos( 0, 0 ); + con_resize( CON_WIDTH, CON_HEIGHT ); + con_print_title(); + + HANDLE stdo = GetStdHandle( STD_OUTPUT_HANDLE ); + + CONSOLE_CURSOR_INFO info; + GetConsoleCursorInfo( stdo, &info ); + info.bVisible = false; + SetConsoleCursorInfo( stdo, &info ); +} + +void setc( U8 c ) { + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), c ); +} + +void con_resize( U8 w, U8 h ) { + SMALL_RECT console_wnd{}; + console_wnd.Right = w; + console_wnd.Bottom = h; + + HANDLE std_handle = GetStdHandle( STD_OUTPUT_HANDLE ); + SetConsoleWindowInfo( std_handle, true, &console_wnd ); + SetConsoleScreenBufferSize( std_handle, COORD( w + 1, h + 1 ) ); + SetConsoleWindowInfo( std_handle,true,&console_wnd ); + + HWND con_handle = GetConsoleWindow(); + HMENU sys_menu = GetSystemMenu( con_handle, false ); + + if( sys_menu ) { + DeleteMenu( sys_menu, SC_MAXIMIZE, MF_BYCOMMAND ); + DeleteMenu( sys_menu, SC_SIZE, MF_BYCOMMAND ); + } +} + +void con_print_internal( U8 color, const char* text, ... ) { + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), color ); + va_list args; + va_start( args, text ); + vprintf_s( text, args ); + va_end( args ); +} + +void con_print( U8 color, const char* text, ... ) { + if( !con_mutex.SpinCount ) { + InitializeCriticalSectionAndSpinCount( &con_mutex, 0x100 ); + } + + EnterCriticalSection( &con_mutex ); + + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), color ); + va_list args; + va_start( args, text ); + vprintf_s( text, args ); + va_end( args ); + + LeaveCriticalSection( &con_mutex ); +} + +void con_print_title() { + con_print_internal( 133, " =============== [ heaven's gate ] =============== " ); + con_print_internal( 15, " [%s]\n", __DATE__ ); + con_print_internal( 15, "\n" ); +} + +void con_setpos( U8 x, U8 y ) { + HANDLE std_handle = GetStdHandle( STD_OUTPUT_HANDLE ); + SetConsoleCursorPosition( std_handle, COORD( x, y ) ); +} + +void con_print_line( U8 line ) { + EnterCriticalSection( &con_mutex ); + + CON_LINE* l = &con_lines[line]; + l->line_num = line; + + con_setpos( 0, CON_TITLE_HEIGHT + line + 1 ); + + U8 border_col = ( !l->active? CONFG_DARKGRAY : CONFG_WHITE ); + + con_print_internal( border_col, "\r = " ); + con_print_internal( l->text_col, l->text ); + + U8 spacing = CON_MAX_WIDTH - (U8)( strlen( l->text ) + strlen( l->subtext ) ); + char* spacer = (char*)_alloca( spacing + 1 ); + memset( spacer, ' ', spacing ); + spacer[spacing] = 0; + + con_print_internal( 0, spacer ); + if( l->subtext_col > 15 || !l->active ) + con_print_internal( l->subtext_col, l->subtext ); + else + con_print_internal( l->subtext_col + CONBG_DARKGRAY, l->subtext ); + + con_print_internal( border_col, " =" ); + LeaveCriticalSection( &con_mutex ); +} + +void con_set_line( U8 line, const char* text, const char* subtext, bool selected, U8 fg, U8 bg ) { + if( line > CON_MAX_HEIGHT ) + return; + + CON_LINE* l = &con_lines[line]; + strcpy( l->text, text ); + l->text_col = fg + bg; + strcpy( l->subtext, subtext ); + l->subtext_col = fg + bg; + l->active = selected; + + con_print_line( line ); +} + +void con_set_line_text( U8 line, const char* text, bool selected, U8 fg, U8 bg ) { + if( line > CON_MAX_HEIGHT ) + return; + + CON_LINE* l = &con_lines[line]; + strcpy( l->text, text ); + l->text_col = fg + bg; + l->active = selected; + + con_print_line( line ); +} + +void con_set_line_subtext( U8 line, const char* text, bool selected, U8 fg, U8 bg ) { + if( line > CON_MAX_HEIGHT ) + return; + + CON_LINE* l = &con_lines[line]; + strcpy( l->subtext, text ); + l->subtext_col = fg + bg; + l->active = selected; + + con_print_line( line ); +} + +void con_set_line_callback( U8 line, LINE_CALLBACK cb ) { + if( line > CON_MAX_HEIGHT ) + return; + + con_lines[line].callback = cb; +} + +void con_clear_line( U8 line ) { + EnterCriticalSection( &con_mutex ); + + CON_LINE* l = &con_lines[line]; + + l->line_num = -1; + l->active = false; + l->callback = nullptr; + l->subtext[0] = 0; + l->text[0] = 0; + + con_setpos( 0, CON_TITLE_HEIGHT + line + 1 ); + + char* spacer = (char*)_alloca( CON_WIDTH + 1 ); + memset( spacer, ' ', CON_WIDTH ); + spacer[CON_WIDTH] = 0; + + con_print_internal( 0, spacer ); + + LeaveCriticalSection( &con_mutex ); +} + +void con_clear() { + for( U8 i = 0; i < CON_MAX_HEIGHT; ++i ) + con_clear_line( i ); +} + +void con_set_bottomline_text( U8 color, const char* text, ... ) { + EnterCriticalSection( &con_mutex ); + if( con_assert ) + return; + + con_setpos( 0, CON_HEIGHT ); + setc( color ); + + char str_buffer[256]{}; + va_list args; + va_start( args, text ); + vsprintf_s( str_buffer, 256, text, args ); + va_end( args ); + + strcpy( con_lines[CON_MAX_HEIGHT].text, str_buffer ); + con_lines[CON_MAX_HEIGHT].text_col = color; + + U8 length = (U8)strlen( str_buffer ); + U8 spacing = CON_WIDTH - length + 1; + + memset( str_buffer + length, ' ', spacing ); + str_buffer[CON_WIDTH] = '\0'; + WriteConsoleA( GetStdHandle( STD_OUTPUT_HANDLE ), str_buffer, CON_WIDTH, 0, 0 ); + + LeaveCriticalSection( &con_mutex ); +} + +void con_set_bottomline_text( const char* text, ... ) { + if( con_assert ) + return; + + char str_buffer[256]{}; + va_list args; + va_start( args, text ); + vsprintf_s( str_buffer, 256, text, args ); + va_end( args ); + + con_set_bottomline_text( CONFG_BLACK + CONBG_LIGHTGRAY, str_buffer ); +} + +void con_set_assert( const char* text, ... ) { + char str_buffer[256]{}; + va_list args; + va_start( args, text ); + vsprintf_s( str_buffer, 256, text, args ); + va_end( args ); + + con_set_bottomline_text( CONFG_RED + CONBG_LIGHTGRAY, str_buffer ); + EnterCriticalSection( &con_mutex ); + con_assert = true; + LeaveCriticalSection( &con_mutex ); +} + + +void con_clear_bottomline_text() { + EnterCriticalSection( &con_mutex ); + + con_setpos( 0, CON_HEIGHT - 1 ); + + char* spacer = (char*)_alloca( CON_WIDTH + 1 ); + memset( spacer, ' ', CON_WIDTH ); + spacer[CON_WIDTH] = 0; + + con_print_internal( 0, spacer ); + + LeaveCriticalSection( &con_mutex ); +} + +void con_refresh() { + con_print_internal( 0, "\r" ); + system( "cls" ); + con_setpos( 0, 0 ); + con_print_title(); + for( U8 i = 0; i < CON_MAX_HEIGHT; ++i ) { + CON_LINE* line = &con_lines[i]; + + if( line->line_num != -1 || !!strlen( line->text ) ) + con_print_line( i ); + } + + CON_LINE* bottom_line = &con_lines[CON_MAX_HEIGHT]; + con_set_bottomline_text( bottom_line->text_col, bottom_line->text ); +} + + +STR<64> con_progressbar( F32 progress, U8 width ) { + static U64 last_call = u_tick(); + static U8 cur_spinner = 0; + static char spinner_anim[] = { + '-', + '\\', + '|', + '/', + '-', + '\\', + '|', + '/' + }; + + if( width <= 3 ) + return ""; + + STR<64> ret; + memset( ret.data, ' ', width ); + ret[width] = 0; + + ret[0] = '['; + ret[width - 1] = ']'; + + progress = u_clamp( progress, 0.f, 1.f ); + U8 total = (U8)( ( width - 1 ) * progress ); + for( U8 i = 1; i < total; ++i ) { + ret[i] = '='; + } + + if( progress < 1.0f ) { + if( u_tick() - last_call > 200 ) { + ++cur_spinner; + last_call = u_tick(); + } + + ret[total + 1] = spinner_anim[cur_spinner % sizeof(spinner_anim)]; + } + + return ret; +}
\ No newline at end of file diff --git a/src/conout.h b/src/conout.h new file mode 100644 index 0000000..3c6685b --- /dev/null +++ b/src/conout.h @@ -0,0 +1,150 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "util.h" +#include "typedef.h" + +#define clog( ... ) con_print( CONFG_WHITE, __VA_ARGS__ ) +#define clogc( x, ... ) con_print( x, __VA_ARGS__ ) + +constexpr U8 CON_WIDTH = 52; +constexpr U8 CON_HEIGHT = 16; +constexpr U8 CON_MAX_WIDTH = CON_WIDTH - 6; +constexpr U8 CON_MAX_HEIGHT = CON_HEIGHT - 5; +constexpr U8 CON_TITLE_HEIGHT = 4; +constexpr U8 LINE_INACTIVE = 0xff; + +enum ConsoleColFg_t { + CONFG_BLACK = 0, + CONFG_DARKBLUE, + CONFG_DARKGREEN, + CONFG_LIGHTBLUE, + CONFG_RED, + CONFG_PURPLE, + CONFG_GOLD, + CONFG_LIGHTGRAY, + CONFG_DARKGRAY, + CONFG_BLUE, + CONFG_LIGHTGREEN, + CONFG_CYAN, + CONFG_LIGHTRED, + CONFG_MAGENTA, + CONFG_YELLOW, + CONFG_WHITE +}; + +enum ConsoleColBg_t { + CONBG_BLACK = 0, + CONBG_DARKBLUE = 0x10, + CONBG_DARKGREEN = 0x20, + CONBG_LIGHTBLUE = 0x30, + CONBG_RED = 0x40, + CONBG_PURPLE = 0x50, + CONBG_GOLD = 0x60, + CONBG_LIGHTGRAY = 0x70, + CONBG_DARKGRAY = 0x80, + CONBG_BLUE = 0x90, + CONBG_LIGHTGREEN = 0xa0, + CONBG_CYAN = 0xb0, + CONBG_LIGHTRED = 0xc0, + CONBG_MAGENTA = 0xd0, + CONBG_YELLOW = 0xe0, + CONBG_WHITE = 0xf0 +}; + +enum LineActionType_t { + LINE_ACTION_ENTER, + LINE_ACTION_LEFTARROW, + LINE_ACTION_RIGHTARROW +}; + +typedef void( *LINE_CALLBACK )( struct CON_LINE* self, U8 action ); + +struct CON_LINE { + char text[CON_MAX_WIDTH + 1]; + char subtext[12]; + + U8 text_col = 15; + U8 subtext_col = 15; + I8 line_num; + + bool active; + LINE_CALLBACK callback; +}; + + +extern CON_LINE* con_lines; +extern U8 con_selected_line; + +extern void con_print_title(); +extern void con_resize( U8 w, U8 h ); +extern void con_setpos( U8 x, U8 y ); +extern void con_set_line_text( + U8 line, + const char* text, + bool selected = false, + U8 fg = CONFG_WHITE, + U8 bg = CONBG_BLACK +); + +extern void con_set_line_subtext( + U8 line, + const char* text, + bool selected = false, + U8 fg = CONFG_WHITE, + U8 bg = CONBG_BLACK +); + +extern void con_set_line( + U8 line, + const char* text, + const char* subtext, + bool selected = false, + U8 fg = CONFG_WHITE, + U8 bg = CONBG_BLACK +); + +extern void con_init(); +extern void con_set_line_callback( U8 line, LINE_CALLBACK cb ); +extern void con_set_bottomline_text( const char* text, ... ); +extern void con_set_bottomline_text( U8 color, const char* text, ... ); +extern void con_clear_bottomline_text(); +extern void con_clear_line( U8 line ); +extern void con_clear(); +extern void con_refresh(); +extern void con_print( U8 color, const char* text, ... ); +extern void con_print_line( U8 line ); +extern void con_set_assert( const char* text, ... ); + +inline STR<16> con_to_setting_str( bool setting ) { + return setting ? "[ON]" : "[OFF]"; +} + +inline STR<16> con_to_setting_str( F32 setting ) { + char buf[16]; + snprintf( buf, 16, "[%.02f]", (I32)( setting * 100 ) ); + + return buf; +} + +inline STR<16> con_to_setting_str( I32 setting ) { + char buf[16]; + snprintf( buf, 16, "[%d]", setting ); + + return buf; +} + +inline STR<16> con_to_setting_str( U32 setting ) { + char buf[16]; + snprintf( buf, 16, "[%u]", setting ); + + return buf; +} + +inline void con_print_colors() { + for( I16 i = 0; i <= 255; ++i ) + con_print( (U8)i, "%003d", i ); +} + +extern STR<64> con_progressbar( F32 progress, U8 width = CON_MAX_WIDTH ); diff --git a/src/csgo/console.cpp b/src/csgo/console.cpp new file mode 100644 index 0000000..0b16ceb --- /dev/null +++ b/src/csgo/console.cpp @@ -0,0 +1,100 @@ +#include "hack.h" +#include "../menu.h" + + +struct CMD_TOGGLE { + const char* name; + const char* desc; + SETTING<bool>& var; +}; + + +void hack_toggle( CMD_TOGGLE cmd ) { + con_clear(); + cmd.var = !cmd.var; + + menu_pages[menu_page].page_fn(); + show_paging( menu_page ); +} + +#define gcon_match( name ) !strncmp( buf + 1, name, strlen( name ) ) + +#define gcon_var( string ) { 0, strlen( string ) + 1, ( void* )string } + +void __cdecl game_hack_toggle( VECTOR<STR<64>> args ) { + static SETTING<bool>& bhop_active = *settings.find<bool>( "bhop_active"fnv ); + static SETTING<bool>& chams_active = *settings.find<bool>( "chams_active"fnv ); + static SETTING<bool>& glow_active = *settings.find<bool>( "glow_active"fnv ); + static SETTING<bool>& nightmode_active = *settings.find<bool>( "nightmode_active"fnv ); + static SETTING<bool>& noflash_active = *settings.find<bool>( "noflash_active"fnv ); + static SETTING<bool>& clantag_active = *settings.find<bool>( "clantag_active"fnv ); + + static SETTING<bool>& aim_active = *settings.find<bool>( "aim_active"fnv ); + static SETTING<bool>& crosshair_active = *settings.find<bool>( "crosshair_active"fnv ); + static SETTING<bool>& rcs_active = *settings.find<bool>( "rcs_active"fnv ); + static SETTING<bool>& triggerteam_active = *settings.find<bool>( "triggerteam_active"fnv ); + + char buf[512]{}; + + for( auto& it : args ) + sprintf( buf, "%s\n%s", buf, it.data ); + + CMD_TOGGLE cmd_toggle[10] = { + { "hg_bhop" , "toggles aim assist", bhop_active }, + { "hg_chams" , "toggles bhop", chams_active }, + { "hg_glow" , "toggles chams", glow_active }, + { "hg_night" , "toggles clantag", nightmode_active }, + { "hg_flash" , "toggles no flash", noflash_active }, + { "hg_clan" , "toggles glow", clantag_active }, + { "hg_aim" , "toggles nightmode", aim_active }, + { "hg_xhair" , "toggles standalone rcs", crosshair_active }, + { "hg_rcs" , "toggles team triggerbot", rcs_active }, + { "hg_triggerteam", "toggles recoil crosshair", triggerteam_active } + }; + + for( const auto& cmd : cmd_toggle ) { + if( gcon_match( cmd.name ) ) { + hack_toggle( cmd ); + return; + } + } + + if( gcon_match( "hg_help" ) ) { + const HWND hconsole = FindWindowA( "Valve001", 0 ); + if( !hconsole ) + return; + + u_sleep( 1 * T_SEC / 5 ); + for( auto& cmd : cmd_toggle ) { + sprintf( buf, "echo \"%s : %s\"", cmd.name, cmd.desc ); + + COPYDATASTRUCT hconsole_out; + hconsole_out.cbData = strlen( buf ) + 1; + hconsole_out.dwData = 0; + hconsole_out.lpData = ( void* )buf; + SendMessageA( hconsole, + WM_COPYDATA, 0, + ( LPARAM )&hconsole_out + ); + + u_sleep( 1 * T_SEC / 20 ); + } + + return; + } + + const HWND hconsole = FindWindowA( "Valve001", 0 ); + if( !hconsole ) + return; + + COPYDATASTRUCT hconsole_out; + hconsole_out.cbData = strlen( "echo \"invalid cmd, use \'hg_help\' for cmd list\"" ) + 1; + hconsole_out.dwData = 0; + hconsole_out.lpData = ( void* )"echo \"invalid cmd, use \'hg_help\' for cmd list\""; + SendMessageA( hconsole, + WM_COPYDATA, 0, + ( LPARAM )&hconsole_out + ); + + return; +}
\ No newline at end of file diff --git a/src/csgo/convar.h b/src/csgo/convar.h new file mode 100644 index 0000000..bdcb510 --- /dev/null +++ b/src/csgo/convar.h @@ -0,0 +1,67 @@ +#include "csgo.h" + +inline U32 convar_find( CSGO* p, const char* name ) { + VECTOR<MODULE_ENTRY> modules = p->dump_modules32(); + + for( auto& it : modules ) { + U32 string_ptr = 0; + do { + string_ptr = p->code_match( (U32)it.base, (U8*)name, strlen( name ), string_ptr + 1 ); + if( !string_ptr ) + break; + + U8* ptr_bytes = (U8*)( &string_ptr ); + U8 pattern[] = { + 0x68, 0x00, 0x00, 0x00, 0x00, // cvar creation flags + 0x68, 0x00, 0x00, 0x00, 0x00, // defaultValue + 0x68, + *ptr_bytes, + *(ptr_bytes + 1), + *(ptr_bytes + 2), + *(ptr_bytes + 3), + 0xe8 // call create_cvar + }; + + U32 string_ref = p->code_match( (U32)it.base, pattern, sizeof( pattern ) ); + if( string_ref ) + return p->read<U32>( string_ref - 11 ); + + // try with mov instead of call + pattern[sizeof( pattern ) - 1] = 0xb9; // mov ecx, this + string_ref = p->code_match( (U32)it.base, pattern, sizeof( pattern ) ); + + if( !string_ref ) + continue; + + U32 convar = p->read<U32>( string_ref + sizeof( pattern ) ); + return convar; + } while( true ); + } + + return 0; +} + +struct CVValue_t { + char* m_pszString; + int m_StringLength; + float m_fValue; + int m_nValue; +}; + +template <typename T> +inline void convar_set( CSGO* p, U32 convar, T _new ) { + U32 val = *(U32*)&_new; + val ^= convar; + + CVValue_t value = p->read<CVValue_t>( convar + 0x24 ); + value.m_nValue = val; + *(U32*)(&value.m_fValue) = val; + + p->write<CVValue_t>( convar + 0x24, value ); +} + +template <typename T> +inline T convar_get( CSGO* p, U32 convar ) { + U32 val = p->read<U32>( convar + 0x2c ) ^ convar; + return *(T*)( &val ); +}
\ No newline at end of file diff --git a/src/csgo/csgo.h b/src/csgo/csgo.h new file mode 100644 index 0000000..f23be80 --- /dev/null +++ b/src/csgo/csgo.h @@ -0,0 +1,22 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "../process.h" +#include "../conout.h" +#include "interface.h" + + +class CSGO : public PROCESS32 { +public: + CSGO() : PROCESS32( "csgo.exe" ) {}; + + void dump_interfaces() { + interfaces = srceng_get_interfaces( this ); + } + + U32 client; + U32 engine; + + VECTOR<IFACE_ENTRY> interfaces; +};
\ No newline at end of file diff --git a/src/csgo/csgoentity.cpp b/src/csgo/csgoentity.cpp new file mode 100644 index 0000000..4c91a98 --- /dev/null +++ b/src/csgo/csgoentity.cpp @@ -0,0 +1,6 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include "csgoentity.h" + +CSGO* CSGOENTITY::csgop;
\ No newline at end of file diff --git a/src/csgo/csgoentity.h b/src/csgo/csgoentity.h new file mode 100644 index 0000000..5d4a4cf --- /dev/null +++ b/src/csgo/csgoentity.h @@ -0,0 +1,81 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "../util.h" + +#include "sdk.h" +#include "netvar.h" + +#define OFFSET( name, prop, table, type, off ) \ + type name() { \ + static U32 offset = netvar_find( csgop, table, prop ) + off; \ + return get<type>( offset ); } \ + void name( type v ) { \ + static U32 offset = netvar_find( csgop, table, #name ) + off; \ + return set<type>( offset, v ); } \ + +#define NETVAR( name, table, type ) \ + type name() { \ + static U32 offset = netvar_find( csgop, table, #name ); \ + return get<type>( offset ); } \ + void name( type v ) { \ + static U32 offset = netvar_find( csgop, table, #name ); \ + return set<type>( offset, v ); } \ + + +class CSGOENTITY { +public: + static CSGO* csgop; + +public: + CSGOENTITY( U32 ptr ) : base( ptr ) {}; + CSGOENTITY( const CSGOENTITY& other ) : base( other.base ) {} + + inline operator U32&() { return base; } + + template <typename t> + t get( U32 offset ) { return csgop->read<t>( base + offset ); } + + template <typename t> + void set( U32 offset, t v ) { return csgop->write<t>( base + offset, v ); } + +public: + CSGO_CLIENT_CLASS get_clientclass() { + U32 networkable = get<U32>( 0x8 ); + U32 create_fn = csgop->read<U32>( networkable + 0x8 ); + U32 clientclass = csgop->read<U32>( create_fn + 0x1 ); + + return csgop->read<CSGO_CLIENT_CLASS>( clientclass ); + } + + NETVAR( m_fFlags, "DT_CSPlayer", I32 ); + OFFSET( m_MoveType , "m_nRenderMode", "DT_CSPlayer" , I32, 1 ); + OFFSET( m_iCrosshairID, "m_bHasDefuser", "DT_CSPlayer" , I32, 92 ); + OFFSET( m_dwBoneMatrix, "m_nForceBone", "DT_BaseAnimating", U32, 28 ); + + bool m_bDormant() { + return get<bool>( 0xed ); + } + + static CSGOENTITY from_list( I32 idx ) { + static U32 entlist = csgop->read<U32>( + csgop->code_match( + csgop->client, "BB ? ? ? ? 83 FF 01 0F 8C ? ? ? ? 3B F8" + ) + 1 + ); + + return csgop->read<U32>( + entlist + idx * 0x10 + ); + } + + bool is_weapon() { + CSGO_CLIENT_CLASS cl = get_clientclass(); + return ( cl.index >= CWeaponAug && cl.index <= CWeaponXM1014 ) + || cl.index == CAK47 || cl.index == CDEagle; + } + +public: + U32 base; +};
\ No newline at end of file diff --git a/src/csgo/csgoentity.h.bak b/src/csgo/csgoentity.h.bak new file mode 100644 index 0000000..0532673 --- /dev/null +++ b/src/csgo/csgoentity.h.bak @@ -0,0 +1,73 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "../util.h" + +#include "sdk.h" +#include "netvar.h" + +#define OFFSET( name, prop, table, type, off ) \ + type name() { \ + static U32 offset = netvar_find( csgop, table, prop ) + off; \ + return get<type>( offset ); } \ + void name( type v ) { \ + static U32 offset = netvar_find( csgop, table, #name ) + off; \ + return set<type>( offset, v ); } \ + +#define NETVAR( name, table, type ) \ + type name() { \ + static U32 offset = netvar_find( csgop, table, #name ); \ + return get<type>( offset ); } \ + void name( type v ) { \ + static U32 offset = netvar_find( csgop, table, #name ); \ + return set<type>( offset, v ); } \ + + +class CSGOENTITY { +public: + static CSGO* csgop; + +public: + CSGOENTITY( U32 ptr ) : base( ptr ) {}; + CSGOENTITY( const CSGOENTITY& other ) : base( other.base ) {} + + inline operator U32&() { return base; } + + template <typename t> + t get( U32 offset ) { return csgop->read<t>( base + offset ); } + + template <typename t> + void set( U32 offset, t v ) { return csgop->write<t>( base + offset, v ); } + +public: + CSGO_CLIENT_CLASS get_clientclass() { + U32 networkable = get<U32>( 0x8 ); + U32 create_fn = csgop->read<U32>( networkable + 0x8 ); + U32 clientclass = csgop->read<U32>( create_fn + 0x1 ); + + return csgop->read<CSGO_CLIENT_CLASS>( clientclass ); + } + + NETVAR( m_fFlags, "DT_CSPlayer", I32 ); + OFFSET( m_iCrosshairID, "m_bHasDefuser", "DT_CSPlayer", I32, 92 ); + OFFSET( m_dwBoneMatrix, "m_nForceBone", "DT_BaseAnimating", U32, 28 ); + + static CSGOENTITY from_list( I32 idx ) { + const U64 entlist = csgop->code_match( + csgop->client, "BB ? ? ? ? 83 FF 01 0F 8C ? ? ? ? 3B F8" + ); + + return csgop->read<U32>( + csgop->client + entlist + idx * 0x10 + ); + } + + bool is_weapon() { + CSGO_CLIENT_CLASS cl = get_clientclass(); + return cl.index >= CWeaponAug && cl.index <= CWeaponXM1014; + } + +public: + U32 base; +};
\ No newline at end of file diff --git a/src/csgo/csgoplayer.h b/src/csgo/csgoplayer.h new file mode 100644 index 0000000..ecf84c3 --- /dev/null +++ b/src/csgo/csgoplayer.h @@ -0,0 +1,36 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "csgoentity.h" + +class CSGOPLAYER : public CSGOENTITY { +public: + CSGOPLAYER( U32 base ) : CSGOENTITY( base ) {} + CSGOPLAYER( const CSGOENTITY& other ) : CSGOENTITY( other.base ) {} + CSGOPLAYER() = default; + + // this doesnt need to be a part of the aimbot. + VEC3 get_bone_pos( I32 bone_id ) { + return VEC3{ + csgop->read<F32>( m_dwBoneMatrix( ) + 0x30 * bone_id + 0x0c ), + csgop->read<F32>( m_dwBoneMatrix( ) + 0x30 * bone_id + 0x1c ), + csgop->read<F32>( m_dwBoneMatrix( ) + 0x30 * bone_id + 0x2c ) + }; + } + + NETVAR( m_bSpottedByMask , "DT_BaseEntity", I32 ); + + NETVAR( m_aimPunchAngle , "DT_BasePlayer", VEC3 ); + NETVAR( m_hActiveWeapon , "DT_BasePlayer", U32 ); + NETVAR( m_iHealth , "DT_BasePlayer", I32 ); + NETVAR( m_vecOrigin , "DT_BasePlayer", VEC3 ); + + NETVAR( m_clrRender , "DT_CSPlayer" , BYTECOLOR ); + NETVAR( m_flFlashMaxAlpha, "DT_CSPlayer" , F32 ); + NETVAR( m_iShotsFired , "DT_CSPlayer" , I32 ); + NETVAR( m_iTeamNum , "DT_CSPlayer" , I32 ); + NETVAR( m_lifeState , "DT_CSPlayer" , I32 ); + + OFFSET( m_vecViewOffset , "m_vecViewOffset[0]", "DT_CSPlayer", VEC3, 0 ); +};
\ No newline at end of file diff --git a/src/csgo/hack.cpp b/src/csgo/hack.cpp new file mode 100644 index 0000000..e979f3d --- /dev/null +++ b/src/csgo/hack.cpp @@ -0,0 +1,521 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include "hack.h" + +#include "convar.h" +#include "netvar.h" +#include "../disasm.h" + +#include <algorithm> + +SETTING_HOLDER settings; +SETTING<I32> triggerbot_key{ &settings, "triggerbot_key", 0x6 }; +SETTING<bool> triggerteam_active{ &settings, "triggerteam_active", false }; +SETTING<bool> aim_active{ &settings, "aim_active", false }; +SETTING<bool> rcs_active{ &settings, "rcs_active", false }; +SETTING<bool> bhop_active{ &settings, "bhop_active", true }; +SETTING<bool> chams_active{ &settings, "chams_active", false }; +SETTING<bool> glow_active{ &settings, "glow_active", false }; +SETTING<bool> nightmode_active{ &settings, "nightmode_active", false }; +SETTING<bool> noflash_active{ &settings, "noflash_active", false }; +SETTING<bool> crosshair_active{ &settings, "crosshair_active", false }; +SETTING<bool> clantag_active{ &settings, "clantag_active", false }; + +F64 perf_ipt = .0; +F64 perf_tps = .0; +U64 perf_tickrate = 1024; + +U32 localplayer_ptr; +U32 ambientmin_ptr; +U32 attack_ptr; +U32 clantag_ptr; +U32 clientstate_ptr; +U32 glow_ptr; +U32 jump_ptr; +U32 pitch_ptr; +U32 tonemap_ptr; +U32 xhair_ptr; +U32 yaw_ptr; + +void hack_run_bhop( CSGO* p ) { + if( !bhop_active || !( GetAsyncKeyState( VK_SPACE ) & 0x8000 ) ) + return; + + assert( !!localplayer_ptr ); + assert( !!jump_ptr ); + + CSGOPLAYER player = p->read<U32>( localplayer_ptr ); + if( !player ) + return; + + I32 player_flags = player.m_fFlags(); + bool air = !( player_flags & 1 << 0 ); + + if( !air || player.m_MoveType( ) == 9 ) + p->write<I32>( jump_ptr, 6 ); + else + p->write<I32>( jump_ptr, 4 ); +} + +void hack_run_trigger( CSGO* p ) { + if( !( GetAsyncKeyState( triggerbot_key ) & 0x8000 ) ) + return; + + assert( !!localplayer_ptr ); + assert( !!attack_ptr ); + + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + I32 crosshairid = local.m_iCrosshairID(); + + CSGOPLAYER t_player = CSGOENTITY::from_list( crosshairid - 1 ); + if( t_player.m_iTeamNum( ) == local.m_iTeamNum( ) && !triggerteam_active ) + return; + + if( crosshairid > 0 && crosshairid < 65 ) + p->write< I32 >( attack_ptr, 6 ); +} + +void hack_run_chams( CSGO* p ) { + if( chams_active ) + convar_set<float>( p, ambientmin_ptr, nightmode_active ? 250.f : 50.f ); + else + convar_set<float>( p, ambientmin_ptr, 0.f ); +} + +void hack_run_glow( CSGO* p ) { + if( !glow_active ) + return; + + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + if( !local ) + return; + + U32 local_team = local.m_iTeamNum(); + + GLOW_OBJ_MANAGER glow; + p->read( glow_ptr, &glow, sizeof( GLOW_OBJ_MANAGER ) ); + + if( !glow.count ) + return; + + GLOW_OBJECT* glow_objects = (GLOW_OBJECT*)malloc( sizeof( GLOW_OBJECT ) * glow.count ); + p->read( (U32)( glow.objects ), glow_objects, sizeof( GLOW_OBJECT ) * glow.count ); + + for( U32 i = 0; i < glow.count; ++i ) { + GLOW_OBJECT& o = glow_objects[i]; + + if( !o.ent || local.base == o.ent ) + continue; + + CSGOPLAYER e = o.ent; + CSGO_CLIENT_CLASS cl = e.get_clientclass(); + COLOR color; + + /* clientclass outdated af*/ + if( cl.index == CCSPlayer ) { + I32 team = e.m_iTeamNum(); + if( team == local_team || (team != 2 && team != 3) ) + continue; + + color = ( team == 2 ) ? + COLOR{ 1.0f, 0.17f, 0.37f, 0.7f } : + COLOR{ 0.17f, 0.67f, 0.8f, 0.8f }; + + // TODO: RUN ENTLIST AND CLEAR THIS ONCE CHAMS ARE DISABLED. + if( chams_active ) + e.m_clrRender( BYTECOLOR{ 232, 85, 193, 255 } ); + } + else if( cl.index >= CWeaponAug && cl.index <= CWeaponXM1014 && !o.rwo ) { + color = { 0.8f, 0.8f, 0.8f, 0.6f }; + } + else continue; + + o.rwo = true; + o.rwuo = false; + o.bloom_amt = 0.7f; + o.full_bloom = false; + o.color = color; + + U32 obj_address = (U32)glow.objects + i * sizeof( GLOW_OBJECT ); + p->write( obj_address + 0x8, (void*)( (U32)&glow_objects[i] + 0x8 ), sizeof( GLOW_OBJECT ) - 0x16 ); + } + + free( glow_objects ); +} + +void hack_run_nightmode( CSGO* p ) { + static bool prev_active = false; + + static F32 anim_end = 0.f; + const F32 anim_time = 1.2f; + + if( nightmode_active != prev_active ) { + F32 time = (F32)u_time(); + anim_end = time + anim_time; + + prev_active = nightmode_active; + } + + F32 time = (F32)u_tick() / T_SEC; + if( time < anim_end ) { + F32 delta = ( anim_end - time ) / anim_time; + if( delta > 1.0f ) + delta = 1.0f; + + convar_set<float>( p, tonemap_ptr, nightmode_active ? 0.2f + delta * 0.9f : 1.0f - delta * 0.9f ); + } +} + +void hack_run_noflash( CSGO* p ) { + if( !noflash_active ) + return; + + assert( !!localplayer_ptr ); + + CSGOPLAYER player = p->read<U32>( localplayer_ptr ); + if( !player ) + return; + + if( player.m_flFlashMaxAlpha( ) > 0.f ) + player.m_flFlashMaxAlpha( 0.f ); +} + +void hack_run_crosshair( CSGO* p ) { + if( crosshair_active ) + convar_set<F32>( p, xhair_ptr, 1.f ); + else + convar_set<F32>( p, xhair_ptr, 0.f ); +} + +__declspec( naked ) void __stdcall setclantag_shellcode( void* string ) { + __asm { + push ebp + mov ebp, esp + sub esp, __LOCAL_SIZE + } + + U32 clantag_offset; + clantag_offset = 0xDADADADA; + + using set_clantag = int( __fastcall* )( const char*, const char* ); + ( (set_clantag)(clantag_offset) )( (const char*)string, (const char*)string ); + + DISASM_SIG(); + + __asm { + mov esp, ebp + pop ebp + ret + } +} + +void hack_setclantag( CSGO* csgo, const char* str ) { + static U64 func_address = 0; + static U64 string_address = 0; + + if( !func_address || !string_address ) { + DISASM_INFO disasm = disasm_function( &setclantag_shellcode ); + + U8* func_copy = (U8*)malloc( disasm.func_length ); + memcpy( func_copy, disasm.func_start, disasm.func_length ); + + for( U32 i = 0; i < disasm.func_length; ++i ) { + if( *(U32*)( func_copy + i ) == 0xdadadada ) { + *(U32*)( func_copy + i ) = clantag_ptr; + break; + } + } + + func_address = csgo->allocate( disasm.func_length ); + string_address = csgo->allocate( 16, PAGE_READWRITE ); + csgo->write( func_address, func_copy, disasm.func_length ); + + free( func_copy ); + } + + + U32 len = strlen( str ); + assert( (len < 16) ); + + csgo->write( string_address, str, len ); + u_thread_create( + csgo->get_base(), + (LPTHREAD_START_ROUTINE)(U32)func_address, + (void*)(U32)string_address + ); +} + +void hack_run_clantag( CSGO* csgo ) { + if( !clantag_active || !localplayer_ptr ) + return; + + const char8_t* clantag[] = { + u8"\u30FB\u2605*\u309C\u22C6", + u8"\u309C\u30FB\u2605\u22C6*", + u8"\u22C6\u309C\u30FB*\u2605", + u8"*\u22C6\u309C\u2605\u30FB", + u8"\u2605*\u22C6\u30FB\u309C" + }; + + static I32 counter = 0; + static U64 last_tick = u_tick() + (rand() % 1000 - 500); + U64 tick = u_tick(); + + + if( tick - last_tick > 1000 ) { + counter = (++counter) % 5; + + hack_setclantag( csgo, (const char*)( clantag[counter] ) ); + last_tick = tick; + } +} + +// fix tapfire over-compensation issue +void hack_run_recoil( CSGO* p ) { + if( !rcs_active ) + return; + + assert( !!localplayer_ptr ); + assert( !!clientstate_ptr ); + + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + if( !local ) + return; + + CSGOENTITY wep = CSGOENTITY::from_list( + ( ( local.m_hActiveWeapon( ) & 0xFFF ) - 1 ) + ); + if( !wep.is_weapon( ) ) + return; + + static VEC3 last_punch{ }; + if( local.m_iShotsFired( ) ) { + VEC3 local_view = p->read<VEC3>( clientstate_ptr + 0x4d90 ); + VEC3 rcs_angle = { + local_view.x + last_punch.x - local.m_aimPunchAngle( ).x * 2.f, + local_view.y + last_punch.y - local.m_aimPunchAngle( ).y * 2.f, + 0.f + }; + + p->write<VEC3>( clientstate_ptr + 0x4d90, rcs_angle.clamp( ) ); + + last_punch = { + local.m_aimPunchAngle( ).x * 2.f, + local.m_aimPunchAngle( ).y * 2.f, + 0.f + }; + } else { + // this isnt right iirc + last_punch = { + local.m_aimPunchAngle( ).x * 2.f, + local.m_aimPunchAngle( ).y * 2.f, + 0.f + }; + } + return; +} + +inline void hack_print_offset( U8 line, const char* name, ULONG offset ) { + con_set_line_text( line, name ); + U8 color = offset > 0x1000 ? CONFG_WHITE : CONFG_RED; + + con_set_line_subtext( line, u_num_to_string_hex( offset ), false, color ); +} + +inline U32 get_clantag_offset( CSGO* csgo ) { + const char* const clantag_str = "Current clan ID for name decoration"; + U32 str = csgo->code_match( csgo->engine, (U8*)clantag_str, strlen( clantag_str ) ); + while( csgo->read<U8>( str - 1 ) != 0 ) + str = csgo->code_match( csgo->engine, (U8*)clantag_str, strlen( clantag_str ), str + 1 ); + + U8 str_bytes[] = { + 0x68, + *( (U8*)(&str) + 0 ), + *( (U8*)(&str) + 1 ), + *( (U8*)(&str) + 2 ), + *( (U8*)(&str) + 3 ) + }; + + U32 push_str = csgo->code_match( csgo->engine, str_bytes, sizeof( str_bytes ) ); + U8 func_buffer[100]; + csgo->read( push_str - 100, func_buffer, sizeof( func_buffer ) ); + + U32 cvar_func = 0; + for( U32 i = 0; i < 100; ++i ) { + if( func_buffer[i] == 0x68 && func_buffer[i + 5] == 0x51 ) { + cvar_func = *(U32*)( func_buffer + i + 1 ); + break; + } + } + + U8 cvar_func_buffer[256]; + csgo->read( cvar_func, cvar_func_buffer, sizeof( cvar_func_buffer ) ); + + for( U32 i = 0; i < 256; ++i ) { + if( cvar_func_buffer[i] == 0xe8 + && cvar_func_buffer[i + 5] == 0x5f + && cvar_func_buffer[i + 6] == 0x5e + && cvar_func_buffer[i + 7] == 0x5b ) { + return *(U32*)( cvar_func_buffer + i + 1 ) + cvar_func + i + 5; + } + } + + return 0; +} + +inline U32 get_jump_offset( CSGO* csgo ) { + IFACE_ENTRY chl = u_vector_search<IFACE_ENTRY>( csgo->interfaces, []( IFACE_ENTRY* e ) { + return !!strstr( e->name, "VClient0" ); + } ); + + if( !chl.ptr ) + return 0; + + U32 chl_vtable = csgo->read<U32>( chl.ptr ); + U32 chl_vtable_16 = csgo->read<U32>( chl_vtable + 16 * sizeof(U32) ); + U32 input = csgo->read<U32>( chl_vtable_16 + 1 ); + + U32 input_vtable = csgo->read<U32>( input ); + U32 vtable_3 = csgo->read<U32>( input_vtable + 2 * sizeof(U32) ); + + U8 func_buffer[256]; + csgo->read( vtable_3, func_buffer, sizeof( func_buffer ) ); + + U8 pattern[] = { 0x83, 0xca, 0x02, 0x24, 0x03 }; + for( U32 i = 0; i < sizeof( func_buffer ) - sizeof( pattern ); ++i ) { + if( u_binary_match( func_buffer + i, pattern, sizeof( pattern ) ) ) { + return *(U32*)( func_buffer + i - 8 ); + } + } + + return 0; +} + +inline U32 get_attack_offset( CSGO* csgo ) { + IFACE_ENTRY chl = u_vector_search<IFACE_ENTRY>( csgo->interfaces, []( IFACE_ENTRY* e ) { + return !!strstr( e->name, "VClient0" ); + } ); + + if( !chl.ptr ) + return 0; + + U32 chl_vtable = csgo->read<U32>( chl.ptr ); + U32 chl_vtable_16 = csgo->read<U32>( chl_vtable + 16 * sizeof(U32) ); + U32 input = csgo->read<U32>( chl_vtable_16 + 1 ); + + U32 input_vtable = csgo->read<U32>( input ); + U32 vtable_3 = csgo->read<U32>( input_vtable + 2 * sizeof(U32) ); + + U8 func_buffer[256]; + csgo->read( vtable_3, func_buffer, sizeof( func_buffer ) ); + + U8 pattern[] = { 0x83, 0xca, 0x01, 0x24, 0x03 }; + for( U32 i = 0; i < sizeof( func_buffer ) - sizeof( pattern ); ++i ) { + if( u_binary_match( func_buffer + i, pattern, sizeof( pattern ) ) ) { + return *(U32*)( func_buffer + i - 8 ); + } + } + + return 0; +} + +inline U32 get_clientstate_offset( CSGO* csgo ) { + IFACE_ENTRY engine = u_vector_search<IFACE_ENTRY>( csgo->interfaces, []( IFACE_ENTRY* e ) { + return !!strstr( e->name, "VEngineClient0" ); + } ); + + if( !engine.ptr ) + return 0; + + U32 engine_vtable = csgo->read<U32>( engine.ptr ); + U32 engine_vtable_18 = csgo->read<U32>( engine_vtable + 18 * sizeof(U32) ); + + U8 func_buffer[256]; + csgo->read( engine_vtable_18, func_buffer, sizeof( func_buffer ) ); + + for( U32 i = 0; i < 256; ++i ) { + if( func_buffer[i] == 0x8b + && func_buffer[i+1] == 0x34 + && func_buffer[i+2] == 0x85 ) { + return csgo->read<U32>( *(U32*)( func_buffer + i + 3 ) ); + } + } + + return 0; +} + +#define progress( x ) con_set_line( CON_MAX_HEIGHT - 1, con_progressbar( x ), "" ) + +CSGO* hack_init() { + static CSGO p; + con_clear(); + + while( !p.open() ) { + progress( 0.f ); + con_set_bottomline_text( "waiting for process..." ); + Sleep( 500 ); + } + + progress( .2f ); + do { + p.client = p.get_module32( "client.dll"fnv ); + p.engine = p.get_module32( "engine.dll"fnv ); + if( p.client && p.engine ) + break; + + progress( .3f ); + con_set_bottomline_text( "waiting for modules..." ); + Sleep( 500 ); + } while( true ); + + progress( .4f ); + con_set_bottomline_text( "dumping interfaces..." ); + + do { + p.dump_interfaces(); + if( p.interfaces.size() > 1 ) + break; + + progress( .4f ); + Sleep( 500 ); + } while( true ); + + progress( .5f ); + // preload netvar tables + netvar_get_table( &p, " " ); + progress( .6f ); + + con_set_bottomline_text( "searching for offsets..." ); + + con_set_line_text( 0, "found interfaces: " ); + con_set_line_subtext( 0, u_num_to_string_dec( p.interfaces.size() ), false, CONFG_CYAN ); + + localplayer_ptr = p.read<U32>( p.code_match( p.client, LOCALPLAYER_SIG ) + 3 ) + 4; + hack_print_offset( 1, "localplayer", localplayer_ptr ); progress( .62f ); + jump_ptr = get_jump_offset( &p ); + hack_print_offset( 2, "jump", jump_ptr ); progress( .65f ); + attack_ptr = get_attack_offset( &p ); + hack_print_offset( 3, "attack", attack_ptr ); progress( .7f ); + glow_ptr = p.read<U32>( p.code_match( p.client, GLOWSTRUCT_SIG ) + 1 ) + 4; + hack_print_offset( 4, "glow", glow_ptr ); progress( .74f ); + clantag_ptr = get_clantag_offset( &p ); + hack_print_offset( 5, "SetClanTag", clantag_ptr ); progress( .78f ); + clientstate_ptr = get_clientstate_offset( &p ); + hack_print_offset( 6, "clientstate", clientstate_ptr ); progress( .83f ); + + pitch_ptr = convar_find( &p, "m_pitch" ); + hack_print_offset( 7, "pitch", pitch_ptr ); progress( .90f ); + yaw_ptr = 0xdee938 + p.client; // convar_find( &p, "m_yaw" ); <-- how is this wrong + hack_print_offset( 8, "yaw", yaw_ptr ); progress( 1.f ); + ambientmin_ptr = convar_find( &p, "r_modelAmbientMin" ); + tonemap_ptr = convar_find( &p, "mat_force_tonemap_scale" ); + xhair_ptr = convar_find( &p, "cl_crosshair_recoil" ); + + progress( 1.f ); + CSGOENTITY::csgop = &p; + + return &p; +} + +#undef progress
\ No newline at end of file diff --git a/src/csgo/hack.h b/src/csgo/hack.h new file mode 100644 index 0000000..c10dd7c --- /dev/null +++ b/src/csgo/hack.h @@ -0,0 +1,138 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once + +#include <time.h> + +#include "../conout.h" +#include "../setting.h" + +#include "csgo.h" +#include "csgoentity.h" +#include "csgoplayer.h" + +struct CMD_FUNC { + using func_t = void( __cdecl* )( VECTOR<STR<64>> ); + func_t func; + STR<64> name; +}; + +void __cdecl game_hack_toggle( VECTOR<STR<64>> args ); +static CMD_FUNC g_hack_toggle = { + &game_hack_toggle, + "hg_" +}; + +static CMD_FUNC* cmd_funcs[] = { + &g_hack_toggle, +}; + +extern SETTING_HOLDER settings; +extern F64 perf_ipt; +extern F64 perf_tps; +static I64 perf_drift; +extern U64 perf_tickrate; + +const char* const LOCALPLAYER_SIG = "8D 34 85 ? ? ? ? 89 15 ? ? ? ? 8B 41 08 8B 48 04 83 F9 FF"; +const char* const GLOWSTRUCT_SIG = "A1 ? ? ? ? A8 01 75 4B"; + +extern U32 localplayer_ptr; +extern U32 clientstate_ptr; +extern U32 pitch_ptr; +extern U32 yaw_ptr; + +extern void hack_run_aim( CSGO* p ); +extern void hack_run_bhop( CSGO* p ); +extern void hack_run_chams( CSGO* p ); +extern void hack_run_clantag( CSGO* p ); +extern void hack_run_crosshair( CSGO* p ); +extern void hack_run_glow( CSGO* p ); +extern void hack_run_nightmode( CSGO* p ); +extern void hack_run_noflash( CSGO* p ); +extern void hack_run_recoil( CSGO* p ); +extern void hack_run_trigger( CSGO* p ); +extern CSGO* hack_init(); + +inline U64 hack_calc_perf_metrics( U64 tickrate ) { + static U64 last_tick; + U64 tick = u_tick(); + + static U64 last_tps_tick; + static U64 tick_counter = 0; + + perf_ipt = (tick - last_tick) / (F64)T_SEC; + + if( tick - last_tps_tick < T_SEC * 0.5 ) + ++tick_counter; + else { + perf_tps = (F64)tick_counter * 2; + tick_counter = 0; + last_tps_tick = tick; + + I64 tick_delta = (I64)tickrate - (I64)perf_tps; + F64 tick_ratio = (F64)tick_delta / (F64)( tickrate ) * 10; + if( tick_ratio < 1.0 ) + tick_ratio = 1.0; + + perf_drift += (I64)( 100.0 * tick_ratio ) * ( tick_delta < 0 ? 1 : -1 ); + } + + if( tickrate > 0 ) { + U64 delay = (T_SEC / tickrate); + u_sleep( delay + perf_drift ); + } + else { + u_sleep( 1 ); + } + + last_tick = tick; + return perf_drift; +} + +static bool hack_run( PROCESS32* p ) { + hack_calc_perf_metrics( perf_tickrate ); + + CSGO* csgo = (CSGO*)p; + + hack_run_aim( csgo ); + hack_run_bhop( csgo ); + hack_run_trigger( csgo ); + hack_run_recoil( csgo ); + hack_run_chams( csgo ); + hack_run_glow( csgo ); + hack_run_nightmode( csgo ); + hack_run_noflash( csgo ); + hack_run_crosshair( csgo ); + hack_run_clantag( csgo ); + + + static U32 string_ptr = 0; + if( !string_ptr ) { + string_ptr = p->code_match( csgo->engine, "B9 ? ? ? ? E8 ? ? ? ? 84 C0 75 0E 68 ? ? ? ? FF 15 ? ? ? ? 83 C4 04 83 05 ? ? ? ? ? 75 04" ); + string_ptr = p->read<U32>( string_ptr + 1 ); + } + + STR<64> buf; + p->read( string_ptr, buf, sizeof( buf ) ); + + for( U16 i = 0; i < 1; ++i ) { + CMD_FUNC* fn = cmd_funcs[i]; + + if( strncmp( fn->name.data, buf.data, strlen( fn->name.data ) ) == 0 ) { + fn->func( { buf } ); + p->write<U8>( string_ptr, 0 ); + } + } + + + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + con_set_bottomline_text( + "local: 0x%08x | flags: 0x%03x | tps: %.0f", + local.base, + local.m_fFlags(), + (F32)perf_tps + ); + + return csgo->valid(); +}
\ No newline at end of file diff --git a/src/csgo/hack_aim.cpp b/src/csgo/hack_aim.cpp new file mode 100644 index 0000000..9c95bdf --- /dev/null +++ b/src/csgo/hack_aim.cpp @@ -0,0 +1,110 @@ +#include "hack.h" + +#include "convar.h" +#include "netvar.h" + +SETTING<bool>& aim_active = *settings.find<bool>( "aim_active"fnv ); + +bool aim_check_player( CSGOPLAYER player, CSGO* p ) { + if( !player ) + return true; // if no player + if( player.get_clientclass().index != CCSPlayer ) + return true; // if not player + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + if( player.base == local ) + return true; // if player is you + if( player.m_iTeamNum() == local.m_iTeamNum() ) + return true; + if( player.m_bDormant() ) + return true; // dormant + if( player.m_lifeState() ) + return true; + if( !player.m_bSpottedByMask() ) + return true; + return false; +} + +#define aim_fov 10.f +#define aim_reset( ) { \ + m_pitch = m_yaw = 0.022f; \ + convar_set( p, pitch_ptr, m_pitch ); \ + convar_set( p, yaw_ptr, m_yaw ); \ + return; \ +} + +F32 calc_dist( VEC3 v, F32 distance ) { + F32 sqr1 = sinf( v.x * M_PI / 180.f ) * distance; + F32 sqr2 = sinf( v.y * M_PI / 180.f ) * distance; + return sqrtf( + ( sqr1 * sqr1 ) + ( sqr2 * sqr2 ) + ); +} + +void hack_run_aim( CSGO* p ) { + if( !aim_active ) + return; + + F32 m_pitch, m_yaw; + + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + if( local.m_iHealth( ) < 1 || !local ) + aim_reset(); + + CSGOENTITY wep = CSGOENTITY::from_list( + ( ( local.m_hActiveWeapon() & 0xFFF ) - 1 ) + ); + + if( !wep.is_weapon( ) ) + aim_reset(); + + F32 lowest_dist{ aim_fov }; + U32 closest{ }; + for( U32 index{}; index <= 64; ++index ) { + CSGOPLAYER player = CSGOENTITY::from_list( index ); + + if( aim_check_player( player, p ) ) + continue; + + VEC3 local_pos = local.m_vecOrigin( ) + local.m_vecViewOffset( ); + VEC3 local_view = p->read<VEC3>( clientstate_ptr + 0x4d90 ); + // could replace this magic number with pattern, but is it worth it ? + VEC3 target_pos; + if( wep.get_clientclass( ).index == CWeaponAWP ) + target_pos = player.get_bone_pos( 6 ); + else + target_pos = player.get_bone_pos( 8 ); + VEC3 target_ang = vector_angles( local_pos, target_pos ); + + //F32 distance = ( local_view - target_ang ).clamp().length2d(); // non-dynamic + F32 distance = calc_dist( + ( local_view - target_ang ), + local_pos.dist_to( target_pos ) + ); + + if( distance > lowest_dist ) + continue; + + lowest_dist = distance; + closest = player; + } + + if( !closest ) + aim_reset(); + + // change this to change strength. this is the minimum allowed by the game. + const F32 min_sens = 0.0001f; + F32 factor = ( lowest_dist / aim_fov ); + if( factor > 1.f ) + factor = 1.f; + + // change this for how aggressively the aim 'comes on'. + // lower values = less assist on outer edge of fov, more on inner. + factor = pow( factor, 3.f ); + + + m_pitch = min_sens + ( 0.022f - min_sens ) * factor, + m_yaw = min_sens + ( 0.022f - min_sens ) * factor; + + convar_set( p, pitch_ptr, m_pitch ); + convar_set( p, yaw_ptr, m_yaw ); +}
\ No newline at end of file diff --git a/src/csgo/interface.h b/src/csgo/interface.h new file mode 100644 index 0000000..62afb4a --- /dev/null +++ b/src/csgo/interface.h @@ -0,0 +1,110 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "../process.h" +#include "../util.h" +#include "../typedef.h" + +struct IFACE_ENTRY { + U32 ptr; + STR<64> name; + U32 module; + STR<64> module_name; +}; + +struct IFACE_REG { + void* create_fn; + const char* name; + U32 next; +}; + +inline bool iface_is_createinterface_export( PROCESS32* proc, U32 exp ) { + U8 buf[12]; + + proc->read( exp, buf, 12 ); + + return( + buf[0] == 0x55 && + buf[4] == 0xe9 && + buf[9] == 0xcc && + buf[10] == 0xcc + ); +} + +inline bool iface_is_createinterface( PROCESS32* proc, U32 fn ) { + U8 buf[12]; + + proc->read( fn, buf, 12 ); + + return ( + buf[0] == 0x55 && + buf[4] == 0x8b && + buf[10] == 0x57 + ); +} + +inline U32 iface_follow_createinterface( PROCESS32* proc, U32 exp ) { + U32 jmp = exp + 0x4; + U32 rel = proc->read<U32>( jmp + 0x1 ); + + return jmp + rel + 0x5; +} + +inline U32 iface_get_list( PROCESS32* proc, U32 exp ) { + return proc->read<U32>( proc->read<U32>( exp + 0x6 ) ); +} + +static VECTOR< IFACE_ENTRY > srceng_get_interfaces( PROCESS32* proc ) { + VECTOR< MODULE_EXPORT64 > exports; + VECTOR< MODULE_ENTRY > modules; + VECTOR< IFACE_ENTRY > ifaces; + MODULE_EXPORT64* create_interface_export; + U32 create_interface; + + modules = proc->dump_modules32(); + for( auto& module : modules ) { + create_interface_export = 0; + exports = module_get_exports( (U32)module.base, proc->get_base() ); + + for( auto& it : exports ) { + if( fnv1a( it.name ) == "CreateInterface"fnv && + iface_is_createinterface_export( proc, (U32)it.base ) + ) { + create_interface_export = ⁢ + break; + } + } + + if( !create_interface_export ) + continue; + + create_interface = iface_follow_createinterface( proc, (U32)create_interface_export->base ); + if( !create_interface || !iface_is_createinterface( proc, create_interface ) ) + continue; + + U32 list_ptr = iface_get_list( proc, create_interface ); + if( !list_ptr ) + continue; + + IFACE_REG reg = proc->read<IFACE_REG>( list_ptr ); + STR<64> name{}; + do { + memset( name.data, 0, 64 ); + proc->read( (U32)reg.name, name.data, 64 ); + name.data[63] = 0; + + IFACE_ENTRY e; + e.module = (U32)module.base; + e.module_name = module.name; + e.name = name; + e.ptr = proc->read<U32>( (U32)(reg.create_fn) + 0x1 ); + + ifaces.push_back( e ); + + reg = proc->read<IFACE_REG>( reg.next ); + } while( list_ptr != reg.next && reg.next ); + } + + return ifaces; +}
\ No newline at end of file diff --git a/src/csgo/materialsystem.h b/src/csgo/materialsystem.h new file mode 100644 index 0000000..263f808 --- /dev/null +++ b/src/csgo/materialsystem.h @@ -0,0 +1,61 @@ +#include "csgo.h" + +class MATERIAL { +private: + static IFACE_ENTRY* get_matsystem( CSGO* csgo ) { + static IFACE_ENTRY* ret = u_vector_search<IFACE_ENTRY>( csgo->interfaces, + []( IFACE_ENTRY i ) { + return fnv1a( "materialsystem.dll" ) == fnv1a( i.module_name ) + && !!strcmp( i.name, "VMaterialSystem" ); + } ); + + return ret; + } + + static IFACE_ENTRY* get_matsystem_cvar( CSGO* csgo ) { + static IFACE_ENTRY* ret = u_vector_search<IFACE_ENTRY>( csgo->interfaces, + []( IFACE_ENTRY i ) { + return fnv1a( "materialsystem.dll" ) == fnv1a( i.module_name ) + && !!strcmp( i.name, "VEngineCvar" ); + } ); + + return ret; + } + +public: + static U32 first_material( CSGO* csgo ) { + IFACE_ENTRY* mat_system = get_matsystem( csgo ); + + U16 mat_handle = csgo->read<U16>( mat_system->ptr + 0x250 ); + + while( mat_handle != 0xffff ) { + U32 handle_entries = csgo->read<U32>( mat_system->ptr + 0x244 ); + U16 next_handle = csgo->read<U16>( handle_entries + 16 * mat_handle ); + + if( next_handle == 0xffff ) + return mat_handle; + + mat_handle = next_handle; + } + + return 0; + } + + static U16 next_material( CSGO* csgo, U16 mat ) { + IFACE_ENTRY* mat_system = get_matsystem( csgo ); + + if( mat == 0xffff ) + return 0; + + U32 handle_array = csgo->read<U32>( mat_system->ptr + 0x244 ); + U16 next_handle = csgo->read<U16>( handle_array + 16 + mat + 2 ); + if( next_handle == 0xffff ) + return 0xffff; + + for( U16 i = next_handle; i != 0xffff; i = csgo->read<U16>( handle_array * 16 + i ) ) { + next_handle = i; + } + + return next_handle; + } +};
\ No newline at end of file diff --git a/src/csgo/netvar.h b/src/csgo/netvar.h new file mode 100644 index 0000000..cd5c702 --- /dev/null +++ b/src/csgo/netvar.h @@ -0,0 +1,142 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once + +#include "csgo.h" +#include "sdk.h" +#include "../conout.h" + +struct NETVAR_TABLE { + U32 ptr; + STR<64> name; +}; + +inline U32 netvar_get_classes( CSGO* csgo ) { + IFACE_ENTRY chl = u_vector_search<IFACE_ENTRY>( + csgo->interfaces, + []( IFACE_ENTRY* in ) { + return !!strstr( in->name, "VClient0" ); + } + ); + + if( !chl.ptr ) + return 0; + + U32 chl_vtable = csgo->read<U32>( chl.ptr ); + U32 vtable_8 = chl_vtable + 8 * sizeof(U32); + + U32 get_allclasses = csgo->read<U32>( vtable_8 ); + U32 class_ptr = csgo->read<U32>( csgo->read<U32>( get_allclasses + 0x1 ) ); + + return class_ptr; +} + +inline VECTOR<NETVAR_TABLE> netvar_get_tables( CSGO* csgo, U32 list ) { + static VECTOR<NETVAR_TABLE> tables{}; + if( !tables.empty() ) + return tables; + + U32 ptr = list; + STR<64> net_name; + do { + CSGO_CLIENT_CLASS cclass = csgo->read<CSGO_CLIENT_CLASS>( ptr ); + RECV_TABLE table = csgo->read<RECV_TABLE>( (U32)cclass.recv ); + csgo->read( (U32)table.table_name, net_name.data, 64 ); + + tables.push_back( { (U32)cclass.recv, net_name } ); + ptr = (U32)cclass.next; + } while( ptr && ptr != list ); + + return tables; +} + +inline U32 netvar_get_table( CSGO* csgo, const char* table_name ) { + static U32 list_ptr = netvar_get_classes( csgo ); + static VECTOR<NETVAR_TABLE> tables = netvar_get_tables( csgo, list_ptr ); + + for( auto& it : tables ) { + if( !strcmp( it.name.data, table_name ) ) + return it.ptr; + } + + return 0; +} + +inline I32 netvar_get_entry( CSGO* csgo, const char* name, U32 table_ptr ) { + I32 ret{}; + RECV_TABLE table = csgo->read<RECV_TABLE>( table_ptr ); + + RECV_PROP* props = (RECV_PROP*)malloc( table.prop_count * sizeof( RECV_PROP ) ); + csgo->read( (U32)table.props, props, sizeof( RECV_PROP ) * table.prop_count ); + + for( I32 i = 0; i < table.prop_count; ++i ) { + RECV_PROP* prop = &props[i]; + + if( prop->table ) { + RECV_TABLE child = csgo->read<RECV_TABLE>( (U32)prop->table ); + if( child.prop_count ) { + U32 tmp = netvar_get_entry( csgo, name, (U32)prop->table ); + if( tmp ) ret += prop->offset + tmp; + } + } + + STR<64> prop_name; + csgo->read( (U32)prop->varname, prop_name.data, 64 ); + + if( !!strcmp( prop_name.data, name ) ) + continue; + + ret += prop->offset; + break; + } + + free( props ); + return ret; +} + +inline I32 netvar_find( CSGO* csgo, const char* table_name, const char* prop ) { + I32 ret; + U32 table = netvar_get_table( csgo, table_name ); + + if( !table ) + return 0; + + ret = netvar_get_entry( csgo, prop, table ); + return ret; +} + +static void csgo_dump_classes( CSGO* csgo ) { + U32 allclasses = netvar_get_classes( csgo ); + + if( !allclasses ) + return; + + char* dump = (char*)malloc( 99999 ); + memset( dump, 0, 99999 ); + strcat( dump, "enum CSGO_CLIENT_CLASS {\n" ); + + U32 ptr = allclasses; + STR<64> net_name; + do { + CSGO_CLIENT_CLASS cclass = csgo->read<CSGO_CLIENT_CLASS>( ptr ); + csgo->read( (U64)cclass.network_name, net_name.data, 64 ); + + strcat( dump, " " ); + strcat( dump, net_name ); + strcat( dump, " = " ); + strcat( dump, "0x" ); + strcat( dump, u_num_to_string_hex( cclass.index ) ); + strcat( dump, ",\n" ); + + ptr = (U32)cclass.next; + } while( ptr && ptr != allclasses ); + + strcat( dump, "};" ); + + FILE* f = fopen( "./classes.dump", "w" ); + fwrite( dump, strlen( dump ), 1, f ); + fclose( f ); + + free( dump ); +}
\ No newline at end of file diff --git a/src/csgo/sdk.h b/src/csgo/sdk.h new file mode 100644 index 0000000..449d8de --- /dev/null +++ b/src/csgo/sdk.h @@ -0,0 +1,528 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "../vec3.h" + +struct BYTECOLOR { + BYTECOLOR() = default; + BYTECOLOR( U8 r1, U8 g1, U8 b1, U8 a1 ) : r( r1 ), g( g1 ), b( b1 ), a( a1 ) {} + + U8 r; + U8 g; + U8 b; + U8 a; +}; + +struct COLOR { + COLOR() = default; + COLOR( F32 r1, F32 g1, F32 b1, F32 a1 ) : r( r1 ), g( g1 ), b( b1 ), a( a1 ) {} + + F32 r; + F32 g; + F32 b; + F32 a; +}; + +struct GLOW_OBJECT { + U8 pad00[ 4 ]; + U32 ent; //0000 + COLOR color; + U8 pad01[ 8 ]; + F32 bloom_amt; + U8 pad_02[ 4 ]; + bool rwo; //0024 + bool rwuo; //0025 + bool full_bloom; + char pad_002B[1]; //0x002B + I32 fullbloom_stencil; //0x002C + I32 unk; //0x0030 + I32 splitscreen_slot; //0x0034 +}; + +struct GLOW_OBJ_MANAGER { + GLOW_OBJECT* objects; + U32 max; + U32 unk02; + U32 count; + U32 data_ptr_back; + U32 first_free_slot; + U32 unk1; + U32 unk2; + U32 unk3; + U32 unk4; + U32 unk5; +}; + +struct RECV_PROP; +struct RECV_TABLE { + RECV_PROP* props; + I32 prop_count; + void* decoder; + const char* table_name; + + bool initialized; + bool in_main_list; +}; + +struct RECV_PROP { + const char* varname; + I32 recv_type; + I32 flags; + I32 buffer_size; + bool inside_array; + void* extra_data; + + RECV_PROP* array_prop; + void* array_length_proxy; + + void* proxy_fn; + void* dt_proxy_fn; + + RECV_TABLE* table; + I32 offset; + + I32 element_stride; + I32 elements; + + const char* parent_array_name; +}; + +class CSGO_CLIENT_CLASS { +public: + void* create_fn; + void* create_event_fn; + const char* network_name; + void* recv; + CSGO_CLIENT_CLASS* next; + U32 index; +}; + +enum CSGO_CLASS_ID { + CTestTraceline = 0x000000E0, + CTEWorldDecal = 0x000000E1, + CTESpriteSpray = 0x000000DE, + CTESprite = 0x000000DD, + CTESparks = 0x000000DC, + CTESmoke = 0x000000DB, + CTEShowLine = 0x000000D9, + CTEProjectedDecal = 0x000000D6, + CFEPlayerDecal = 0x00000047, + CTEPlayerDecal = 0x000000D5, + CTEPhysicsProp = 0x000000D2, + CTEParticleSystem = 0x000000D1, + CTEMuzzleFlash = 0x000000D0, + CTELargeFunnel = 0x000000CE, + CTEKillPlayerAttachments = 0x000000CD, + CTEImpact = 0x000000CC, + CTEGlowSprite = 0x000000CB, + CTEShatterSurface = 0x000000D8, + CTEFootprintDecal = 0x000000C8, + CTEFizz = 0x000000C7, + CTEExplosion = 0x000000C5, + CTEEnergySplash = 0x000000C4, + CTEEffectDispatch = 0x000000C3, + CTEDynamicLight = 0x000000C2, + CTEDecal = 0x000000C0, + CTEClientProjectile = 0x000000BF, + CTEBubbleTrail = 0x000000BE, + CTEBubbles = 0x000000BD, + CTEBSPDecal = 0x000000BC, + CTEBreakModel = 0x000000BB, + CTEBloodStream = 0x000000BA, + CTEBloodSprite = 0x000000B9, + CTEBeamSpline = 0x000000B8, + CTEBeamRingPoint = 0x000000B7, + CTEBeamRing = 0x000000B6, + CTEBeamPoints = 0x000000B5, + CTEBeamLaser = 0x000000B4, + CTEBeamFollow = 0x000000B3, + CTEBeamEnts = 0x000000B2, + CTEBeamEntPoint = 0x000000B1, + CTEBaseBeam = 0x000000B0, + CTEArmorRicochet = 0x000000AF, + CTEMetalSparks = 0x000000CF, + CSteamJet = 0x000000A8, + CSmokeStack = 0x0000009E, + DustTrail = 0x00000115, + CFireTrail = 0x0000004A, + SporeTrail = 0x0000011B, + SporeExplosion = 0x0000011A, + RocketTrail = 0x00000118, + SmokeTrail = 0x00000119, + CPropVehicleDriveable = 0x00000091, + ParticleSmokeGrenade = 0x00000117, + CParticleFire = 0x00000075, + MovieExplosion = 0x00000116, + CTEGaussExplosion = 0x000000CA, + CEnvQuadraticBeam = 0x00000042, + CEmbers = 0x00000037, + CEnvWind = 0x00000046, + CPrecipitation = 0x0000008A, + CPrecipitationBlocker = 0x0000008B, + CBaseTempEntity = 0x00000012, + NextBotCombatCharacter = 0x00000000, + CEconWearable = 0x00000036, + CBaseAttributableItem = 0x00000004, + CEconEntity = 0x00000035, + CWeaponZoneRepulsor = 0x00000112, + CWeaponXM1014 = 0x00000111, + CWeaponTaser = 0x0000010C, + CTablet = 0x000000AC, + CSnowball = 0x0000009F, + CSmokeGrenade = 0x0000009C, + CWeaponShield = 0x0000010A, + CWeaponSG552 = 0x00000108, + CSensorGrenade = 0x00000098, + CWeaponSawedoff = 0x00000104, + CWeaponNOVA = 0x00000100, + CIncendiaryGrenade = 0x00000063, + CMolotovGrenade = 0x00000071, + CMelee = 0x00000070, + CWeaponM3 = 0x000000F8, + CKnifeGG = 0x0000006C, + CKnife = 0x0000006B, + CHEGrenade = 0x00000060, + CFlashbang = 0x0000004D, + CFists = 0x0000004C, + CWeaponElite = 0x000000EF, + CDecoyGrenade = 0x0000002F, + CDEagle = 0x0000002E, + CWeaponUSP = 0x00000110, + CWeaponM249 = 0x000000F7, + CWeaponUMP45 = 0x0000010F, + CWeaponTMP = 0x0000010E, + CWeaponTec9 = 0x0000010D, + CWeaponSSG08 = 0x0000010B, + CWeaponSG556 = 0x00000109, + CWeaponSG550 = 0x00000107, + CWeaponScout = 0x00000106, + CWeaponSCAR20 = 0x00000105, + CSCAR17 = 0x00000096, + CWeaponP90 = 0x00000103, + CWeaponP250 = 0x00000102, + CWeaponP228 = 0x00000101, + CWeaponNegev = 0x000000FF, + CWeaponMP9 = 0x000000FE, + CWeaponMP7 = 0x000000FD, + CWeaponMP5Navy = 0x000000FC, + CWeaponMag7 = 0x000000FB, + CWeaponMAC10 = 0x000000FA, + CWeaponM4A1 = 0x000000F9, + CWeaponHKP2000 = 0x000000F6, + CWeaponGlock = 0x000000F5, + CWeaponGalilAR = 0x000000F4, + CWeaponGalil = 0x000000F3, + CWeaponG3SG1 = 0x000000F2, + CWeaponFiveSeven = 0x000000F1, + CWeaponFamas = 0x000000F0, + CWeaponBizon = 0x000000EB, + CWeaponAWP = 0x000000E9, + CWeaponAug = 0x000000E8, + CAK47 = 0x00000001, + CWeaponCSBaseGun = 0x000000ED, + CWeaponCSBase = 0x000000EC, + CC4 = 0x00000022, + CBumpMine = 0x00000020, + CBumpMineProjectile = 0x00000021, + CBreachCharge = 0x0000001C, + CBreachChargeProjectile = 0x0000001D, + CWeaponBaseItem = 0x000000EA, + CBaseCSGrenade = 0x00000008, + CSnowballProjectile = 0x000000A1, + CSnowballPile = 0x000000A0, + CSmokeGrenadeProjectile = 0x0000009D, + CSensorGrenadeProjectile = 0x00000099, + CMolotovProjectile = 0x00000072, + CItem_Healthshot = 0x00000068, + CItemDogtags = 0x0000006A, + CDecoyProjectile = 0x00000030, + CPhysPropRadarJammer = 0x0000007F, + CPhysPropWeaponUpgrade = 0x00000080, + CPhysPropAmmoBox = 0x0000007D, + CPhysPropLootCrate = 0x0000007E, + CItemCash = 0x00000069, + CEnvGasCanister = 0x0000003F, + CDronegun = 0x00000032, + CParadropChopper = 0x00000074, + CSurvivalSpawnChopper = 0x000000AB, + CBRC4Target = 0x0000001B, + CInfoMapRegion = 0x00000066, + CFireCrackerBlast = 0x00000048, + CInferno = 0x00000064, + CChicken = 0x00000024, + CDrone = 0x00000031, + CFootstepControl = 0x0000004F, + CCSGameRulesProxy = 0x00000027, + CWeaponCubemap = 0x00000000, + CWeaponCycler = 0x000000EE, + CTEPlantBomb = 0x000000D3, + CTEFireBullets = 0x000000C6, + CTERadioIcon = 0x000000D7, + CPlantedC4 = 0x00000081, + CCSTeam = 0x0000002B, + CCSPlayerResource = 0x00000029, + CCSPlayer = 0x00000028, + CPlayerPing = 0x00000083, + CCSRagdoll = 0x0000002A, + CTEPlayerAnimEvent = 0x000000D4, + CHostage = 0x00000061, + CHostageCarriableProp = 0x00000062, + CBaseCSGrenadeProjectile = 0x00000009, + CHandleTest = 0x0000005F, + CTeamplayRoundBasedRulesProxy = 0x000000AE, + CSpriteTrail = 0x000000A6, + CSpriteOriented = 0x000000A5, + CSprite = 0x000000A4, + CRagdollPropAttached = 0x00000094, + CRagdollProp = 0x00000093, + CPropCounter = 0x0000008E, + CPredictedViewModel = 0x0000008C, + CPoseController = 0x00000088, + CGrassBurn = 0x0000005E, + CGameRulesProxy = 0x0000005D, + CInfoLadderDismount = 0x00000065, + CFuncLadder = 0x00000055, + CTEFoundryHelpers = 0x000000C9, + CEnvDetailController = 0x0000003D, + CDangerZone = 0x0000002C, + CDangerZoneController = 0x0000002D, + CWorldVguiText = 0x00000114, + CWorld = 0x00000113, + CWaterLODControl = 0x000000E7, + CWaterBullet = 0x000000E6, + CMapVetoPickController = 0x0000006E, + CVoteController = 0x000000E5, + CVGuiScreen = 0x000000E4, + CPropJeep = 0x00000090, + CPropVehicleChoreoGeneric = 0x00000000, + CTriggerSoundOperator = 0x000000E3, + CBaseVPhysicsTrigger = 0x00000016, + CTriggerPlayerMovement = 0x000000E2, + CBaseTrigger = 0x00000014, + CTest_ProxyToggle_Networkable = 0x000000DF, + CTesla = 0x000000DA, + CBaseTeamObjectiveResource = 0x00000011, + CTeam = 0x000000AD, + CSunlightShadowControl = 0x000000AA, + CSun = 0x000000A9, + CParticlePerformanceMonitor = 0x00000076, + CSpotlightEnd = 0x000000A3, + CSpatialEntity = 0x000000A2, + CSlideshowDisplay = 0x0000009B, + CShadowControl = 0x0000009A, + CSceneEntity = 0x00000097, + CRopeKeyframe = 0x00000095, + CRagdollManager = 0x00000092, + CPhysicsPropMultiplayer = 0x0000007B, + CPhysBoxMultiplayer = 0x00000079, + CPropDoorRotating = 0x0000008F, + CBasePropDoor = 0x00000010, + CDynamicProp = 0x00000034, + CProp_Hallucination = 0x0000008D, + CPostProcessController = 0x00000089, + CPointWorldText = 0x00000087, + CPointCommentaryNode = 0x00000086, + CPointCamera = 0x00000085, + CPlayerResource = 0x00000084, + CPlasma = 0x00000082, + CPhysMagnet = 0x0000007C, + CPhysicsProp = 0x0000007A, + CStatueProp = 0x000000A7, + CPhysBox = 0x00000078, + CParticleSystem = 0x00000077, + CMovieDisplay = 0x00000073, + CMaterialModifyControl = 0x0000006F, + CLightGlow = 0x0000006D, + CItemAssaultSuitUseable = 0x00000000, + CItem = 0x00000000, + CInfoOverlayAccessor = 0x00000067, + CFuncTrackTrain = 0x0000005C, + CFuncSmokeVolume = 0x0000005B, + CFuncRotating = 0x0000005A, + CFuncReflectiveGlass = 0x00000059, + CFuncOccluder = 0x00000058, + CFuncMoveLinear = 0x00000057, + CFuncMonitor = 0x00000056, + CFunc_LOD = 0x00000051, + CTEDust = 0x000000C1, + CFunc_Dust = 0x00000050, + CFuncConveyor = 0x00000054, + CFuncBrush = 0x00000053, + CBreakableSurface = 0x0000001F, + CFuncAreaPortalWindow = 0x00000052, + CFish = 0x0000004B, + CFireSmoke = 0x00000049, + CEnvTonemapController = 0x00000045, + CEnvScreenEffect = 0x00000043, + CEnvScreenOverlay = 0x00000044, + CEnvProjectedTexture = 0x00000041, + CEnvParticleScript = 0x00000040, + CFogController = 0x0000004E, + CEnvDOFController = 0x0000003E, + CCascadeLight = 0x00000023, + CEnvAmbientLight = 0x0000003C, + CEntityParticleTrail = 0x0000003B, + CEntityFreezing = 0x0000003A, + CEntityFlame = 0x00000039, + CEntityDissolve = 0x00000038, + CDynamicLight = 0x00000033, + CColorCorrectionVolume = 0x00000026, + CColorCorrection = 0x00000025, + CBreakableProp = 0x0000001E, + CBeamSpotlight = 0x00000019, + CBaseButton = 0x00000005, + CBaseToggle = 0x00000013, + CBasePlayer = 0x0000000F, + CBaseFlex = 0x0000000C, + CBaseEntity = 0x0000000B, + CBaseDoor = 0x0000000A, + CBaseCombatCharacter = 0x00000006, + CBaseAnimatingOverlay = 0x00000003, + CBoneFollower = 0x0000001A, + CBaseAnimating = 0x00000002, + CAI_BaseNPC = 0x00000000, + CBeam = 0x00000018, + CBaseViewModel = 0x00000015, + CBaseParticleEntity = 0x0000000E, + CBaseGrenade = 0x0000000D, + CBaseCombatWeapon = 0x00000007, + CBaseWeaponWorldModel = 0x00000017, +}; + +struct CSGO_ANIM_STATE +{ +private: + U32 unk000; //0x0000 + U32 unk001; //0x0004 + char pad_0[4][4]; //0x0008 +public: + float unk_time; //0x0018 wheeee +private: + float point_four; //0x001C always 0.4 + float point_two; //0x0020 always 0.2 + U32 pad_1; //0x0024 +public: + float walk_amt; //0x0028 Resets to 0 when movement stops + float stop_amt; //0x002C Resets to 0 when full run starts (bw/fw) +private: + float point_two2; //0x0030 always 0.2 + float point_four2; //0x0034 always 0.4 + float unk_float_but_special; //0x0038 + float unk_float2; //0x003C Resets to 0 when movement stops + float unk_float3; //0x0040 Resets to 0 when movement starts + float unk_float4; //0x0044 static? 0.3 + float unk_float5; //0x0048 static? 0.3 + float unk_float6; //0x004C 0.0 <-> 1.0 (to 1. when moving) + U32 unk_U32; //0x0050 static? 0x23E + char pad_2[2][4]; //0x0054 + void *curr_weapon_0; //0x005C current weapon + void *static_something; //0x0060 + void *curr_weapon_1; //0x0064 current weapon + void *curr_weapon_2; //0x0068 current weapon + float unk_time1; //0x006C same as +0x18 + U32 unk_time2; //0x0070 increases with time but its an int + U32 what; //0x0074 + float look_dir[3]; //0x0078 + float hell_yaw; //0x0084 + float velocity[3]; //0x0088 + float uppies; //0x0094 + float i_have_no_idea; //0x0098 + float unk_float_the_sixth; //0x009C + float N00000304; //0x00A0 + float jump_something0; //0x00A4 + float jump_something1; //0x00A8 + U32 delaware; //0x00AC + float origin_something[3]; //0x00B0 + float position_something[3]; //0x00BC + float inspector_vector[3]; //0x00C8 + float you_vector_go_catch_it[3]; //0x00D4 + float wow_three_floats[3]; //0x00E0 + float i_cant_believe_its_not_an_array[3]; //0x00EC + float fuel_prices[3]; //0x00F8 + float wow_the_point_FLOATS_get_it; //0x0104 + U8 onGround; //0x0108 + U8 hitGroundAnim; //0x0109 + U16 u_thought; //0x010A + char pad_010C[4]; //0x010C + float N00000387[3]; //0x0110 + float N0000038A; //0x011C + char pad_0120[160]; //0x0120 +}; //Size: 0x01C0 + +class CSGO_NETCHANNEL { + +}; + +struct CSGO_EVENT_INFO { + I16 class_id; + F32 fire_delay; + const void* send_table; + CSGO_CLIENT_CLASS* client_class; + void* data; + I32 packed_bits; + I32 flags; +private: + U8 pad[16]; +}; + +class CSGO_CLIENTSTATE { + char pad[156]; +public: + CSGO_NETCHANNEL* netchannel; + I32 challenge; +private: + U8 pad1[4]; +public: + F64 connect_time; + I32 retry_number; +private: + U8 pad2[84]; +public: + I32 signon_state; +private: + U8 pad3[4]; +public: + F64 next_cmd_time; + I32 server_count; + I32 current_sequence; +private: + U8 pad4[8]; +public: + float clock_offsets[16]; + I32 cur_clock_offset; + I32 server_tick; + I32 client_tick; + I32 delta_tick; +private: + U32 pad5; +public: + char level_name[260]; + char level_name_short[40]; +private: + U8 pad7[212]; +public: + I32 maxclients; +private: + U8 pad8[18836]; +public: + I32 old_tickcount; + F32 tick_remainder; + F32 frame_time; + I32 last_outgoing_command; + I32 choked_commands; + I32 last_command_ack; + I32 last_server_tick; + I32 command_ack; + I32 sound_sequence; + I32 last_progress_percent; + bool is_hltv; +private: + U8 pad9[75]; +public: + VEC3 viewangles; +private: + U8 pad10[204]; +public: + CSGO_EVENT_INFO* events; +};
\ No newline at end of file diff --git a/src/csgo/trace.h b/src/csgo/trace.h new file mode 100644 index 0000000..e496f15 --- /dev/null +++ b/src/csgo/trace.h @@ -0,0 +1,40 @@ +#include "../disasm.h" + +#include "hack.h" + +struct TRACE_ARGS { + U32 ignore_ent; + VEC3 start; + VEC3 end; + U32 mask; + + VEC3 ret_end; + VEC3 ret_normal; + U32 ret_ent; +}; + +__declspec( naked ) void __stdcall trace_shellcode( TRACE_ARGS* args ) { + __asm { + push ebp + mov ebp, esp + sub esp, LOCAL_SIZE + } + + + + DISASM_SIG(); + + __asm { + mov esp, ebp + pop ebp + ret + } +} + +U32 trace_allocate( CSGO* p ) { + DISASM_INFO disasm = disasm_function( &trace_shellcode ); +} + +U32 trace_find_func( CSGO* p ) { + +}
\ No newline at end of file diff --git a/src/disasm.h b/src/disasm.h new file mode 100644 index 0000000..8c12c9a --- /dev/null +++ b/src/disasm.h @@ -0,0 +1,111 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#pragma warning( disable: 4102 ) + +#include "util.h" +#include "asmutil.h" +#include "x86.h" + +#define DISASM_SIG() _DISASM_SIG1( __COUNTER__ ) +#define _DISASM_SIG1( x ) _DISASM_SIG( x ) +#define _DISASM_SIG( x ) \ + db( 0xeb ) db( 0x10 ) db( 0x66 ) db( 0xb8 ) db( 0x39 ) db( 0x1b ) \ + __asm mov eax, ##x __asm mov eax, ##x^(##x/2) db( 0xcc ) db( 0xcc ) + + +struct DISASM_INFO { + U8* func_start; + U32 func_length; + U8* sig_ptr; + I32 check; +}; + +const I32 DISASM_SIG_LENGTH = 18; + +U8* disasm_get_wrapper_target( void* funptr ) { + U8* func = (U8*)funptr; + + if( func[0] != 0xe9 || func[5] != 0xe9 ) + return 0; + + U32 jmp_rel = *(U32*)( &func[1] ); + return (U8*)( funptr ) + jmp_rel + 5; +} + +U8* disasm_find_sig_end( void* funptr, int* out_checknr = 0 ) { + static const char* signature_str = "eb 10 66 b8 39 1b b8 ? ? ? ? b8 ? ? ? ? cc cc"; + U8 *ret = 0, *ptr = (U8*)funptr; + U32 sig_size; + U8* sig_bytes = u_parse_signature( signature_str, &sig_size ); + + for( U16 i = 0; i < 64; ++i ) { + if( u_binary_match( ptr + i, sig_bytes, sig_size ) ) { + ret = ptr + i; break; + } + } + + free( sig_bytes ); + if( !ret ) + return 0; + + I32* check1 = (I32*)( ret + 7 ); + I32* check2 = (I32*)( ret + 12 ); + if( out_checknr ) + *out_checknr = *check1; + + if( *check2 == ( (*check1) ^ (*check1 / 2) ) ) + return ret; + + return 0; +} + +U8* disasm_find_ret_instruction( void* funptr ) { + U8* ptr = (U8*)funptr; + + for( U16 i = 0; i < 64; ++i ) { + if( ptr[i] == RET_FAR + || ptr[i] == RET_NEAR + || ptr[i] == RET_FAR_IMM16 + || ptr[i] == RET_NEAR_IMM16 ) { + return ptr + i; + } + } + + return 0; +} + +void disasm_print( DISASM_INFO disasm ) { + for( U32 i = 0; i < disasm.func_length; ++i ) { + if( !( i % 8 ) ) + con_print( CONFG_RED, "\n0x%08x : ", (U32)(disasm.func_start + i) ); + + con_print( CONFG_WHITE, "%02x ", disasm.func_start[i] ); + } + con_print( CONFG_WHITE, "\n" ); +} + +DISASM_INFO disasm_function( void* func ) { + DISASM_INFO ret{}; + I32 checknr; + U8* signature = disasm_find_sig_end( func, &checknr ); + if( !signature ) { + U8* wrapper_target = disasm_get_wrapper_target( func ); + if( !wrapper_target ) + return ret; + + return disasm_function( wrapper_target ); + } + + U8* ret_byte = disasm_find_ret_instruction( func ); + if( !ret_byte ) + return ret; + + ret.func_start = (U8*)func; + ret.func_length = ret_byte - (U8*)func + 1; + ret.check = checknr; + ret.sig_ptr = signature; + + return ret; +}
\ No newline at end of file diff --git a/src/fnv.h b/src/fnv.h new file mode 100644 index 0000000..88d66cb --- /dev/null +++ b/src/fnv.h @@ -0,0 +1,39 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "typedef.h" + +typedef U32 FNV1A; + +enum : FNV1A { + FNV1A_PRIME = 0x1000193, + FNV1A_BASIS = 0x811C9DC5 +}; + +inline constexpr U32 strlen_ct( const char* str ) { + U32 s = 0; + for( ; !!str[s]; ++s ); + + return s; +} + +inline constexpr FNV1A fnv1a( const U8* data, const U32 size ) { + FNV1A out = FNV1A_BASIS; + + for( U32 i = 0; i < size; ++i ) + out = ( out ^ data[i] ) * FNV1A_PRIME; + + return out; +} + +inline constexpr FNV1A fnv1a( const char* str ) { + U32 len = strlen_ct( str ); + + return fnv1a( (const U8*)str, len ); +} + +#pragma warning( disable : 4455 ) +constexpr FNV1A operator""fnv( const char* str, U32 len ) { + return fnv1a( (const U8*)str, len ); +}
\ No newline at end of file diff --git a/src/heavens-gate.aps b/src/heavens-gate.aps Binary files differnew file mode 100644 index 0000000..a37fb5f --- /dev/null +++ b/src/heavens-gate.aps diff --git a/src/heavens-gate.filters b/src/heavens-gate.filters new file mode 100644 index 0000000..53d2b66 --- /dev/null +++ b/src/heavens-gate.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="source.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="process.h"> + <Filter>Source Files</Filter> + </ClInclude> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/src/heavens-gate.user b/src/heavens-gate.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/src/heavens-gate.user @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup /> +</Project>
\ No newline at end of file diff --git a/src/heavens-gate.vcxproj b/src/heavens-gate.vcxproj new file mode 100644 index 0000000..4cc2b26 --- /dev/null +++ b/src/heavens-gate.vcxproj @@ -0,0 +1,261 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <TrackFileAccess>false</TrackFileAccess> + </PropertyGroup> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="stripped|Win32"> + <Configuration>stripped</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>15.0</VCProjectVersion> + <ProjectGuid>{D2960E74-5A8F-4D86-9788-7BBAF0248F68}</ProjectGuid> + <RootNamespace>Project6</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='stripped|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v142</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='stripped|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)\bin\</OutDir> + <IntDir>..\intermediate\$(Configuration)\</IntDir> + <TargetName>heavens-gate</TargetName> + <PostBuildEventUseInBuild>true</PostBuildEventUseInBuild> + <IncludePath>$(SolutionDir)/openssl/include;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath> + <LibraryPath>$(SolutionDir)/openssl/include;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='stripped|Win32'"> + <OutDir>$(SolutionDir)\bin\</OutDir> + <IntDir>..\intermediate\$(Configuration)\</IntDir> + <TargetName>heavens-gate</TargetName> + <PostBuildEventUseInBuild>true</PostBuildEventUseInBuild> + <IncludePath>$(SolutionDir)/openssl/include;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath> + <LibraryPath>$(SolutionDir)/openssl/include;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)\bin\</OutDir> + <IntDir>..\intermediate\$(Configuration)\</IntDir> + <TargetName>heavens-gate</TargetName> + <PostBuildEventUseInBuild>true</PostBuildEventUseInBuild> + <EnableManagedIncrementalBuild>false</EnableManagedIncrementalBuild> + <LinkIncremental>true</LinkIncremental> + <IncludePath>$(SolutionDir)/openssl/include;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath> + <LibraryPath>$(SolutionDir)/openssl/lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86)</LibraryPath> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>false</SDLCheck> + <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;DEBUG 1</PreprocessorDefinitions> + <CallingConvention>FastCall</CallingConvention> + <LanguageStandard>stdcpplatest</LanguageStandard> + <NoWarn>4530</NoWarn> + <DisableSpecificWarnings>4530</DisableSpecificWarnings> + <ExceptionHandling>false</ExceptionHandling> + <BasicRuntimeChecks>Default</BasicRuntimeChecks> + <BufferSecurityCheck>false</BufferSecurityCheck> + <ControlFlowGuard>false</ControlFlowGuard> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <AdditionalOptions>/ENTRY:"mainCRTStartup" %(AdditionalOptions) /IGNORE:4530</AdditionalOptions> + <Profile>false</Profile> + <OptimizeReferences>false</OptimizeReferences> + <EnableCOMDATFolding>false</EnableCOMDATFolding> + </Link> + <ResourceCompile> + <ResourceOutputFileName>$(IntDir)%(Filename).res</ResourceOutputFileName> + </ResourceCompile> + <PostBuildEvent> + <Command>../cleanup.bat</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>false</SDLCheck> + <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions> + <CallingConvention>FastCall</CallingConvention> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <ExceptionHandling>false</ExceptionHandling> + <ControlFlowGuard>false</ControlFlowGuard> + <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <NoWarn>4530</NoWarn> + <LanguageStandard>stdcpplatest</LanguageStandard> + <DisableSpecificWarnings>4530</DisableSpecificWarnings> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>Default</BasicRuntimeChecks> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Windows</SubSystem> + <EntryPointSymbol> + </EntryPointSymbol> + <AdditionalOptions>/ENTRY:"mainCRTStartup" %(AdditionalOptions)</AdditionalOptions> + <DataExecutionPrevention>false</DataExecutionPrevention> + </Link> + <PostBuildEvent> + <Command>../cleanup.bat</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='stripped|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>false</SDLCheck> + <AdditionalOptions>%(AdditionalOptions)</AdditionalOptions> + <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions> + <CallingConvention>FastCall</CallingConvention> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <ExceptionHandling>false</ExceptionHandling> + <NoWarn>4530</NoWarn> + <ControlFlowGuard>false</ControlFlowGuard> + <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <LanguageStandard>stdcpplatest</LanguageStandard> + <DisableSpecificWarnings>4530</DisableSpecificWarnings> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <OmitFramePointers>true</OmitFramePointers> + <MinimalRebuild>false</MinimalRebuild> + <BasicRuntimeChecks>Default</BasicRuntimeChecks> + <BufferSecurityCheck>false</BufferSecurityCheck> + <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration> + <DebugInformationFormat>None</DebugInformationFormat> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <SubSystem>Windows</SubSystem> + <EntryPointSymbol> + </EntryPointSymbol> + <AdditionalOptions>/ENTRY:"mainCRTStartup" %(AdditionalOptions)</AdditionalOptions> + <DataExecutionPrevention>false</DataExecutionPrevention> + <GenerateDebugInformation>false</GenerateDebugInformation> + <AssemblyDebug>false</AssemblyDebug> + <ProgramDatabaseFile /> + </Link> + <PostBuildEvent> + <Command>../cleanup.bat</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="conout.cpp" /> + <ClCompile Include="conin.cpp" /> + <ClCompile Include="csgo\console.cpp" /> + <ClCompile Include="csgo\csgoentity.cpp" /> + <ClCompile Include="csgo\hack.cpp" /> + <ClCompile Include="csgo\hack_aim.cpp" /> + <ClCompile Include="menu.cpp" /> + <ClCompile Include="ntutil.cpp" /> + <ClCompile Include="setting.cpp" /> + <ClCompile Include="source.cpp" /> + <ClCompile Include="util.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="asmutil.h" /> + <ClInclude Include="csgo\convar.h" /> + <ClInclude Include="csgo\csgo.h" /> + <ClInclude Include="csgo\csgoentity.h" /> + <ClInclude Include="csgo\csgoplayer.h" /> + <ClInclude Include="csgo\hack.h" /> + <ClInclude Include="csgo\interface.h" /> + <ClInclude Include="csgo\materialsystem.h" /> + <ClInclude Include="csgo\netvar.h" /> + <ClInclude Include="csgo\sdk.h" /> + <ClInclude Include="csgo\trace.h" /> + <ClInclude Include="disasm.h" /> + <ClInclude Include="fnv.h" /> + <ClInclude Include="inet.h" /> + <ClInclude Include="mouse.h" /> + <ClInclude Include="resource.h" /> + <ClInclude Include="setting.h" /> + <ClInclude Include="conout.h" /> + <ClInclude Include="conin.h" /> + <ClInclude Include="mathutil.h" /> + <ClInclude Include="menu.h" /> + <ClInclude Include="ntutil.h" /> + <ClInclude Include="process.h" /> + <ClInclude Include="syscall.h" /> + <ClInclude Include="typedef.h" /> + <ClInclude Include="util.h" /> + <ClInclude Include="vec3.h" /> + <ClInclude Include="winintern.h" /> + <ClInclude Include="x86.h" /> + </ItemGroup> + <ItemGroup> + <Image Include="..\resource\heavens-gate-ico.ico" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\resource\heavens-gate.rc"> + <ResourceOutputFileName>Debug\%(Filename).res</ResourceOutputFileName> + <Culture>0x0409</Culture> + <TrackerLogDirectory>Debug\heavens-gate.tlog\</TrackerLogDirectory> + <MinimalRebuildFromTracking>true</MinimalRebuildFromTracking> + <UseResponseFile>false</UseResponseFile> + <SuppressStartupBanner>true</SuppressStartupBanner> + <LinkCompiled>true</LinkCompiled> + <ResourceOutputFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\intermediate\%(Filename).res</ResourceOutputFileName> + <ResourceOutputFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\intermediate\%(Filename).res</ResourceOutputFileName> + <ResourceOutputFileName Condition="'$(Configuration)|$(Platform)'=='stripped|Win32'">..\intermediate\%(Filename).res</ResourceOutputFileName> + </ResourceCompile> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/src/heavens-gate.vcxproj.filters b/src/heavens-gate.vcxproj.filters new file mode 100644 index 0000000..8249fc6 --- /dev/null +++ b/src/heavens-gate.vcxproj.filters @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="source.cpp" /> + <ClCompile Include="conin.cpp"> + <Filter>Console</Filter> + </ClCompile> + <ClCompile Include="conout.cpp"> + <Filter>Console</Filter> + </ClCompile> + <ClCompile Include="ntutil.cpp" /> + <ClCompile Include="util.cpp" /> + <ClCompile Include="csgo\csgoentity.cpp" /> + <ClCompile Include="menu.cpp" /> + <ClCompile Include="setting.cpp" /> + <ClCompile Include="csgo\hack.cpp"> + <Filter>Hack</Filter> + </ClCompile> + <ClCompile Include="csgo\hack_aim.cpp"> + <Filter>Hack</Filter> + </ClCompile> + <ClCompile Include="csgo\console.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="typedef.h" /> + <ClInclude Include="conin.h"> + <Filter>Console</Filter> + </ClInclude> + <ClInclude Include="conout.h"> + <Filter>Console</Filter> + </ClInclude> + <ClInclude Include="asmutil.h"> + <Filter>Util</Filter> + </ClInclude> + <ClInclude Include="util.h"> + <Filter>Util</Filter> + </ClInclude> + <ClInclude Include="mathutil.h"> + <Filter>Util</Filter> + </ClInclude> + <ClInclude Include="syscall.h"> + <Filter>Util</Filter> + </ClInclude> + <ClInclude Include="ntutil.h"> + <Filter>Util</Filter> + </ClInclude> + <ClInclude Include="process.h"> + <Filter>Util</Filter> + </ClInclude> + <ClInclude Include="winintern.h"> + <Filter>Util</Filter> + </ClInclude> + <ClInclude Include="menu.h"> + <Filter>Menu</Filter> + </ClInclude> + <ClInclude Include="fnv.h" /> + <ClInclude Include="x86.h" /> + <ClInclude Include="resource.h" /> + <ClInclude Include="csgo\csgo.h" /> + <ClInclude Include="csgo\csgoentity.h" /> + <ClInclude Include="csgo\csgoplayer.h" /> + <ClInclude Include="csgo\interface.h" /> + <ClInclude Include="csgo\materialsystem.h" /> + <ClInclude Include="csgo\netvar.h" /> + <ClInclude Include="csgo\sdk.h" /> + <ClInclude Include="disasm.h" /> + <ClInclude Include="setting.h" /> + <ClInclude Include="mouse.h" /> + <ClInclude Include="vec3.h" /> + <ClInclude Include="csgo\convar.h" /> + <ClInclude Include="csgo\trace.h" /> + <ClInclude Include="inet.h" /> + <ClInclude Include="csgo\hack.h"> + <Filter>Hack</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <Filter Include="Console"> + <UniqueIdentifier>{70c04199-d27a-4e3e-8b24-7be72b38326b}</UniqueIdentifier> + </Filter> + <Filter Include="Hack"> + <UniqueIdentifier>{34bdb695-2332-40eb-9d0e-1e91691fdea6}</UniqueIdentifier> + </Filter> + <Filter Include="Util"> + <UniqueIdentifier>{2a464b99-56b4-4450-8dc1-4dd920a6183b}</UniqueIdentifier> + </Filter> + <Filter Include="Menu"> + <UniqueIdentifier>{77e5fc6f-b4e1-4265-ba15-0295ef9bd911}</UniqueIdentifier> + </Filter> + <Filter Include="Config"> + <UniqueIdentifier>{55f07d41-9e36-4718-b51c-f6883ca4d543}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\resource\heavens-gate.rc" /> + </ItemGroup> + <ItemGroup> + <Image Include="..\resource\heavens-gate-ico.ico" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/src/heavens-gate.vcxproj.user b/src/heavens-gate.vcxproj.user new file mode 100644 index 0000000..7837d9f --- /dev/null +++ b/src/heavens-gate.vcxproj.user @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='stripped|Win32'"> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + </PropertyGroup> +</Project>
\ No newline at end of file diff --git a/src/inet.h b/src/inet.h new file mode 100644 index 0000000..69c13c7 --- /dev/null +++ b/src/inet.h @@ -0,0 +1,76 @@ +#pragma once + +#include <winsock2.h> +#include <ws2tcpip.h> +#include <openssl/ssl.h> +#include <openssl/err.h> + +#include "conout.h" +#include "typedef.h" + +#pragma comment( lib, "libssl.lib" ) +#pragma comment( lib, "libcrypto.lib" ) +#pragma comment( lib, "Ws2_32.lib" ) + +inline U32 net_create_socket( I32 family, I32 type, I32 protocol ) { + static WSADATA wsa_data; + static bool wsa_init = false; + if( !wsa_init ) { + if( WSAStartup( MAKEWORD( 2, 2 ), &wsa_data ) != 0 ) { + assert( true, "WSAStartup() error" ); + return INVALID_SOCKET; + } + + wsa_init = true; + } + + return socket( family, type, protocol ); +} + +inline U32 net_connect( U32 socket, const char* ip, U16 port ) { + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons( port ); + inet_pton( AF_INET, ip, &addr.sin_addr.s_addr ); + + return connect( socket, (sockaddr*)&addr, sizeof( addr ) ); +} + +inline SSL_CTX* ssl_create_context() { + OpenSSL_add_all_algorithms(); +#ifdef DEBUG + SSL_load_error_strings(); +#endif + + SSL_CTX* ctx = SSL_CTX_new( TLSv1_2_client_method() ); + if( !ctx ) + return nullptr; + + return ctx; +} + +inline SSL* ssl_connect( SSL_CTX* ctx, int sock ) { + SSL* ssl = SSL_new( ctx ); + if( !ssl ) + return nullptr; + + SSL_set_fd( ssl, sock ); + if( SSL_connect( ssl ) <= 0 ) + return nullptr; + + return ssl; +} + +inline void ssl_destroy( SSL* ssl ) { + if( ssl ) + SSL_free( ssl ); +} + +inline void ssl_destroy_context( SSL_CTX* ctx ) { + if( ctx ) + SSL_CTX_free( ctx ); +} + +inline int ssl_send( SSL* ssl, const void* data, int len ) { + return SSL_write( ssl, data, len ); +}
\ No newline at end of file diff --git a/src/mathutil.h b/src/mathutil.h new file mode 100644 index 0000000..d1672ec --- /dev/null +++ b/src/mathutil.h @@ -0,0 +1,21 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "typedef.h" + + +template < typename t > +inline t u_clamp( t in, const t& min, const t& max ) { + return in < min ? min : in > max ? max : in; +} + +template < typename t > +inline t u_max( const t& t1, const t& t2 ) { + return t1 > t2 ? t1 : t2; +} + +template < typename t > +inline t u_min( const t& t1, const t& t2 ) { + return t1 > t2 ? t2 : t1; +}
\ No newline at end of file diff --git a/src/menu.cpp b/src/menu.cpp new file mode 100644 index 0000000..a1c8fc8 --- /dev/null +++ b/src/menu.cpp @@ -0,0 +1,383 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include "menu.h" +#include "conin.h" + +#include "csgo/hack.h" + +CSGO* csgop; + +I8 menu_page = 1; +MENU_PAGE menu_pages[MENU_PAGE_MAX - MENU_PAGE_MIN + 1]; + +void show_paging( U8 num ) { + char line_str[CON_MAX_WIDTH + 3]{}; + + U32 cur_char = 0; + if( num > MENU_PAGE_MIN ) { + sprintf( line_str, "<-%s", menu_pages[num-1].name ); + cur_char = strlen( line_str ); + } + + char mid_str[16]; + sprintf( mid_str, "[%d] %s", num, menu_pages[num].name ); + I32 mid_len = strlen( mid_str ); + + I32 diff = CON_MAX_WIDTH / 2 - (I32)cur_char - mid_len / 2; + + memset( line_str + cur_char, ' ', diff ); + cur_char += diff; + + strcat( line_str, mid_str ); + cur_char += mid_len; + + if( num < MENU_PAGE_MAX ) { + char next_str[16]; + sprintf( next_str, "%s->", menu_pages[num+1].name ); + + I32 next_len = strlen( next_str ); + I32 diff = CON_MAX_WIDTH - (I32)cur_char - next_len; + + memset( line_str + cur_char, ' ', diff ); + strcat( line_str, next_str ); + } + + con_set_line( + CON_MAX_HEIGHT - 1, + line_str, + "", + con_selected_line == CON_MAX_HEIGHT - 1, + CONFG_MAGENTA + ); + + con_set_line_callback( + CON_MAX_HEIGHT - 1, + []( CON_LINE* self, U8 action ) { + if( action == LINE_ACTION_LEFTARROW && menu_page > MENU_PAGE_MIN ) + --menu_page; + if( action == LINE_ACTION_RIGHTARROW && menu_page < MENU_PAGE_MAX ) + ++menu_page; + + con_clear(); + menu_pages[menu_page].page_fn(); + show_paging( menu_page ); + } ); +} + +void show_page_0() { + con_set_line_text( 0, "load config", false ); + con_set_line_subtext( 0, "[ENTER]", false, CONFG_LIGHTBLUE ); + con_set_line_callback( 0, []( CON_LINE* self, U8 action ) { + if( action == LINE_ACTION_ENTER ) { + settings.load(); + } + } ); + + con_set_line_text( 1, "save config", false ); + con_set_line_subtext( 1, "[ENTER]", false, CONFG_LIGHTBLUE ); + con_set_line_callback( 1, []( CON_LINE* self, U8 action ) { + if( action == LINE_ACTION_ENTER ) { + settings.save(); + } + } ); + + con_set_line_text( 2, "perf_tickrate", false ); + con_set_line_subtext( 2, u_num_to_string_dec( perf_tickrate ), false, CONFG_BLUE ); + con_set_line_callback( 2, []( CON_LINE* self, U8 action ) { + if( action == LINE_ACTION_LEFTARROW ) { + if( GetAsyncKeyState( VK_LCONTROL ) & 0x8000 ) { + if( perf_tickrate > 10 ) + perf_tickrate -= 10; + else + perf_tickrate = 0; + } else { + if( perf_tickrate > 0 ) + --perf_tickrate; + } + } + if( action == LINE_ACTION_RIGHTARROW ) { + if( GetAsyncKeyState( VK_LCONTROL ) & 0x8000 ) { + if( perf_tickrate < 2048 ) + perf_tickrate += 10; + else + perf_tickrate = 2048; + } else { + if( perf_tickrate < 2048 ) + ++perf_tickrate; + } + } + + con_set_line_subtext( 2, u_num_to_string_dec( perf_tickrate ), true, CONFG_BLUE ); + } ); +} + +void show_page_1() { + static SETTING<bool>& bhop_active = *settings.find<bool>( "bhop_active"fnv ); + static SETTING<bool>& chams_active = *settings.find<bool>( "chams_active"fnv ); + static SETTING<bool>& glow_active = *settings.find<bool>( "glow_active"fnv ); + static SETTING<bool>& nightmode_active = *settings.find<bool>( "nightmode_active"fnv ); + static SETTING<bool>& noflash_active = *settings.find<bool>( "noflash_active"fnv ); + static SETTING<bool>& clantag_active = *settings.find<bool>( "clantag_active"fnv ); + + con_set_line_text( 0,"bhop",false ); + con_set_line_subtext( + 0, + bhop_active? "[on]" : "[off]", + con_selected_line == 0, + bhop_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + + con_set_line_callback(0,[]( CON_LINE *self,U8 action ) { + bhop_active = !bhop_active; + con_set_line_subtext( + 0, + bhop_active? "[on]" : "[off]", + self->active, + bhop_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + }); + + con_set_line_text(1, "chams", false); + con_set_line_subtext( + 1, + chams_active? "[on]" : "[off]", + false, + chams_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + + con_set_line_callback( 1, []( CON_LINE *self,U8 action ) { + chams_active = !chams_active; + con_set_line_subtext( + 1, + chams_active? "[on]" : "[off]", + self->active, + chams_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + }); + + con_set_line_text(2, "glow", false); + con_set_line_subtext( + 2, + glow_active? "[on]" : "[off]", + false, + glow_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + + con_set_line_callback( 2, []( CON_LINE *self,U8 action ) { + glow_active = !glow_active; + con_set_line_subtext( + 2, + glow_active? "[on]" : "[off]", + self->active, + glow_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + }); + + con_set_line_text(3, "nightmode", false); + con_set_line_subtext( + 3, + nightmode_active? "[on]" : "[off]", + false, + nightmode_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + + con_set_line_callback( 3, []( CON_LINE *self,U8 action ) { + nightmode_active = !nightmode_active; + con_set_line_subtext( + 3, + nightmode_active? "[on]" : "[off]", + self->active, + nightmode_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + }); + + con_set_line_text( 4, "no flash", false ); + con_set_line_subtext( + 4, + noflash_active? "[on]" : "[off]", + false, + noflash_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + + con_set_line_callback( 4, []( CON_LINE *self,U8 action ) { + noflash_active = !noflash_active; + con_set_line_subtext( + 4, + noflash_active? "[on]" : "[off]", + self->active, + noflash_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + }); + + con_set_line_text( 5, "clantag changer" ); + con_set_line_subtext( + 5, + clantag_active? "[on]" : "[off]", + false, + clantag_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + + con_set_line_callback( 5, []( CON_LINE* self, U8 action ) { + clantag_active = !clantag_active; + con_set_line_subtext( + 5, + clantag_active? "[on]" : "[off]", + self->active, + clantag_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + } ); + + con_set_line_text( 6, "dump all classes to classes.dump", false ); + con_set_line_subtext( + 6, + key_titles[VK_RETURN], + false, + CONFG_LIGHTBLUE + ); + + con_set_line_callback( 6, []( CON_LINE*, U8 action ) { + if( action == LINE_ACTION_ENTER ) + csgo_dump_classes( csgop ); + } ); + + + con_set_line_text( 7, "dump syscalls to syscall_arch.dump", false ); + con_set_line_subtext( + 7, + key_titles[VK_RETURN], + false, + CONFG_LIGHTBLUE + ); + + con_set_line_callback( 7, []( CON_LINE*, U8 action ) { + if( action == LINE_ACTION_ENTER ) + syscall_dump_to_file(); + } ); + + con_set_line_text( 8, "dump interfaces to interfaces.dump", false ); + con_set_line_subtext( + 8, + key_titles[VK_RETURN], + false, + CONFG_LIGHTBLUE + ); + + con_set_line_callback( 8, []( CON_LINE*, U8 action ) { + if( action == LINE_ACTION_ENTER ) + csgo_dump_ifaces_to_file( csgop ); + } ); +} + +void show_page_2() { + static SETTING<bool>& aim_active = *settings.find<bool>( "aim_active"fnv ); + static SETTING<bool>& crosshair_active = *settings.find<bool>( "crosshair_active"fnv ); + static SETTING<bool>& rcs_active = *settings.find<bool>( "rcs_active"fnv ); + static SETTING<I32>& triggerbot_key = *settings.find<I32>( "triggerbot_key"fnv ); + static SETTING<bool>& triggerteam_active = *settings.find<bool>( "triggerteam_active"fnv ); + + con_set_line_text( 0,"aim assist",false ); + con_set_line_subtext( + 0, + aim_active? "[on]" : "[off]", + con_selected_line == 0, + aim_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + + con_set_line_callback(0,[]( CON_LINE *self,U8 action ) { + aim_active = !aim_active; + con_set_line_subtext( + 0, + aim_active? "[on]" : "[off]", + self->active, + aim_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + }); + + con_set_line_text( 1, "rcs xhair", false); + con_set_line_subtext( + 1, + crosshair_active? "[on]" : "[off]", + false, + crosshair_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + + con_set_line_callback( 1, []( CON_LINE *self,U8 action ) { + crosshair_active = !crosshair_active; + con_set_line_subtext( + 1, + crosshair_active? "[on]" : "[off]", + self->active, + crosshair_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + }); + + con_set_line_text( 2, "rcs", false ); + con_set_line_subtext( + 2, + rcs_active? "[on]" : "[off]", + false, + rcs_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + + con_set_line_callback( 2, []( CON_LINE *self,U8 action ) { + rcs_active = !rcs_active; + con_set_line_subtext( + 2, + rcs_active? "[on]" : "[off]", + self->active, + rcs_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + }); + + con_set_line_text( 3, "triggerbot", false ); + con_set_line_subtext( + 3, + key_titles[triggerbot_key], + false, + CONFG_LIGHTBLUE + ); + + con_set_line_callback( 3, []( CON_LINE *,U8 action ) { + if( action == LINE_ACTION_ENTER ) { + con_update_hotkey( 3, triggerbot_key.v ); + } + } ); + + con_set_line_text( 4, "trigger team", false ); + con_set_line_subtext( + 4, + triggerteam_active? "[on]" : "[off]", + false, + triggerteam_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + + con_set_line_callback( 4, []( CON_LINE *self,U8 action ) { + triggerteam_active = !triggerteam_active; + con_set_line_subtext( + 4, + triggerteam_active? "[on]" : "[off]", + self->active, + triggerteam_active? CONFG_LIGHTGREEN : CONFG_LIGHTRED + ); + }); +} + +void menu_show_ui( PROCESS32 *p ) { + csgop = (CSGO*)p; + + con_clear(); + con_capturing_input = true; + + menu_pages[0] = { "config", &show_page_0 }; + menu_pages[1] = { "general", &show_page_1 }; + menu_pages[2] = { "aim", &show_page_2 }; + + show_page_1(); + show_paging( 1 ); + + con_set_bottomline_text( + "LOCALPLAYER: %08X | FLAGS: %08X | menu", + p->read<U32>( localplayer_ptr ),0x0 + ); +}
\ No newline at end of file diff --git a/src/menu.h b/src/menu.h new file mode 100644 index 0000000..f728c73 --- /dev/null +++ b/src/menu.h @@ -0,0 +1,86 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once + +#include "process.h" +#include "util.h" + +#include "syscall.h" +#include "csgo/csgo.h" + +static void syscall_dump_to_file() { + static VECTOR< SYSCALL_ENTRY > syscalls = syscall_dump(); + static VECTOR< SYSCALL_ENTRY > syscalls64 = syscall_dump64(); + static VECTOR< MODULE_EXPORT64 > nt64_exports = module_get_exports64( nt_get_address64() ); + char* syscall_str = (char*)malloc( 100000 ); + + memset( syscall_str, 0, 100000 ); + + char line_buf[256]{}; + for( auto& it : syscalls ) { + sprintf_s<256>( line_buf, "%d %s -> %llx\n", it.idx, it.name.data, it.base ); + strcat( syscall_str, line_buf ); + } + + FILE* dump = fopen( "./syscalls_32.dump", "w" ); + fwrite( syscall_str, strlen( syscall_str ), 1, dump ); + fclose( dump ); + + memset( syscall_str, 0, 100000 ); + + for( auto& it : syscalls64 ) { + sprintf_s<256>( line_buf, "%d %s -> %llx\n", it.idx, it.name.data, it.base ); + strcat( syscall_str, line_buf ); + } + + dump = fopen( "./syscalls_64.dump", "w" ); + fwrite( syscall_str, strlen( syscall_str ), 1, dump ); + fclose( dump ); + + memset( syscall_str, 0, 100000 ); + + for( auto& it : nt64_exports ) { + sprintf_s<256>( line_buf, "%s -> %llx\n", it.name.data, it.base ); + strcat( syscall_str, line_buf ); + } + + dump = fopen( "./nt64.dump", "w" ); + fwrite( syscall_str, strlen( syscall_str ), 1, dump ); + fclose( dump ); + + free( syscall_str ); +} + +static void csgo_dump_ifaces_to_file( CSGO* p ) { + std::vector< IFACE_ENTRY > ifaces = srceng_get_interfaces( p ); + static char iface_str[999999]{}; + + memset( iface_str, 0, sizeof( iface_str ) ); + char line_buf[256]{}; + for( auto& it : ifaces ) { + sprintf( line_buf, "%s -> %08x in [%s]\n", it.name.data, it.ptr, it.module_name.data ); + strcat( iface_str, line_buf ); + } + + FILE* dump = fopen( "./interfaces.dump", "w" ); + fwrite( iface_str, strlen( iface_str ), 1, dump ); + fclose( dump ); +} + +void show_paging( U8 num ); + +typedef void(*CON_PAGE_FN)(); + +struct MENU_PAGE { + const char* name; + CON_PAGE_FN page_fn; +}; + +const I8 MENU_PAGE_MIN = 0; +const I8 MENU_PAGE_MAX = 2; + +extern I8 menu_page; +extern MENU_PAGE menu_pages[MENU_PAGE_MAX - MENU_PAGE_MIN + 1]; + +extern void menu_show_ui( PROCESS32* p );
\ No newline at end of file diff --git a/src/mouse.h b/src/mouse.h new file mode 100644 index 0000000..ef41881 --- /dev/null +++ b/src/mouse.h @@ -0,0 +1,32 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include <windows.h> +#include <winternl.h> +#pragma comment( lib, "ntdll.lib" ) + +#include "util.h" + +struct LOGITECH_MOUSE_IO { + char button; + char x; + char y; + char wheel; +private: + char unk; +}; + +HANDLE nt_init_device( const char* device_name ) { + UNICODE_STRING name; + OBJECT_ATTRIBUTES attr; + + RtlInitUnicodeString(&name, u_ansi_to_widebyte( device_name ) ); + InitializeObjectAttributes( &attr, &name, 0, NULL, NULL ); + + NTSTATUS status = NtCreateFile(&g_input, GENERIC_WRITE | SYNCHRONIZE, &attr, &g_io, 0, + FILE_ATTRIBUTE_NORMAL, 0, 3, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 0, 0); + + return status; +} + +HANDLE mouse_open( )
\ No newline at end of file diff --git a/src/ntutil.cpp b/src/ntutil.cpp new file mode 100644 index 0000000..c0f6b98 --- /dev/null +++ b/src/ntutil.cpp @@ -0,0 +1,304 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include "ntutil.h" +#include "syscall.h" + +// it's big nigga season + +NTSTATUS64 nt_create_thread64( + REG64* thread, + ACCESS_MASK mask, + _OBJECT_ATTRIBUTES64* object_attributes, + HANDLE process_handle, + LPTHREAD_START_ROUTINE start_routine, + void* parameter, + U32 suspended, + U32 stack_zero_bits, + U32 stack_commit, + U32 stack_reserve +) { + static SYSCALL_ENTRY nt_create_thread = syscall_find_syscall64( "NtCreateThreadEx"fnv ); + + REG64 start = (U64)start_routine; + REG64 access64 = (U64)mask; + REG64 process64 = (U64)process_handle; + REG64 thread_handle_ptr = (U64)thread; + REG64 object_attributes_ptr = (U64)object_attributes; + REG64 suspended64 = (U64)suspended; + REG64 parameter64 = (U64)parameter; + + REG64 stack_zero_bits64 = stack_zero_bits; + REG64 stack_commit64 = stack_commit; + REG64 stack_reserve64 = stack_reserve; + + REG64 unk64{}; + + NTSTATUS64 status = syscall_execute( nt_create_thread.idx, + thread_handle_ptr, + access64, + object_attributes_ptr, + process64, + start, + parameter64, + suspended64, + stack_zero_bits64, + stack_commit64, + stack_reserve64, + unk64 + ); + + return status; +} + +NTSTATUS64 nt_close64( REG64 handle ) { + static SYSCALL_ENTRY nt_close = syscall_find_syscall( "NtClose"fnv ); + + NTSTATUS64 status = syscall_execute( nt_close.idx, handle ); + return status; +} + +NTSTATUS64 nt_open_process64( + HANDLE* handle, + U32 desired_access, + _OBJECT_ATTRIBUTES64* obj_attrbitues, + _CLIENT_ID_T<U64>* client_id +) { + static SYSCALL_ENTRY nt_open_process = syscall_find_syscall( "NtOpenProcess"fnv ); + + REG64 handle64{}; + REG64 desired_access64 = (U64)desired_access; + REG64 object_attributes64 = (U64)obj_attrbitues; + REG64 client_id64 = (U64)client_id; + + NTSTATUS64 status = syscall_execute( nt_open_process.idx, + (REG64)(U64)&handle64, + desired_access64, + object_attributes64, + client_id64 + ); + + *handle = (HANDLE)handle64.u32[0]; + return status; +} + +NTSTATUS64 nt_write_vm64( + HANDLE handle, + U64 address, + void* value, + ULONG size, + U64* out_ret_bytes +) { + static SYSCALL_ENTRY nt_write_vm = syscall_find_syscall( "NtWriteVirtualMemory"fnv ); + + REG64 handle64 = (U64)handle; + REG64 address64 = address; + REG64 value64 = (U64)value; + REG64 size64 = (U64)size; + REG64 out_ret_bytes64 = (U64)out_ret_bytes; + + NTSTATUS64 status = syscall_execute( nt_write_vm.idx, + handle64, + address64, + value64, + size64, + out_ret_bytes64 + ); + + return status; +} + +NTSTATUS64 nt_read_vm64( + HANDLE handle, + U64 address, + void* buffer, + ULONG size, + U64* out_ret_bytes +) { + static SYSCALL_ENTRY nt_write_vm = syscall_find_syscall( "NtReadVirtualMemory"fnv ); + + REG64 handle64 = (U64)handle; + REG64 address64 = address; + REG64 buffer64 = (U64)buffer; + REG64 size64 = (U64)size; + REG64 out_ret_bytes64 = (U64)out_ret_bytes; + + NTSTATUS64 status = syscall_execute( nt_write_vm.idx, + handle64, + address64, + buffer64, + size64, + out_ret_bytes64 + ); + + return status; +} + +NTSTATUS64 nt_query_vm64( + HANDLE handle, + U64 address, + WIN32_MEMORY_INFORMATION_CLASS information_class, + void* memory_information, + U64 memory_information_length, + U64* return_length + ) { + static SYSCALL_ENTRY nt_query_vm = syscall_find_syscall( "NtQueryVirtualMemory"fnv ); + + REG64 handle64 = (U64)handle; + REG64 address64 = address; + REG64 info_class64 = (U64)information_class; + REG64 memory_information64 = (U64)memory_information; + REG64 memory_information_length64 = memory_information_length; + REG64 return_length64 = (U64)return_length; + + NTSTATUS64 status = syscall_execute( nt_query_vm.idx, + handle64, + address64, + info_class64, + memory_information64, + memory_information_length64, + return_length64 + ); + + return status; +} + +NTSTATUS64 nt_allocate_vm64( + HANDLE handle, + U64* allocated_address, + ULONG zero_bits, + U64* region_size, + ULONG allocation_type, + ULONG protect) { + static SYSCALL_ENTRY nt_allocate_vm = syscall_find_syscall64( "NtAllocateVirtualMemory"fnv ); + + REG64 handle64 = (U64)handle; + REG64 allocated_address64 = (U64)allocated_address; + REG64 zero_bits64 = (U64)zero_bits; + REG64 region_size64 = (U64)region_size; + REG64 allocation_type64 = (U64)allocation_type; + REG64 protect64 = (U64)protect; + + NTSTATUS64 status = syscall_execute( nt_allocate_vm.idx, + handle64, + allocated_address64, + zero_bits64, + region_size64, + allocation_type64, + protect64 + ); + + return status; +} + +NTSTATUS64 nt_query_system_information64( + SYSTEM_INFORMATION_CLASS info_class, + void* system_information, + ULONG system_infromation_length, + ULONG* return_length +) { + static SYSCALL_ENTRY nt_query_system_info = syscall_find_syscall( "NtQuerySystemInformation"fnv ); + + REG64 info_class64 = (U64)info_class; + REG64 system_information64 = (U64)system_information; + REG64 system_information_length64 = (U64)system_infromation_length; + REG64 return_length64 = (U64)return_length; + + NTSTATUS64 status = syscall_execute( nt_query_system_info.idx, + info_class64, + system_information64, + system_information_length64, + return_length64 + ); + + return status; +} + +NTSTATUS64 nt_query_information_process64( + HANDLE handle, + PROCESSINFOCLASS info_class, + void* process_information, + ULONG process_information_length, + ULONG* out_information_length +) { + static SYSCALL_ENTRY nt_query_info_process = syscall_find_syscall64( "NtQueryInformationProcess"fnv ); + + REG64 handle64 = (U64)handle; + REG64 info_class64 = (U64)info_class; + REG64 process_info64 = (U64)process_information; + REG64 process_info_length64 = (U64)process_information_length; + REG64 out_info_length64 = (U64)out_information_length; + + NTSTATUS64 status = syscall_execute( nt_query_info_process.idx, + handle64, + info_class64, + process_info64, + process_info_length64, + out_info_length64 + ); + + return status; +} + +NTSTATUS64 nt_delay_execution64( + BOOLEAN alterable, + LARGE_INTEGER* delay_interval +) { + static SYSCALL_ENTRY nt_delay_execution = syscall_find_syscall64( "NtDelayExecution"fnv ); + + REG64 alterable64 = (U64)alterable; + REG64 delay_interval64 = (U64)delay_interval; + + NTSTATUS64 status = syscall_execute( nt_delay_execution.idx, + alterable64, + delay_interval64 + ); + + return status; +} + +NTSTATUS64 nt_query_object64( + HANDLE handle, + I32 info_class, + void* object_information, + ULONG object_information_length, + ULONG* return_length +) { + static SYSCALL_ENTRY nt_query_object = syscall_find_syscall64( "NtQueryObject"fnv ); + + REG64 handle64 = (U64)handle; + REG64 info_class64 = (U64)info_class; + REG64 object_info64 = (U64)object_information; + REG64 object_info_length64 = (U64)object_information_length; + REG64 return_length64 = (U64)return_length; + + NTSTATUS64 status = syscall_execute( nt_query_object.idx, + handle64, + info_class64, + object_info64, + object_info_length64, + return_length64 + ); + + return status; +} + +NTSTATUS64 nt_set_timer_resolution64( + ULONG desired_resolution, + BOOLEAN set_resolution, + ULONG* current_resolution) { + static SYSCALL_ENTRY nt_set_timer_resolution = syscall_find_syscall64( "NtSetTimerResolution"fnv ); + + REG64 desired_resolution64 = (U64)desired_resolution; + REG64 set_resolution64 = (U64)set_resolution; + REG64 current_resolution64 = (U64)current_resolution; + + NTSTATUS64 status = syscall_execute( nt_set_timer_resolution.idx, + desired_resolution64, + set_resolution64, + current_resolution64 + ); + + return status; +} + diff --git a/src/ntutil.h b/src/ntutil.h new file mode 100644 index 0000000..feca8f6 --- /dev/null +++ b/src/ntutil.h @@ -0,0 +1,251 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include <Windows.h> +#include <winternl.h> +#include <vector> +#include "x86.h" +#include "winintern.h" +#include "asmutil.h" +#include "util.h" + +struct MODULE_EXPORT { + const char* name; + void* base; +}; + +struct MODULE_EXPORT64 { + STR<256> name; + U64 base; +}; + +inline void* nt_get_address() { + U32 fs_offset = (U32)&( (NT_TIB*)nullptr )->Self; + + PTEB teb = (PTEB)( __readfsdword( fs_offset ) ); + PEB* peb = teb->ProcessEnvironmentBlock; + + auto ldr_entry = (PLDR_DATA_TABLE_ENTRY)peb->Ldr->InMemoryOrderModuleList.Flink[0].Flink; + auto data_entry = ldr_entry->Reserved2[0]; + + return data_entry; +} + +inline U64 nt_get_address64() { + REG64 _ret; + + heavens_gate_enter(); + + { + db( 0x65 ) db( 0x48 ) db( 0x8b ) db( 0x04 ) db( 0x25 ) + db( 0x30 ) db( 0x00 ) db( 0x00 ) db( 0x00 ) // mov rax, qword ptr[gs:0x30] // get TEB + db( 0x48 ) db( 0x8b ) db( 0x40 ) db( 0x60 ) // mov rax, qword ptr[rax+0x60] // TEB->PEB + db( 0x48 ) db( 0x8b ) db( 0x40 ) db( 0x18 ) // mov rax, qword ptr[rax+0x18] // PEB->LDR + db( 0x48 ) db( 0x8b ) db( 0x40 ) db( 0x10 ) // mov rax, qword ptr[rax+0x10] // LDR->InMemList + db( 0x48 ) db( 0x8b ) db( 0x00 ) // mov rax, qword ptr[rax] // *InMemList.Flink + db( 0x48 ) db( 0x8b ) db( 0x40 ) db( 0x30 ) // mov rax, qword ptr[rax+0x30] // entry->DllBase + } + + __asm { + rex_w mov _ret.u32[0], eax + } + + heavens_gate_exit(); + + return _ret.u64; +} + +inline std::vector< MODULE_EXPORT > module_get_exports( void* module_base ) { + auto dos_header = (IMAGE_DOS_HEADER*)( module_base ); + auto nt_headers = (IMAGE_NT_HEADERS*)( (U32)module_base + dos_header->e_lfanew ); + auto data_dir = nt_headers->OptionalHeader.DataDirectory[0].VirtualAddress; + auto export_dir = (IMAGE_EXPORT_DIRECTORY*)( data_dir + (U32)module_base ); + + U32* names = (U32*)( (U32)module_base + export_dir->AddressOfNames ); + U32* funcs = (U32*)( (U32)module_base + export_dir->AddressOfFunctions ); + U16* ords = (U16*)( (U32)module_base + export_dir->AddressOfNameOrdinals ); + + std::vector< MODULE_EXPORT > ret; + for( U32 i = 0; i < export_dir->NumberOfNames; ++i ) { + const char* name = (const char*)( (U32)module_base + names[i] ); + void* func = (void*)( (U32)module_base + funcs[ords[i]] ); + + ret.push_back( { name, func } ); + } + + return ret; +}; + +extern NTSTATUS64 nt_create_thread64( + REG64* thread, + ACCESS_MASK mask, + _OBJECT_ATTRIBUTES64* object_attributes, + HANDLE process_handle, + LPTHREAD_START_ROUTINE start_routine, + void* parameter, + U32 suspended, + U32 stack_zero_bits = 0, + U32 stack_commit = 0, + U32 stack_reserve = 0 +); + +extern NTSTATUS64 nt_close64( + REG64 handle +); + +inline NTSTATUS64 nt_close64( HANDLE handle ) { + return nt_close64( (U64)handle ); +} + +extern NTSTATUS64 nt_open_process64( + HANDLE* handle, + U32 desired_access, + _OBJECT_ATTRIBUTES64* obj_attrbitues, + _CLIENT_ID_T<U64>* client_id +); + +extern NTSTATUS64 nt_write_vm64( + HANDLE handle, + U64 address, // imagine lmfao + void* value, + ULONG size, + U64* out_ret_bytes = 0 +); + +extern NTSTATUS64 nt_read_vm64( + HANDLE handle, + U64 address, + void* buffer, + ULONG size, + U64* out_ret_bytes = 0 +); + +extern NTSTATUS64 nt_query_vm64( + HANDLE handle, + U64 address, + WIN32_MEMORY_INFORMATION_CLASS information_class, + void* memory_information, + U64 memory_information_length, + U64* return_length = 0 +); + +extern NTSTATUS64 nt_allocate_vm64( + HANDLE handle, + U64* allocated_address, + ULONG zero_bits, + U64* region_size, + ULONG allocation_type, + ULONG protect +); + +extern NTSTATUS64 nt_free_vm64( + HANDLE handle, + U64* address, + U64* size, + ULONG free_type +); + +extern NTSTATUS64 nt_query_system_information64( + SYSTEM_INFORMATION_CLASS info_class, + void* system_information, + ULONG system_infromation_length, + ULONG* return_length +); + +extern NTSTATUS64 nt_query_information_process64( + HANDLE handle, + PROCESSINFOCLASS info_class, + void* process_information, + ULONG process_information_length, + ULONG* out_information_length +); + +extern NTSTATUS64 nt_delay_execution64( + BOOLEAN alterable, + LARGE_INTEGER* delay_interval +); + +extern NTSTATUS64 nt_query_object64( + HANDLE handle, + I32 info_class, + void* object_information, + ULONG object_information_length, + ULONG* return_length +); + +extern NTSTATUS64 nt_set_timer_resolution64( + ULONG desired_resolution, + BOOLEAN set_resolution, + ULONG* current_resolution +); + +inline std::vector< MODULE_EXPORT64 > module_get_exports( U32 module_base, HANDLE proc = (HANDLE)-1 ) { + std::vector< MODULE_EXPORT64 > ret; + IMAGE_DOS_HEADER dos_header; + IMAGE_NT_HEADERS nt_headers; + U32 data_dir; + IMAGE_EXPORT_DIRECTORY export_dir; + + nt_read_vm64( proc, module_base, &dos_header, sizeof( dos_header ) ); + nt_read_vm64( proc, module_base + dos_header.e_lfanew, &nt_headers, sizeof( nt_headers ) ); + data_dir = nt_headers.OptionalHeader.DataDirectory[0].VirtualAddress; + nt_read_vm64( proc, module_base + data_dir, &export_dir, sizeof( export_dir ) ); + + U32 names = module_base + export_dir.AddressOfNames; + U32 funcs = module_base + export_dir.AddressOfFunctions; + U32 ords = module_base + export_dir.AddressOfNameOrdinals; + + char name[256]{}; + U32 func = 0; + U16 ord; + U32 str_ptr = 0; + + for( U32 i = 0; i < export_dir.NumberOfNames; ++i ) { + nt_read_vm64( proc, names + 0x4 * i, &str_ptr, 0x4 ); + nt_read_vm64( proc, module_base + str_ptr, name, 256 ); + + nt_read_vm64( proc, ords + 0x2 * i, &ord, 0x2 ); + nt_read_vm64( proc, funcs + 0x4 * ord, &func, 0x4 ); + + name[255] = 0; + ret.push_back( { STR<256>( name ), module_base + func } ); + } + + return ret; +} + +inline std::vector< MODULE_EXPORT64 > module_get_exports64( U64 module_base, HANDLE proc = (HANDLE)-1 ) { + std::vector< MODULE_EXPORT64 > ret; + IMAGE_DOS_HEADER dos_header; + IMAGE_NT_HEADERS64 nt_headers; + U64 data_dir; + IMAGE_EXPORT_DIRECTORY export_dir; + + nt_read_vm64( proc, module_base, &dos_header, sizeof( dos_header ) ); + nt_read_vm64( proc, module_base + dos_header.e_lfanew, &nt_headers, sizeof( nt_headers ) ); + data_dir = nt_headers.OptionalHeader.DataDirectory[0].VirtualAddress; + nt_read_vm64( proc, module_base + data_dir, &export_dir, sizeof( export_dir ) ); + + U64 names = module_base + export_dir.AddressOfNames; + U64 funcs = module_base + export_dir.AddressOfFunctions; + U64 ords = module_base + export_dir.AddressOfNameOrdinals; + + char name[256]{}; + U64 func = 0; + U16 ord; + U64 str_ptr = 0; + + for( U32 i = 0; i < export_dir.NumberOfNames; ++i ) { + nt_read_vm64( proc, names + 0x4 * i, &str_ptr, 0x4 ); + nt_read_vm64( proc, module_base + str_ptr, name, 256, 0 ); + + nt_read_vm64( proc, ords + 0x2 * i, &ord, 0x2 ); + nt_read_vm64( proc, funcs + 0x4 * ord, &func, 0x4 ); + + + ret.push_back( { STR<128>( name ), module_base + func } ); + } + + return ret; +}
\ No newline at end of file diff --git a/src/process.h b/src/process.h new file mode 100644 index 0000000..ed4cde8 --- /dev/null +++ b/src/process.h @@ -0,0 +1,358 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include <Windows.h> +#include <TlHelp32.h> + +#include "ntutil.h" +#include "winintern.h" +#include "typedef.h" +#include "fnv.h" + +#include "conout.h" + + +struct MODULE_ENTRY { + U64 base; + U64 size; + STR<64> name; + FNV1A hash; +}; + +class PROCESS32 { +private: + HANDLE m_base{}; + U64 m_id{}; + char m_name[256]{}; + +private: + + +public: + PROCESS32( const char* name ) { + memset( m_name, 0, 256 ); + memcpy( m_name, name, strlen( name ) ); + }; + + HANDLE get_base() { return m_base; } + + I8 open() { + m_id = 0; + + const U32 PINFO_ALLOC_SIZE = 0x400000; + _SYSTEM_PROCESS_INFORMATION64* pinfo; + ULONG received_bytes; + + pinfo = (_SYSTEM_PROCESS_INFORMATION64*)VirtualAlloc( + 0, + PINFO_ALLOC_SIZE, + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE + ); + + NTSTATUS64 status = nt_query_system_information64( + SystemProcessInformation, + pinfo, + PINFO_ALLOC_SIZE, + &received_bytes + ); + + if( status != STATUS_SUCCESS ) + return 0; + + wchar_t name_buffer[128]; + do { + if( pinfo->ImageName.Buffer ) { + nt_read_vm64( (HANDLE)-1, pinfo->ImageName.Buffer, name_buffer, 256 ); + STR<128> pname = u_widebyte_to_ansi( name_buffer ); + if( !strcmp( pname, m_name ) ) { + m_id = pinfo->UniqueProcessId; + break; + } + } + + pinfo = (decltype( pinfo ))( (U32)pinfo + pinfo->NextEntryOffset ); + } while( !!pinfo->NextEntryOffset ); + + VirtualFree( pinfo, PINFO_ALLOC_SIZE, MEM_FREE ); + + _OBJECT_ATTRIBUTES64 obj_attributes{}; + _CLIENT_ID_T<U64> cid; + + cid.UniqueProcess = (U64)( UlongToHandle( m_id ) ); + cid.UniqueThread = 0; + obj_attributes.Length = sizeof( obj_attributes ); + + status = nt_open_process64( + &m_base, + PROCESS_ALL_ACCESS, + &obj_attributes, + &cid + ); + + return status == STATUS_SUCCESS; + } + + U8 valid() { + PROCESS_BASIC_INFORMATION64 info; + + // 4 = ObjectHandleFlagInformation + NTSTATUS64 status = nt_query_information_process64( + m_base, ProcessBasicInformation, + &info, + sizeof(info), + 0 + ); + + if( status != STATUS_SUCCESS ) + return 0; + + return info.ExitStatus != 0; + } + + U32 get_module_size32( U64 module_base ) { + IMAGE_NT_HEADERS nt_headers; + IMAGE_DOS_HEADER dos_header; + + read( module_base, &dos_header, sizeof( dos_header ) ); + read( module_base + dos_header.e_lfanew, &nt_headers, sizeof( nt_headers ) ); + + return nt_headers.OptionalHeader.SizeOfImage; + } + + U64 get_module_size64( U64 module_base ) { + IMAGE_NT_HEADERS64 nt_headers; + IMAGE_DOS_HEADER dos_header; + + read( module_base, &dos_header, sizeof( dos_header ) ); + read( module_base + dos_header.e_lfanew, &nt_headers, sizeof( nt_headers ) ); + + return nt_headers.OptionalHeader.SizeOfImage; + } + + std::vector< MODULE_ENTRY > dump_modules64() { + std::vector< MODULE_ENTRY > ret; + PROCESS_BASIC_INFORMATION64 pbi; + ULONG pbi_len; + PEB64 peb; + NTSTATUS64 status; + + status = nt_query_information_process64( + m_base, + ProcessBasicInformation, + &pbi, + sizeof( PROCESS_BASIC_INFORMATION64 ), + &pbi_len + ); + + read( pbi.PebBaseAddress, &peb, sizeof( PEB64 ) ); + + PEB_LDR_DATA64 ldr; + read( peb.Ldr, &ldr, sizeof( ldr ) ); + + U64 root = ldr.InMemoryOrderModuleList.Flink; + for( U64 entry = read<U64>( root ); entry != root && !!entry; entry = read<U64>( entry ) ) { + LDR_DATA_TABLE_ENTRY64 ldr_entry; + read( entry, &ldr_entry, sizeof( ldr_entry ) ); + + if( !ldr_entry.FullDllName.Buffer ) + continue; + + wchar_t module_buffer[256]{}; + read( + ldr_entry.FullDllName.Buffer, + module_buffer, 256 * sizeof( wchar_t ) + ); + + STR<256> module_name = u_widebyte_to_ansi<256>( module_buffer ); + FNV1A module_hash = fnv1a( module_name ); + U64 module_base = ldr_entry.DllBase; + U64 module_size = ldr_entry.SizeOfImage; + + ret.push_back( { + module_base, + module_size, + module_name.data, + module_hash + } ); + } + + return ret; + } + + U64 get_module64( FNV1A name, U32* out_size = 0 ) { + std::vector< MODULE_ENTRY > modules = dump_modules64(); + for( auto& it : modules ) { + if( it.hash == name ) { + if( out_size ) + *out_size = (U32)it.size; + + return it.base; + } + } + + return 0; + } + + std::vector< MODULE_ENTRY > dump_modules32() { + std::vector< MODULE_ENTRY > ret; + U64 peb32_addr; + NTSTATUS64 status; + + if( !m_id ) + return ret; + + ULONG out_ret = 0; + status = nt_query_information_process64( + m_base, + ProcessWow64Information, + &peb32_addr, + sizeof( U64 ), + &out_ret + ); + + if( status != STATUS_SUCCESS ) + return ret; + + PEB* peb = (PEB*)VirtualAlloc( + 0, + sizeof( PEB ), + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE + ); + + read( peb32_addr, peb, sizeof( PEB ) ); + + PEB_LDR_DATA ldr; + read( (U32)peb->Ldr, &ldr, sizeof( ldr ) ); + + VirtualFree( peb, sizeof( PEB64 ), MEM_FREE ); + + U64 root = (U32)ldr.InMemoryOrderModuleList.Flink; + for( U32 entry = read<U32>( root ); entry != root; entry = read<U32>( entry ) ) { + LDR_DATA_TABLE_ENTRY data_table{}; + read( entry, &data_table, sizeof( data_table ) ); + + if( !data_table.FullDllName.Buffer ) + continue; + + wchar_t module_buffer[256]{}; + read( + (U64)data_table.FullDllName.Buffer, + module_buffer, 256 * sizeof( wchar_t ) + ); + + STR<256> module_name = u_widebyte_to_ansi<256>( module_buffer ); + FNV1A module_hash = fnv1a( module_name ); + U64 module_base = (U32)data_table.Reserved2[0]; + U64 module_size = *(U32*)((U32)&data_table + 0x20); + + ret.push_back( { + module_base, + module_size, + module_name.data, + module_hash + } ); + } + + return ret; + } + + U32 get_module32( FNV1A name, U32* out_size = 0 ) { + std::vector< MODULE_ENTRY > modules = dump_modules32(); + for( auto& it : modules ) { + if( it.hash == name ) { + if( out_size ) + *out_size = (U32)it.size; + + return (U32)it.base; + } + } + + return 0; + } + + U32 code_match( U32 module_base, const char* sig, U32 start = 0 ) { + U32 sig_length; + U8* sig_bytes = u_parse_signature( sig, &sig_length ); + if( !sig_bytes || sig_length <= 2 ) + return 0; + + U32 ret = code_match( module_base, sig_bytes, sig_length, start ); + + free( sig_bytes ); + return ret; + } + + U32 code_match( U32 module_base, U8* bytes, U32 length, U32 start = 0 ) { + MEMORY_BASIC_INFORMATION64 mbi{0}; + U32 module_size = get_module_size32( module_base ); + if( start < module_base ) + start = module_base; + + U8* module_copy = (U8*)malloc( module_size ); + read( module_base, module_copy, module_size ); + + bool first = true; + + for( U64 off = start - module_base; off < module_size; off += mbi.RegionSize ) { + nt_query_vm64( m_base, module_base + off, MemoryRegionInfo, &mbi, sizeof( mbi ) ); + + if( mbi.State == MEM_FREE ) + continue; + + U32 mbi_address = (U32)mbi.BaseAddress - module_base; + U32 region_start = first? start - (U32)mbi.BaseAddress : 0; + for( U32 i = region_start; i < mbi.RegionSize - length; ++i ) { + if( u_binary_match( module_copy + mbi_address + i, bytes, length ) ) { + free( module_copy ); + return (U32)mbi.BaseAddress + i; + } + + first = false; + } + } + + free( module_copy ); + return 0; + } + + U64 get_id() { return m_id; } + + template < typename t > void write( U64 address, const t& value ) { + nt_write_vm64( m_base, address, (void*)&value, sizeof( t ) ); + } + + void write( U64 address, const void* buffer, U32 size ) { + nt_write_vm64( m_base, address, (void*)buffer, size ); + } + + template < typename t > t read( U64 address ) { + t buffer{}; + read( address, &buffer, sizeof( t ) ); + + return buffer; + } + + void read( U64 address, void* out, U32 size ) { + nt_read_vm64( m_base, address, out, size ); + } + + bool protect( U64 address, U32 size, ULONG protect ) { + } + + U64 allocate( + U64 size, + ULONG protect = PAGE_EXECUTE_READWRITE, + ULONG alloc_type = MEM_COMMIT | MEM_RESERVE + ) { + U64 out{}; + NTSTATUS64 st = nt_allocate_vm64( m_base, &out, 0, &size, alloc_type, protect ); + if( st != STATUS_SUCCESS ) { + return 0; + } + + return out; + } +}; diff --git a/src/resource.h b/src/resource.h new file mode 100644 index 0000000..e43b024 --- /dev/null +++ b/src/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by heavens-gate.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/setting.cpp b/src/setting.cpp new file mode 100644 index 0000000..e46888c --- /dev/null +++ b/src/setting.cpp @@ -0,0 +1,133 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include "setting.h" + +const char* get_path() { + static char out_dir[260]{}; + + if( !out_dir[0] ) { + strcat( out_dir, getenv( "USERPROFILE" ) ); + strcat( out_dir, "/" ); + strcat( out_dir, ".godword" ); + } + + return out_dir; +} + +// credits: gcc +size_t getline(char **lineptr, size_t *n, FILE *stream) { + char *bufptr = NULL; + char *p = bufptr; + size_t size; + int c; + + if (lineptr == NULL) { + return -1; + } + if (stream == NULL) { + return -1; + } + if (n == NULL) { + return -1; + } + bufptr = *lineptr; + size = *n; + + c = fgetc(stream); + if (c == EOF) { + return -1; + } + if (bufptr == NULL) { + bufptr = (char*)malloc(128); + if (bufptr == NULL) { + return -1; + } + size = 128; + } + p = bufptr; + while(c != EOF) { + if ((p - bufptr) > int(size - 1)) { + size = size + 128; + bufptr = (char*)realloc(bufptr, size); + if (bufptr == NULL) { + return -1; + } + } + *p++ = c; + if (c == '\n') { + break; + } + c = fgetc(stream); + } + + *p++ = '\0'; + *lineptr = bufptr; + *n = size; + + return p - bufptr - 1; +} + +void setting_save( const char* name, const void* src, U32 size ) { + char* buffer = (char*)malloc( size * 2 + 1 ); + const U8* data = (const U8*)( src ); + + memset( buffer, 0, size * 2 + 1 ); + + for( U32 i = 0; i < size; ++i ) { + sprintf( &buffer[2 * i], "%02x", data[i] ); + } + + FILE* f = fopen( get_path(), "a" ); + if( !f ) + return free( buffer ); + + fprintf( f, "%s = %s\n", name, buffer ); + fflush( f ); + + free( buffer ); + fclose( f ); +} + +void setting_load( const char* name, const void* dst, U32 size ) { + char* buffer = (char*)malloc( size * 2 + 1 ); + U8* data = (U8*)( dst ); + + memset( buffer, 0, size * 2 + 1 ); + + FILE* f = fopen( get_path(), "r+" ); + if( !f ) + return free( buffer ); + + char read_name[64]{}; + char* line = nullptr; + U32 len = 128; + + /* + * probably not the proper way + * don't wanna fuck with an entire ini parser + */ + while( getline( &line, &len, f ) != -1 ) { + if( line ) { + sscanf( line, "%s = %s", read_name, buffer ); + if( !strcmp( name, read_name ) ) + break; + + free( line ); + line = nullptr; + } + } + + fclose( f ); + + if( !buffer[0] ) + return free( buffer ); + + for( U32 i = 0; i < size; ++i ) { + unsigned temp; + sscanf( &buffer[2 * i], "%02x", &temp ); + data[i] = temp; + } + + free( buffer ); +} diff --git a/src/setting.h b/src/setting.h new file mode 100644 index 0000000..7a1f44d --- /dev/null +++ b/src/setting.h @@ -0,0 +1,80 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include <vector> + +#include "fnv.h" + +extern void setting_save( const char* name, const void* src, U32 size ); +extern void setting_load( const char* name, const void* dst, U32 size ); + +class SETTING_NODE { +public: + virtual void load() {}; + virtual void save() {}; + virtual FNV1A get_hash() { return {}; }; +}; + +template <typename t> +class SETTING; + +class SETTING_HOLDER : SETTING_NODE { +public: + SETTING_HOLDER() = default; + SETTING_HOLDER( SETTING_HOLDER* other ) { other->register_( this ); } + void register_( SETTING_NODE* node ) { nodes.push_back( node ); } + + void save() override { + for( auto& it : nodes ) + it->save(); + } + + void load() override { + for( auto& it : nodes ) + it->load(); + } + + template <typename t> + SETTING<t>* find( FNV1A hash ) { + for( auto it : nodes ) { + if( it->get_hash() == hash ) + return (SETTING<t>*)(it); + } + + return 0; + } + +private: + VECTOR<SETTING_NODE*> nodes; +}; + +template < typename t > +class SETTING : SETTING_NODE { +public: + SETTING( SETTING_HOLDER* owner, const char* name, t _default = t{} ) : + m_owner( owner ), + m_name( name ), + v( _default ), + m_hash( fnv1a( name ) ) + { + owner->register_( this ); + }; + + __forceinline SETTING( const SETTING<t>& other ) : v( other.v ) {} + __forceinline SETTING( const t& other ) : v( other ) {} + + void save() override { setting_save( m_name, &v, sizeof( t ) ); } + void load() override { setting_load( m_name, &v, sizeof( t ) ); } + + FNV1A get_hash() override { return m_hash; } + + operator t&() { return v; } + t* operator&() { return &v; } + + t v; +private: + SETTING_HOLDER* m_owner; + const char* m_name; + FNV1A m_hash; +};
\ No newline at end of file diff --git a/src/source.cpp b/src/source.cpp new file mode 100644 index 0000000..965820f --- /dev/null +++ b/src/source.cpp @@ -0,0 +1,39 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include "csgo/hack.h" +#include "util.h" +#include "conin.h" +#include "menu.h" +#include "csgo/convar.h" + +bool run() { + con_init(); + PROCESS32* p = hack_init(); + + Sleep( 1000 ); + settings.load(); + menu_show_ui( p ); + + for( ;; ) { + if( !hack_run( p ) ) { + nt_close64( p->get_base() ); + u_sleep( 5 * T_SEC ); + break; + } + } + + return false; +} + +I32 __cdecl main() { + con_init(); + + u_set_debug_privilege(); + u_thread_create( &con_hook_handler ); + u_thread_create( &con_handler ); + + for( ; !run(); ); + + return 0; +} diff --git a/src/syscall.h b/src/syscall.h new file mode 100644 index 0000000..001b3af --- /dev/null +++ b/src/syscall.h @@ -0,0 +1,300 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "x86.h" +#include "fnv.h" +#include "asmutil.h" +#include "conout.h" +#include "ntutil.h" +#include "winintern.h" + +struct SYSCALL_ENTRY { + STR<64> name; + FNV1A hash; + U64 base; + I32 idx; +}; + + +inline U32 syscall_wrapper_size( const U8* fn, U16* out_ret_bytes = 0 ) { + for( U32 off = 0; off < 0x18; ++off ) { + // x64 + { + if( *(U16*)(&fn[off]) == 0x050f /* syscall */ + && *(U16*)(&fn[off + 3]) == 0x2ecd /* int 2e */ + ) { + if( out_ret_bytes ) + *out_ret_bytes = 0; + return off + 5; + } + } + + // x86 + { + if( fn[off] == 0xc3 /* retn */ ) { + if( out_ret_bytes ) + *out_ret_bytes = 0; + + return off + 1; + } + if( fn[off] == 0xc2 /* retn imm16 */ ) { + if( out_ret_bytes ) + *out_ret_bytes = *(U16*)( &fn[off + 1] ); + + return off + 3; + } + } + } + + return 0; +} + +inline U8 syscall_is_syscall( const U8* fn, U32 fn_size ) { + // x64 + if( fn[0] == 0x4c && fn[1] == 0x8b && fn[2] == 0xd1 ) { // mov r10, rcx + return ( fn_size > 0 && fn_size < 0x20 ) ? 2 : 0; + } + + // x86 + { + if( fn[0] != x86_encode_mov_imm32( X86Regs_t::eax ) ) + return false; + + for( U32 off = 0; off < fn_size; ++off ) { + if( *(U16*)( &fn[off] ) == 0xd2ff /* call edx */ ) + return 1; + } + } + + return 0; +} + +inline U32 syscall_get_index( const U8* fn, U32 size, U16* out_ret_bytes = 0 ) { + U16 ret_bytes{}; + U8 syscall_type = syscall_is_syscall( fn, size ); + + if( !syscall_type ) + return 0; + + if( out_ret_bytes ) + *out_ret_bytes = ret_bytes; + + // same for x86/x64 + for( U32 off = 0; off < size; ++off ) { + if( *( fn + off ) == x86_encode_mov_imm32( X86Regs_t::eax ) ) + return *(U32*)( fn + off + 1 ); + } + + return 0; +} + +inline VECTOR< SYSCALL_ENTRY > syscall_dump() { + static VECTOR< SYSCALL_ENTRY > ret; + static VECTOR< MODULE_EXPORT > nt_exports; + + // ntdll can't change during runtime + if( !ret.empty() ) + return ret; + + void* nt = nt_get_address(); + if( nt_exports.empty() ) + nt_exports = module_get_exports( nt ); + + for( auto exp : nt_exports ) { + U32 size = syscall_wrapper_size( (U8*)exp.base ); + if( !size ) + continue; + + if( !syscall_is_syscall( (U8*)exp.base, size ) ) + continue; + + U32 idx = syscall_get_index( (U8*)exp.base, size ); + + SYSCALL_ENTRY e; + e.base = (U64)exp.base; + e.name = exp.name; + e.hash = fnv1a( e.name ); + e.idx = idx; + + ret.push_back( e ); + } + + return ret; +} + +inline VECTOR< SYSCALL_ENTRY > syscall_dump64() { + static VECTOR< SYSCALL_ENTRY > ret{}; + static VECTOR< MODULE_EXPORT64 > nt_exports{}; + + if( !ret.empty() ) + return ret; + + U64 nt64 = nt_get_address64(); + if( nt_exports.empty() ) + nt_exports = module_get_exports64( nt64 ); + + U8* syscall_wrapper = (U8*)VirtualAlloc( + 0, + 4096, + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE + ); + + for( auto exp : nt_exports ) { + nt_read_vm64( (HANDLE)-1, exp.base, syscall_wrapper, 0x30 ); + + U32 size = syscall_wrapper_size( syscall_wrapper ); + if( !size ) + continue; + + if( !syscall_is_syscall( syscall_wrapper, size ) ) + continue; + + U32 idx = syscall_get_index( syscall_wrapper, size ); + + SYSCALL_ENTRY e; + e.base = exp.base; + e.name = exp.name.data; + e.hash = fnv1a( exp.name ); + e.idx = idx; + + ret.push_back( e ); + } + + VirtualFree( syscall_wrapper, 4096, MEM_FREE ); + return ret; +} + +inline SYSCALL_ENTRY syscall_find_syscall( FNV1A syscall_hash ) { + static VECTOR< SYSCALL_ENTRY > syscalls = syscall_dump(); + + for( auto& syscall : syscalls ) { + if( syscall.hash == syscall_hash ) + return syscall; + } + + return {}; +} + +inline SYSCALL_ENTRY syscall_find_syscall64( FNV1A syscall_hash ) { + VECTOR< SYSCALL_ENTRY > syscalls = syscall_dump64(); + + for( auto& syscall : syscalls ) { + if( syscall.hash == syscall_hash ) + return syscall; + } + + return {}; +} + + +template < typename ... argt > +NTSTATUS64 __cdecl syscall_execute( U32 idx, argt ... args ) { + REG64 args64[] = { (REG64)(args)... }; + + U64 argc = sizeof...( argt ); + U16 arg = 0; + REG64 _rcx = arg < argc? (REG64)args64[arg++] : 0; + REG64 _rdx = arg < argc? (REG64)args64[arg++] : 0; + REG64 _r8 = arg < argc? (REG64)args64[arg++] : 0; + REG64 _r9 = arg < argc? (REG64)args64[arg++] : 0; + REG64 _rax = {}; + + REG64 argc64 = ( argc - arg ); + REG64 argp = (U64)&args64[arg]; + + REG64 idx64 = (U64)idx; + + U32 _esp; + U16 _fs; + + // backup fs and esp to make restoring simpler + __asm { + mov _fs, fs + mov _esp, esp + + mov eax, 0x2b + mov fs, ax + + // align stack to 16 + and esp, 0xfffffff0 + } + + heavens_gate_enter(); + + // x64 syscall calling convention + // standard fastcall, first 4 args go in registers + __asm { + rex_wr mov edx, _rcx.u32[0] // mov r10, a0 + rex_w mov edx, _rdx.u32[0] // mov edx, a1 + rex_w mov ecx, _rcx.u32[0] + rex_wr mov eax, _r8.u32[0] // mov r8, a2 + rex_wr mov ecx, _r9.u32[0] // mov r9, a3 + } + + __asm { + rex_w mov eax, argc64.u32[0] + test al, 1 + jnz stack_ok + // most syscalls are fine with the stack being aligned to 16 bytes + // but few specific ones crash + // adjust based on no. of args + sub esp, 8 + } + +stack_ok: + + __asm { + push edi + rex_w mov edi, argp.u32[0] // mov rdi, argp + rex_w lea edi, dword ptr[edi + 8 * eax - 8] + } + +arg_loop: + + __asm { + rex_w test eax, eax // test rax, rax + jz loop_end + push dword ptr[edi] + rex_w sub edi, 8 // sub rdi, 8 + rex_w sub eax, 1 // sub rax, 1 + jmp arg_loop + } +loop_end: + + __asm { + rex_w mov eax, idx64.u32[0] + // make stack space for syscall + rex_w sub esp, 0x28 // this fucker cost me a night + + // do the epic + db( 0x0f ) db( 0x05 ) // syscall + } + + //unfuck the stack + __asm { + rex_w mov ecx, argc64.u32[0] + rex_w lea esp, dword ptr[esp + 8 * ecx + 0x28] + + pop edi + + // store 64 bits of rax on the stack + rex_w mov _rax.u32[0], eax + } + + heavens_gate_exit(); + + __asm { + // restore stack segment + mov ax, ds + mov ss, ax + + // restore esp and fs + mov esp, _esp + mov ax, _fs + mov fs, ax + } + + return _rax.u64; +} diff --git a/src/typedef.h b/src/typedef.h new file mode 100644 index 0000000..97b17da --- /dev/null +++ b/src/typedef.h @@ -0,0 +1,28 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#ifdef __cplusplus +#include <vector> +template<typename t> +using VECTOR = std::vector<t>; +#endif + +typedef char I8; +typedef short I16; +typedef int I32; +typedef long long I64; + +typedef unsigned char U8; +typedef unsigned short U16; +typedef unsigned int U32; +typedef unsigned long long U64; + +typedef float F32; +typedef double F64; + +typedef unsigned long PTR; + + +#define assert( x ) if( !x ) con_set_assert( "ASSERTION FAILED: %s() (line: %d)", __func__, __LINE__ ) +#define pause() system( "pause" )
\ No newline at end of file diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..576dcbd --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,42 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include "util.h" +#include "syscall.h" + +ULONG u_thread_create( LPTHREAD_START_ROUTINE routine, void* param ) { + REG64 thread; + ULONG ret_id; + + nt_create_thread64( &thread, 0x1fffff, 0, GetCurrentProcess(), routine, param, 0 ); + ret_id = GetThreadId( (HANDLE)thread.u32[0] ); + + nt_close64( thread ); + + return ret_id; +} + +ULONG u_thread_create( HANDLE proc, LPTHREAD_START_ROUTINE routine, void* param ) { + REG64 thread; + ULONG ret_id; + + nt_create_thread64( &thread, 0x1fffff, 0, proc, routine, param, 0 ); + ret_id = GetThreadId( (HANDLE)thread.u32[0] ); + + nt_close64( thread ); + + return ret_id; +} + +void u_sleep( U64 ns ) { + static bool resolution_set = false; + if( !resolution_set ) { + ULONG timer_resolution; + nt_set_timer_resolution64( 1, true, &timer_resolution ); + resolution_set = true; + } + + LARGE_INTEGER interval; + interval.QuadPart = -1 * ns; + nt_delay_execution64( false, &interval ); +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..c46ff72 --- /dev/null +++ b/src/util.h @@ -0,0 +1,182 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include <chrono> +#include <windows.h> +#include <stdio.h> +#include <thread> + +#include "typedef.h" + +constexpr U64 T_MS = 10000; +constexpr U64 T_SEC = 1000 * T_MS; +constexpr U64 T_MIN = 60 * T_SEC; +constexpr U64 T_HOUR = 60 * T_MIN; +constexpr U64 T_DAY = 24 * T_HOUR; + +extern ULONG u_thread_create( LPTHREAD_START_ROUTINE routine, void* param = 0 ); +extern ULONG u_thread_create( HANDLE proc, LPTHREAD_START_ROUTINE routine, void* param = 0 ); +extern void u_sleep( U64 ns ); + +template < U32 size > +struct STR { + STR() = default; + STR( const char* other ) { strcpy_s< size >( data, other ); } + template < U32 size2 > + STR( STR< size2 >&& other ) { strcpy_s< size >( data, other ); } + + operator char*() { return data; } + + char data[size]{}; +}; + +template < U32 size > +struct WSTR { + WSTR() = default; + WSTR( const wchar_t* other ) { wstrcpy_s< size >( data, other ); } + template < U32 size2 > + WSTR( WSTR< size2 >&& other ) { wstrcpy_s< size >( data, other ); } + + operator wchar_t*() { return data; } + + wchar_t data[size]{}; +}; + +template < typename t > +STR< 32 > u_num_to_string_hex( t num ) { + STR< 32 > ret; + + sprintf( ret.data, "%08X", num ); + return ret; +} + +template < typename t > +STR< 32 > u_num_to_string_dec( t num ) { + STR< 32 > ret; + + sprintf( ret.data, "%lld", (I64)num ); + return ret; +} + +template < U32 size = 128 > +STR< size > u_widebyte_to_ansi( const wchar_t* str ) { + STR< size > ret; + + for( U32 i = 0; !!str[i]; ++i ) { + ret.data[i] = str[i] & 0xff; + } + + return ret; +} + +template < U32 size = 128 > +WSTR< size > u_ansi_to_widebyte( const char* str ) { + WSTR< size > ret; + + for( U32 i = 0; !!str[i]; ++i ) { + ret.data[i] = str[i]; + } + + return ret; +} + +inline U8 u_set_debug_privilege() { + HANDLE token; + TOKEN_PRIVILEGES tkp{}; + + if( !OpenProcessToken( + GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, + &token + ) ) { + return 0; + } + + if( !LookupPrivilegeValueA( 0, SE_DEBUG_NAME, &tkp.Privileges->Luid ) ) { + CloseHandle( token ); + return 0; + } + + tkp.PrivilegeCount = 1; + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if( !AdjustTokenPrivileges( token, false, &tkp, 0, nullptr, 0 ) ) { + CloseHandle( token ); + return 0; + } + + CloseHandle( token ); + + return 1; +} + +inline U8 u_binary_match( U8* code, U8* pattern, U32 size ) { + for( U32 i = 0; i < size; ++i ) { + if( pattern[i] && (code[i] ^ pattern[i]) != 0 ) + return 0; + } + + return 1; +} + +inline U8* u_parse_signature( const char* sig, U32* out_len ) { + U32 i, byte, len = strlen( sig ); + U8* sig_bytes = (U8*)malloc( len ); + + for( i = 0, byte = 0; i < len; ++byte ) { + if( sig[i] == ' ' ) + return 0; + + if( sig[i] == '?' ) { + sig_bytes[byte] = 0; + for( U32 i2 = i; i2 < len; ++i2 ) { + if( sig[i2 + 1] == ' ' ) { + i = i2 + 2; + break; + } + } + + continue; + } + + unsigned long temp; + sscanf( &sig[i], "%02x", &temp ); + + sig_bytes[byte] = (U8)( temp & 0xff ); + i += 3; + } + + if( out_len ) + *out_len = byte; + return sig_bytes; +} + +template <typename t> +inline t u_vector_search( VECTOR<t> v, bool( *func)( t* t1 ) ) { + for( auto& it : v ) { + if( func( &it ) ) + return it; + } + + return {}; +} + +inline U64 u_tick() { + static LARGE_INTEGER freq; + if( !freq.QuadPart ) + QueryPerformanceFrequency( &freq ); + + LARGE_INTEGER ticks; + QueryPerformanceCounter( &ticks ); + + constexpr U64 wanted_precision = 10000000; + if( wanted_precision == freq.QuadPart ) + return ticks.QuadPart; + return (U64)(ticks.QuadPart / ((double)freq.QuadPart / wanted_precision) ); +} + +inline F64 u_time() { + constexpr F64 NSEC_TO_SEC = 1.f / T_SEC; + return u_tick() * NSEC_TO_SEC; +}
\ No newline at end of file diff --git a/src/vec3.h b/src/vec3.h new file mode 100644 index 0000000..e91a73d --- /dev/null +++ b/src/vec3.h @@ -0,0 +1,120 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include "typedef.h" + +#define M_PI 3.141592653589793238f + +struct VEC3 { + F32 x, y, z; + + VEC3() { x = y = z = 0.0f; } + VEC3( F32 X, F32 Y, F32 Z ) { x = X; y = Y; z = Z; } + VEC3( const F32* v ) { x = v[0]; y = v[1]; z = v[2]; } + VEC3( const VEC3& v ) { x = v.x; y = v.y; z = v.z; } + + VEC3& operator=( const VEC3& v ) { x = v.x; y = v.y; z = v.z; return *this; } + F32& operator[]( I32 i ) { return ( (F32*)this )[i]; } + F32 operator[]( I32 i ) const { return ( (F32*)this )[i]; } + + VEC3& operator+=( const VEC3& v ) { x += v.x; y += v.y; z += v.z; return *this; } + VEC3& operator-=( const VEC3& v ) { x -= v.x; y -= v.y; z -= v.z; return *this; } + VEC3& operator*=( const VEC3& v ) { x *= v.x; y *= v.y; z *= v.z; return *this; } + VEC3& operator/=( const VEC3& v ) { x /= v.x; y /= v.y; z /= v.z; return *this; } + + VEC3 operator+( const VEC3& v ) const { return VEC3( x + v.x, y + v.y, z + v.z ); } + VEC3 operator-( const VEC3& v ) const { return VEC3( x - v.x, y - v.y, z - v.z ); } + VEC3 operator*( const VEC3& v ) const { return VEC3( x * v.x, y * v.y, z * v.z ); } + VEC3 operator/( const VEC3& v ) const { return VEC3( x / v.x, y / v.y, z / v.z ); } + + operator bool() const { return !is_zero(); } + + F32 length() const { + return sqrtf( x * x + y * y + z * z ); + } + + F32 lengthsqr() const { + return ( x * x + y * y + z * z ); + } + + F32 length2d() const { + return sqrtf( x * x + y * y ); + } + + F32 length2dsqr() const { + return ( x * x + y * y ); + } + + F32 dist_to( const VEC3& v ) const { + return ( *this - v ).length(); + } + + F32 dist_to_sqr( const VEC3& v ) const { + return ( *this - v ).lengthsqr(); + } + + F32 dot( const VEC3& v ) const { + return ( x * v.x + y * v.y + z * v.z ); + } + + F32 angle_between( const VEC3& to ) { + const F32 from_length = length( ); + const F32 to_length = to.length( ); + + if( from_length && to_length ) { + return acosf( dot( to ) / from_length * to_length ); + } + + return 0.f; + } + + VEC3 cross( const VEC3& v ) const { + return VEC3( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); + } + + bool is_zero() const { + return ( x > -FLT_EPSILON && x < FLT_EPSILON && + y > -FLT_EPSILON && y < FLT_EPSILON && + z > -FLT_EPSILON && z < FLT_EPSILON ); + } + + inline void normalize_in_place() { + F32 iradius = 1.f / ( length() + FLT_EPSILON ); //FLT_EPSILON + + x *= iradius; + y *= iradius; + z *= iradius; + } + + VEC3 abs() const { + return VEC3{ ::abs( x ), ::abs( y ), ::abs( z ) }; + } + + VEC3 clamp() { + for( U32 axis{}; axis < 2; axis++ ) { + auto &cur_axis = operator[]( axis ); + if( !isfinite( cur_axis ) ) + cur_axis = 0.f; + else + cur_axis = remainderf( cur_axis, 360.f ); + } + + x = x > 89.f ? 89.f : x < -89.f ? -89.f : x; + y = y > 180.f ? 180.f : y < -180.f ? -180.f : y; + z = 0.f; + + return *this; + } + +}; + +_forceinline VEC3 vector_angles( const VEC3& start, const VEC3& end ) { + VEC3 delta = end - start; + + float magnitude = sqrtf( ( delta.x * delta.x ) + ( delta.y * delta.y ) ); + float pitch = atan2f( -delta.z, magnitude ) * 57.295779513082f; + float yaw = atan2f( delta.y, delta.x ) * 57.295779513082f; + + VEC3 angle( pitch, yaw, 0.0f ); + return angle.clamp( ); +}
\ No newline at end of file diff --git a/src/winintern.h b/src/winintern.h new file mode 100644 index 0000000..458a832 --- /dev/null +++ b/src/winintern.h @@ -0,0 +1,367 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once + +#include <windows.h> + +#ifndef STATUS_SUCCESS +# define STATUS_SUCCESS 0 +#endif + +template <class T> +struct _LIST_ENTRY_T +{ + T Flink; + T Blink; +}; + +template <class T> +struct _UNICODE_STRING_T +{ + union + { + struct + { + WORD Length; + WORD MaximumLength; + }; + T dummy; + }; + T Buffer; +}; + +template <class T> +struct _NT_TIB_T +{ + T ExceptionList; + T StackBase; + T StackLimit; + T SubSystemTib; + T FiberData; + T ArbitraryUserPointer; + T Self; +}; + +template <class T> +struct _CLIENT_ID_T +{ + T UniqueProcess; + T UniqueThread; +}; + +struct OBJECT_HANDLE_FLAG_INFORMATION { + BOOLEAN inherit; + BOOLEAN protect; +}; + +template <class T> +struct _TEB_T_ +{ + _NT_TIB_T<T> NtTib; + T EnvironmentPointer; + _CLIENT_ID_T<T> ClientId; + T ActiveRpcHandle; + T ThreadLocalStoragePointer; + T ProcessEnvironmentBlock; + DWORD LastErrorValue; + DWORD CountOfOwnedCriticalSections; + T CsrClientThread; + T Win32ThreadInfo; + DWORD User32Reserved[26]; + //rest of the structure is not defined for now, as it is not needed +}; + +template <class T> +struct _LDR_DATA_TABLE_ENTRY_T +{ + _LIST_ENTRY_T<T> InLoadOrderLinks; + _LIST_ENTRY_T<T> InMemoryOrderLinks; + _LIST_ENTRY_T<T> InInitializationOrderLinks; + T DllBase; + T EntryPoint; + union + { + DWORD SizeOfImage; + T dummy01; + }; + _UNICODE_STRING_T<T> FullDllName; + _UNICODE_STRING_T<T> BaseDllName; + DWORD Flags; + WORD LoadCount; + WORD TlsIndex; + union + { + _LIST_ENTRY_T<T> HashLinks; + struct + { + T SectionPointer; + T CheckSum; + }; + }; + union + { + T LoadedImports; + DWORD TimeDateStamp; + }; + T EntryPointActivationContext; + T PatchInformation; + _LIST_ENTRY_T<T> ForwarderLinks; + _LIST_ENTRY_T<T> ServiceTagLinks; + _LIST_ENTRY_T<T> StaticLinks; + T ContextInformation; + T OriginalBase; + _LARGE_INTEGER LoadTime; +}; + +template <class T> +struct _PEB_LDR_DATA_T +{ + DWORD Length; + DWORD Initialized; + T SsHandle; + _LIST_ENTRY_T<T> InLoadOrderModuleList; + _LIST_ENTRY_T<T> InMemoryOrderModuleList; + _LIST_ENTRY_T<T> InInitializationOrderModuleList; + T EntryInProgress; + DWORD ShutdownInProgress; + T ShutdownThreadId; + +}; + +struct PROCESS_BASIC_INFORMATION64 { + LONG ExitStatus; + U64 PebBaseAddress; + U64 AfiinityMask; + LONG BasePriority; + U64 UniqueProcessId; + U64 InheritedFromUniqueProcessId; +}; + +template <class T, class NGF, int A> +struct _PEB_T +{ + UCHAR InheritedAddressSpace; + UCHAR ReadImageFileExecOptions; + UCHAR BeingDebugged; + UCHAR BitField; + ULONG ImageUsesLargePages: 1; + ULONG IsProtectedProcess: 1; + ULONG IsLegacyProcess: 1; + ULONG IsImageDynamicallyRelocated: 1; + ULONG SpareBits: 4; + T Mutant; + T ImageBaseAddress; + T Ldr; + T ProcessParameters; + T SubSystemData; + T ProcessHeap; + T FastPebLock; + T AtlThunkSListPtr; + T IFEOKey; + T CrossProcessFlags; + T UserSharedInfoPtr; + DWORD SystemReserved; + DWORD AtlThunkSListPtr32; + T ApiSetMap; + T TlsExpansionCounter; + T TlsBitmap; + DWORD TlsBitmapBits[2]; + T ReadOnlySharedMemoryBase; + T HotpatchInformation; + T ReadOnlyStaticServerData; + T AnsiCodePageData; + T OemCodePageData; + T UnicodeCaseTableData; + DWORD NumberOfProcessors; + union + { + DWORD NtGlobalFlag; + NGF dummy02; + }; + LARGE_INTEGER CriticalSectionTimeout; + T HeapSegmentReserve; + T HeapSegmentCommit; + T HeapDeCommitTotalFreeThreshold; + T HeapDeCommitFreeBlockThreshold; + DWORD NumberOfHeaps; + DWORD MaximumNumberOfHeaps; + T ProcessHeaps; + T GdiSharedHandleTable; + T ProcessStarterHelper; + T GdiDCAttributeList; + T LoaderLock; + DWORD OSMajorVersion; + DWORD OSMinorVersion; + WORD OSBuildNumber; + WORD OSCSDVersion; + DWORD OSPlatformId; + DWORD ImageSubsystem; + DWORD ImageSubsystemMajorVersion; + T ImageSubsystemMinorVersion; + T ActiveProcessAffinityMask; + T GdiHandleBuffer[A]; + T PostProcessInitRoutine; + T TlsExpansionBitmap; + DWORD TlsExpansionBitmapBits[32]; + T SessionId; + ULARGE_INTEGER AppCompatFlags; + ULARGE_INTEGER AppCompatFlagsUser; + T pShimData; + T AppCompatInfo; + _UNICODE_STRING_T<T> CSDVersion; + T ActivationContextData; + T ProcessAssemblyStorageMap; + T SystemDefaultActivationContextData; + T SystemAssemblyStorageMap; + T MinimumStackCommit; + T FlsCallback; + _LIST_ENTRY_T<T> FlsListHead; + T FlsBitmap; + DWORD FlsBitmapBits[4]; + T FlsHighIndex; + T WerRegistrationData; + T WerShipAssertPtr; + T pContextData; + T pImageHeaderHash; + T TracingFlags; +}; + +typedef _LDR_DATA_TABLE_ENTRY_T<DWORD> LDR_DATA_TABLE_ENTRY32; +typedef _LDR_DATA_TABLE_ENTRY_T<DWORD64> LDR_DATA_TABLE_ENTRY64; + +typedef _TEB_T_<DWORD> TEB32; +typedef _TEB_T_<DWORD64> TEB64; + +typedef _PEB_LDR_DATA_T<DWORD> PEB_LDR_DATA32; +typedef _PEB_LDR_DATA_T<DWORD64> PEB_LDR_DATA64; + +typedef _PEB_T<DWORD, DWORD64, 34> PEB32; +typedef _PEB_T<DWORD64, DWORD, 30> PEB64; + +struct _XSAVE_FORMAT64 +{ + WORD ControlWord; + WORD StatusWord; + BYTE TagWord; + BYTE Reserved1; + WORD ErrorOpcode; + DWORD ErrorOffset; + WORD ErrorSelector; + WORD Reserved2; + DWORD DataOffset; + WORD DataSelector; + WORD Reserved3; + DWORD MxCsr; + DWORD MxCsr_Mask; + _M128A FloatRegisters[8]; + _M128A XmmRegisters[16]; + BYTE Reserved4[96]; +}; + +struct _CONTEXT64 +{ + DWORD64 P1Home; + DWORD64 P2Home; + DWORD64 P3Home; + DWORD64 P4Home; + DWORD64 P5Home; + DWORD64 P6Home; + DWORD ContextFlags; + DWORD MxCsr; + WORD SegCs; + WORD SegDs; + WORD SegEs; + WORD SegFs; + WORD SegGs; + WORD SegSs; + DWORD EFlags; + DWORD64 Dr0; + DWORD64 Dr1; + DWORD64 Dr2; + DWORD64 Dr3; + DWORD64 Dr6; + DWORD64 Dr7; + DWORD64 Rax; + DWORD64 Rcx; + DWORD64 Rdx; + DWORD64 Rbx; + DWORD64 Rsp; + DWORD64 Rbp; + DWORD64 Rsi; + DWORD64 Rdi; + DWORD64 R8; + DWORD64 R9; + DWORD64 R10; + DWORD64 R11; + DWORD64 R12; + DWORD64 R13; + DWORD64 R14; + DWORD64 R15; + DWORD64 Rip; + _XSAVE_FORMAT64 FltSave; + _M128A Header[2]; + _M128A Legacy[8]; + _M128A Xmm0; + _M128A Xmm1; + _M128A Xmm2; + _M128A Xmm3; + _M128A Xmm4; + _M128A Xmm5; + _M128A Xmm6; + _M128A Xmm7; + _M128A Xmm8; + _M128A Xmm9; + _M128A Xmm10; + _M128A Xmm11; + _M128A Xmm12; + _M128A Xmm13; + _M128A Xmm14; + _M128A Xmm15; + _M128A VectorRegister[26]; + DWORD64 VectorControl; + DWORD64 DebugControl; + DWORD64 LastBranchToRip; + DWORD64 LastBranchFromRip; + DWORD64 LastExceptionToRip; + DWORD64 LastExceptionFromRip; +}; + +struct _SYSTEM_PROCESS_INFORMATION64 { + ULONG NextEntryOffset; + ULONG NumberOfThreads; + BYTE Reserved1[48]; + _UNICODE_STRING_T<U64> ImageName; + KPRIORITY BasePriority; + U64 UniqueProcessId; + U64 Reserved2; + ULONG HandleCount; + ULONG SessionId; + U64 Reserved3; + U64 PeakVirtualSize; + U64 VirtualSize; + ULONG Reserved4; + U64 PeakWorkingSetSize; + U64 WorkingSetSize; + U64 Reserved5; + U64 QuotaPagedPoolUsage; + U64 Reserved6; + U64 QuotaNonPagedPoolUsage; + U64 PagefileUsage; + U64 PeakPagefileUsage; + U64 PrivatePageCount; + LARGE_INTEGER Reserved7[6]; +}; + +template< class T > +struct _OBJECT_ATTRIBUTES_T { + ULONG Length; + T RootDirectory; + T ObjectName; + ULONG Attributes; + T SecurityDescriptor; + T SecurityQualityOfService; +}; + +using _OBJECT_ATTRIBUTES64 = _OBJECT_ATTRIBUTES_T<DWORD64>; +using NTSTATUS64 = DWORD64;
\ No newline at end of file diff --git a/src/x86.h b/src/x86.h new file mode 100644 index 0000000..484e5c2 --- /dev/null +++ b/src/x86.h @@ -0,0 +1,58 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "typedef.h" + +enum X86Regs_t : U8 { + eax = 0, + ecx, + edx, + ebx, + esp, + ebp, + esi, + edi +}; + +enum X64Regs_t : U8 { + rax = 0, + rcx, + rdx, + rbx, + rsp, + rbp, + rsi, + rdi, + r8, + r9, + r10, + r11, + r12, + r13, + r14, + r15 +}; + +union REG64 { + REG64() = default; + REG64( U64 x ) : u64( x ) {} + REG64( U32 x ) { u64 = x; } + + REG64( I64 x ) : u64( *(U64*)( &x ) ) {} + REG64( I32 x ) { u64 = *(U32*)( &x ); } + + U32 u32[2]; + U64 u64; +}; + +constexpr U32 x86_encode_mov_imm32( U32 reg ) { return ( 0xb8 + reg ); } +constexpr U32 x86_encode_push_reg( U32 reg ) { return 0x50 | ( reg & 7 ); } +constexpr U32 x86_encoded_pop_reg( U32 reg ) { return 0x58 | ( reg & 7 ); } + +enum X86Instructions_t : U8 { + RET_NEAR = 0xc3, + RET_FAR = 0xcb, + RET_NEAR_IMM16 = 0xc2, + RET_FAR_IMM16 = 0xca, +};
\ No newline at end of file |
