summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asmutil.h23
-rw-r--r--src/conin.cpp242
-rw-r--r--src/conin.h304
-rw-r--r--src/conout.cpp333
-rw-r--r--src/conout.h150
-rw-r--r--src/csgo/console.cpp100
-rw-r--r--src/csgo/convar.h67
-rw-r--r--src/csgo/csgo.h22
-rw-r--r--src/csgo/csgoentity.cpp6
-rw-r--r--src/csgo/csgoentity.h81
-rw-r--r--src/csgo/csgoentity.h.bak73
-rw-r--r--src/csgo/csgoplayer.h36
-rw-r--r--src/csgo/hack.cpp521
-rw-r--r--src/csgo/hack.h138
-rw-r--r--src/csgo/hack_aim.cpp110
-rw-r--r--src/csgo/interface.h110
-rw-r--r--src/csgo/materialsystem.h61
-rw-r--r--src/csgo/netvar.h142
-rw-r--r--src/csgo/sdk.h528
-rw-r--r--src/csgo/trace.h40
-rw-r--r--src/disasm.h111
-rw-r--r--src/fnv.h39
-rw-r--r--src/heavens-gate.apsbin0 -> 116344 bytes
-rw-r--r--src/heavens-gate.filters27
-rw-r--r--src/heavens-gate.user4
-rw-r--r--src/heavens-gate.vcxproj261
-rw-r--r--src/heavens-gate.vcxproj.filters100
-rw-r--r--src/heavens-gate.vcxproj.user12
-rw-r--r--src/inet.h76
-rw-r--r--src/mathutil.h21
-rw-r--r--src/menu.cpp383
-rw-r--r--src/menu.h86
-rw-r--r--src/mouse.h32
-rw-r--r--src/ntutil.cpp304
-rw-r--r--src/ntutil.h251
-rw-r--r--src/process.h358
-rw-r--r--src/resource.h16
-rw-r--r--src/setting.cpp133
-rw-r--r--src/setting.h80
-rw-r--r--src/source.cpp39
-rw-r--r--src/syscall.h300
-rw-r--r--src/typedef.h28
-rw-r--r--src/util.cpp42
-rw-r--r--src/util.h182
-rw-r--r--src/vec3.h120
-rw-r--r--src/winintern.h367
-rw-r--r--src/x86.h58
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 = &it;
+ 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
new file mode 100644
index 0000000..a37fb5f
--- /dev/null
+++ b/src/heavens-gate.aps
Binary files differ
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