diff options
Diffstat (limited to 'src/csgo')
| -rw-r--r-- | src/csgo/console.cpp | 100 | ||||
| -rw-r--r-- | src/csgo/convar.h | 67 | ||||
| -rw-r--r-- | src/csgo/csgo.h | 22 | ||||
| -rw-r--r-- | src/csgo/csgoentity.cpp | 6 | ||||
| -rw-r--r-- | src/csgo/csgoentity.h | 81 | ||||
| -rw-r--r-- | src/csgo/csgoentity.h.bak | 73 | ||||
| -rw-r--r-- | src/csgo/csgoplayer.h | 36 | ||||
| -rw-r--r-- | src/csgo/hack.cpp | 521 | ||||
| -rw-r--r-- | src/csgo/hack.h | 138 | ||||
| -rw-r--r-- | src/csgo/hack_aim.cpp | 110 | ||||
| -rw-r--r-- | src/csgo/interface.h | 110 | ||||
| -rw-r--r-- | src/csgo/materialsystem.h | 61 | ||||
| -rw-r--r-- | src/csgo/netvar.h | 142 | ||||
| -rw-r--r-- | src/csgo/sdk.h | 528 | ||||
| -rw-r--r-- | src/csgo/trace.h | 40 |
15 files changed, 2035 insertions, 0 deletions
diff --git a/src/csgo/console.cpp b/src/csgo/console.cpp new file mode 100644 index 0000000..0b16ceb --- /dev/null +++ b/src/csgo/console.cpp @@ -0,0 +1,100 @@ +#include "hack.h" +#include "../menu.h" + + +struct CMD_TOGGLE { + const char* name; + const char* desc; + SETTING<bool>& var; +}; + + +void hack_toggle( CMD_TOGGLE cmd ) { + con_clear(); + cmd.var = !cmd.var; + + menu_pages[menu_page].page_fn(); + show_paging( menu_page ); +} + +#define gcon_match( name ) !strncmp( buf + 1, name, strlen( name ) ) + +#define gcon_var( string ) { 0, strlen( string ) + 1, ( void* )string } + +void __cdecl game_hack_toggle( VECTOR<STR<64>> args ) { + static SETTING<bool>& bhop_active = *settings.find<bool>( "bhop_active"fnv ); + static SETTING<bool>& chams_active = *settings.find<bool>( "chams_active"fnv ); + static SETTING<bool>& glow_active = *settings.find<bool>( "glow_active"fnv ); + static SETTING<bool>& nightmode_active = *settings.find<bool>( "nightmode_active"fnv ); + static SETTING<bool>& noflash_active = *settings.find<bool>( "noflash_active"fnv ); + static SETTING<bool>& clantag_active = *settings.find<bool>( "clantag_active"fnv ); + + static SETTING<bool>& aim_active = *settings.find<bool>( "aim_active"fnv ); + static SETTING<bool>& crosshair_active = *settings.find<bool>( "crosshair_active"fnv ); + static SETTING<bool>& rcs_active = *settings.find<bool>( "rcs_active"fnv ); + static SETTING<bool>& triggerteam_active = *settings.find<bool>( "triggerteam_active"fnv ); + + char buf[512]{}; + + for( auto& it : args ) + sprintf( buf, "%s\n%s", buf, it.data ); + + CMD_TOGGLE cmd_toggle[10] = { + { "hg_bhop" , "toggles aim assist", bhop_active }, + { "hg_chams" , "toggles bhop", chams_active }, + { "hg_glow" , "toggles chams", glow_active }, + { "hg_night" , "toggles clantag", nightmode_active }, + { "hg_flash" , "toggles no flash", noflash_active }, + { "hg_clan" , "toggles glow", clantag_active }, + { "hg_aim" , "toggles nightmode", aim_active }, + { "hg_xhair" , "toggles standalone rcs", crosshair_active }, + { "hg_rcs" , "toggles team triggerbot", rcs_active }, + { "hg_triggerteam", "toggles recoil crosshair", triggerteam_active } + }; + + for( const auto& cmd : cmd_toggle ) { + if( gcon_match( cmd.name ) ) { + hack_toggle( cmd ); + return; + } + } + + if( gcon_match( "hg_help" ) ) { + const HWND hconsole = FindWindowA( "Valve001", 0 ); + if( !hconsole ) + return; + + u_sleep( 1 * T_SEC / 5 ); + for( auto& cmd : cmd_toggle ) { + sprintf( buf, "echo \"%s : %s\"", cmd.name, cmd.desc ); + + COPYDATASTRUCT hconsole_out; + hconsole_out.cbData = strlen( buf ) + 1; + hconsole_out.dwData = 0; + hconsole_out.lpData = ( void* )buf; + SendMessageA( hconsole, + WM_COPYDATA, 0, + ( LPARAM )&hconsole_out + ); + + u_sleep( 1 * T_SEC / 20 ); + } + + return; + } + + const HWND hconsole = FindWindowA( "Valve001", 0 ); + if( !hconsole ) + return; + + COPYDATASTRUCT hconsole_out; + hconsole_out.cbData = strlen( "echo \"invalid cmd, use \'hg_help\' for cmd list\"" ) + 1; + hconsole_out.dwData = 0; + hconsole_out.lpData = ( void* )"echo \"invalid cmd, use \'hg_help\' for cmd list\""; + SendMessageA( hconsole, + WM_COPYDATA, 0, + ( LPARAM )&hconsole_out + ); + + return; +}
\ No newline at end of file diff --git a/src/csgo/convar.h b/src/csgo/convar.h new file mode 100644 index 0000000..bdcb510 --- /dev/null +++ b/src/csgo/convar.h @@ -0,0 +1,67 @@ +#include "csgo.h" + +inline U32 convar_find( CSGO* p, const char* name ) { + VECTOR<MODULE_ENTRY> modules = p->dump_modules32(); + + for( auto& it : modules ) { + U32 string_ptr = 0; + do { + string_ptr = p->code_match( (U32)it.base, (U8*)name, strlen( name ), string_ptr + 1 ); + if( !string_ptr ) + break; + + U8* ptr_bytes = (U8*)( &string_ptr ); + U8 pattern[] = { + 0x68, 0x00, 0x00, 0x00, 0x00, // cvar creation flags + 0x68, 0x00, 0x00, 0x00, 0x00, // defaultValue + 0x68, + *ptr_bytes, + *(ptr_bytes + 1), + *(ptr_bytes + 2), + *(ptr_bytes + 3), + 0xe8 // call create_cvar + }; + + U32 string_ref = p->code_match( (U32)it.base, pattern, sizeof( pattern ) ); + if( string_ref ) + return p->read<U32>( string_ref - 11 ); + + // try with mov instead of call + pattern[sizeof( pattern ) - 1] = 0xb9; // mov ecx, this + string_ref = p->code_match( (U32)it.base, pattern, sizeof( pattern ) ); + + if( !string_ref ) + continue; + + U32 convar = p->read<U32>( string_ref + sizeof( pattern ) ); + return convar; + } while( true ); + } + + return 0; +} + +struct CVValue_t { + char* m_pszString; + int m_StringLength; + float m_fValue; + int m_nValue; +}; + +template <typename T> +inline void convar_set( CSGO* p, U32 convar, T _new ) { + U32 val = *(U32*)&_new; + val ^= convar; + + CVValue_t value = p->read<CVValue_t>( convar + 0x24 ); + value.m_nValue = val; + *(U32*)(&value.m_fValue) = val; + + p->write<CVValue_t>( convar + 0x24, value ); +} + +template <typename T> +inline T convar_get( CSGO* p, U32 convar ) { + U32 val = p->read<U32>( convar + 0x2c ) ^ convar; + return *(T*)( &val ); +}
\ No newline at end of file diff --git a/src/csgo/csgo.h b/src/csgo/csgo.h new file mode 100644 index 0000000..f23be80 --- /dev/null +++ b/src/csgo/csgo.h @@ -0,0 +1,22 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "../process.h" +#include "../conout.h" +#include "interface.h" + + +class CSGO : public PROCESS32 { +public: + CSGO() : PROCESS32( "csgo.exe" ) {}; + + void dump_interfaces() { + interfaces = srceng_get_interfaces( this ); + } + + U32 client; + U32 engine; + + VECTOR<IFACE_ENTRY> interfaces; +};
\ No newline at end of file diff --git a/src/csgo/csgoentity.cpp b/src/csgo/csgoentity.cpp new file mode 100644 index 0000000..4c91a98 --- /dev/null +++ b/src/csgo/csgoentity.cpp @@ -0,0 +1,6 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include "csgoentity.h" + +CSGO* CSGOENTITY::csgop;
\ No newline at end of file diff --git a/src/csgo/csgoentity.h b/src/csgo/csgoentity.h new file mode 100644 index 0000000..5d4a4cf --- /dev/null +++ b/src/csgo/csgoentity.h @@ -0,0 +1,81 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "../util.h" + +#include "sdk.h" +#include "netvar.h" + +#define OFFSET( name, prop, table, type, off ) \ + type name() { \ + static U32 offset = netvar_find( csgop, table, prop ) + off; \ + return get<type>( offset ); } \ + void name( type v ) { \ + static U32 offset = netvar_find( csgop, table, #name ) + off; \ + return set<type>( offset, v ); } \ + +#define NETVAR( name, table, type ) \ + type name() { \ + static U32 offset = netvar_find( csgop, table, #name ); \ + return get<type>( offset ); } \ + void name( type v ) { \ + static U32 offset = netvar_find( csgop, table, #name ); \ + return set<type>( offset, v ); } \ + + +class CSGOENTITY { +public: + static CSGO* csgop; + +public: + CSGOENTITY( U32 ptr ) : base( ptr ) {}; + CSGOENTITY( const CSGOENTITY& other ) : base( other.base ) {} + + inline operator U32&() { return base; } + + template <typename t> + t get( U32 offset ) { return csgop->read<t>( base + offset ); } + + template <typename t> + void set( U32 offset, t v ) { return csgop->write<t>( base + offset, v ); } + +public: + CSGO_CLIENT_CLASS get_clientclass() { + U32 networkable = get<U32>( 0x8 ); + U32 create_fn = csgop->read<U32>( networkable + 0x8 ); + U32 clientclass = csgop->read<U32>( create_fn + 0x1 ); + + return csgop->read<CSGO_CLIENT_CLASS>( clientclass ); + } + + NETVAR( m_fFlags, "DT_CSPlayer", I32 ); + OFFSET( m_MoveType , "m_nRenderMode", "DT_CSPlayer" , I32, 1 ); + OFFSET( m_iCrosshairID, "m_bHasDefuser", "DT_CSPlayer" , I32, 92 ); + OFFSET( m_dwBoneMatrix, "m_nForceBone", "DT_BaseAnimating", U32, 28 ); + + bool m_bDormant() { + return get<bool>( 0xed ); + } + + static CSGOENTITY from_list( I32 idx ) { + static U32 entlist = csgop->read<U32>( + csgop->code_match( + csgop->client, "BB ? ? ? ? 83 FF 01 0F 8C ? ? ? ? 3B F8" + ) + 1 + ); + + return csgop->read<U32>( + entlist + idx * 0x10 + ); + } + + bool is_weapon() { + CSGO_CLIENT_CLASS cl = get_clientclass(); + return ( cl.index >= CWeaponAug && cl.index <= CWeaponXM1014 ) + || cl.index == CAK47 || cl.index == CDEagle; + } + +public: + U32 base; +};
\ No newline at end of file diff --git a/src/csgo/csgoentity.h.bak b/src/csgo/csgoentity.h.bak new file mode 100644 index 0000000..0532673 --- /dev/null +++ b/src/csgo/csgoentity.h.bak @@ -0,0 +1,73 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "../util.h" + +#include "sdk.h" +#include "netvar.h" + +#define OFFSET( name, prop, table, type, off ) \ + type name() { \ + static U32 offset = netvar_find( csgop, table, prop ) + off; \ + return get<type>( offset ); } \ + void name( type v ) { \ + static U32 offset = netvar_find( csgop, table, #name ) + off; \ + return set<type>( offset, v ); } \ + +#define NETVAR( name, table, type ) \ + type name() { \ + static U32 offset = netvar_find( csgop, table, #name ); \ + return get<type>( offset ); } \ + void name( type v ) { \ + static U32 offset = netvar_find( csgop, table, #name ); \ + return set<type>( offset, v ); } \ + + +class CSGOENTITY { +public: + static CSGO* csgop; + +public: + CSGOENTITY( U32 ptr ) : base( ptr ) {}; + CSGOENTITY( const CSGOENTITY& other ) : base( other.base ) {} + + inline operator U32&() { return base; } + + template <typename t> + t get( U32 offset ) { return csgop->read<t>( base + offset ); } + + template <typename t> + void set( U32 offset, t v ) { return csgop->write<t>( base + offset, v ); } + +public: + CSGO_CLIENT_CLASS get_clientclass() { + U32 networkable = get<U32>( 0x8 ); + U32 create_fn = csgop->read<U32>( networkable + 0x8 ); + U32 clientclass = csgop->read<U32>( create_fn + 0x1 ); + + return csgop->read<CSGO_CLIENT_CLASS>( clientclass ); + } + + NETVAR( m_fFlags, "DT_CSPlayer", I32 ); + OFFSET( m_iCrosshairID, "m_bHasDefuser", "DT_CSPlayer", I32, 92 ); + OFFSET( m_dwBoneMatrix, "m_nForceBone", "DT_BaseAnimating", U32, 28 ); + + static CSGOENTITY from_list( I32 idx ) { + const U64 entlist = csgop->code_match( + csgop->client, "BB ? ? ? ? 83 FF 01 0F 8C ? ? ? ? 3B F8" + ); + + return csgop->read<U32>( + csgop->client + entlist + idx * 0x10 + ); + } + + bool is_weapon() { + CSGO_CLIENT_CLASS cl = get_clientclass(); + return cl.index >= CWeaponAug && cl.index <= CWeaponXM1014; + } + +public: + U32 base; +};
\ No newline at end of file diff --git a/src/csgo/csgoplayer.h b/src/csgo/csgoplayer.h new file mode 100644 index 0000000..ecf84c3 --- /dev/null +++ b/src/csgo/csgoplayer.h @@ -0,0 +1,36 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "csgoentity.h" + +class CSGOPLAYER : public CSGOENTITY { +public: + CSGOPLAYER( U32 base ) : CSGOENTITY( base ) {} + CSGOPLAYER( const CSGOENTITY& other ) : CSGOENTITY( other.base ) {} + CSGOPLAYER() = default; + + // this doesnt need to be a part of the aimbot. + VEC3 get_bone_pos( I32 bone_id ) { + return VEC3{ + csgop->read<F32>( m_dwBoneMatrix( ) + 0x30 * bone_id + 0x0c ), + csgop->read<F32>( m_dwBoneMatrix( ) + 0x30 * bone_id + 0x1c ), + csgop->read<F32>( m_dwBoneMatrix( ) + 0x30 * bone_id + 0x2c ) + }; + } + + NETVAR( m_bSpottedByMask , "DT_BaseEntity", I32 ); + + NETVAR( m_aimPunchAngle , "DT_BasePlayer", VEC3 ); + NETVAR( m_hActiveWeapon , "DT_BasePlayer", U32 ); + NETVAR( m_iHealth , "DT_BasePlayer", I32 ); + NETVAR( m_vecOrigin , "DT_BasePlayer", VEC3 ); + + NETVAR( m_clrRender , "DT_CSPlayer" , BYTECOLOR ); + NETVAR( m_flFlashMaxAlpha, "DT_CSPlayer" , F32 ); + NETVAR( m_iShotsFired , "DT_CSPlayer" , I32 ); + NETVAR( m_iTeamNum , "DT_CSPlayer" , I32 ); + NETVAR( m_lifeState , "DT_CSPlayer" , I32 ); + + OFFSET( m_vecViewOffset , "m_vecViewOffset[0]", "DT_CSPlayer", VEC3, 0 ); +};
\ No newline at end of file diff --git a/src/csgo/hack.cpp b/src/csgo/hack.cpp new file mode 100644 index 0000000..e979f3d --- /dev/null +++ b/src/csgo/hack.cpp @@ -0,0 +1,521 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#include "hack.h" + +#include "convar.h" +#include "netvar.h" +#include "../disasm.h" + +#include <algorithm> + +SETTING_HOLDER settings; +SETTING<I32> triggerbot_key{ &settings, "triggerbot_key", 0x6 }; +SETTING<bool> triggerteam_active{ &settings, "triggerteam_active", false }; +SETTING<bool> aim_active{ &settings, "aim_active", false }; +SETTING<bool> rcs_active{ &settings, "rcs_active", false }; +SETTING<bool> bhop_active{ &settings, "bhop_active", true }; +SETTING<bool> chams_active{ &settings, "chams_active", false }; +SETTING<bool> glow_active{ &settings, "glow_active", false }; +SETTING<bool> nightmode_active{ &settings, "nightmode_active", false }; +SETTING<bool> noflash_active{ &settings, "noflash_active", false }; +SETTING<bool> crosshair_active{ &settings, "crosshair_active", false }; +SETTING<bool> clantag_active{ &settings, "clantag_active", false }; + +F64 perf_ipt = .0; +F64 perf_tps = .0; +U64 perf_tickrate = 1024; + +U32 localplayer_ptr; +U32 ambientmin_ptr; +U32 attack_ptr; +U32 clantag_ptr; +U32 clientstate_ptr; +U32 glow_ptr; +U32 jump_ptr; +U32 pitch_ptr; +U32 tonemap_ptr; +U32 xhair_ptr; +U32 yaw_ptr; + +void hack_run_bhop( CSGO* p ) { + if( !bhop_active || !( GetAsyncKeyState( VK_SPACE ) & 0x8000 ) ) + return; + + assert( !!localplayer_ptr ); + assert( !!jump_ptr ); + + CSGOPLAYER player = p->read<U32>( localplayer_ptr ); + if( !player ) + return; + + I32 player_flags = player.m_fFlags(); + bool air = !( player_flags & 1 << 0 ); + + if( !air || player.m_MoveType( ) == 9 ) + p->write<I32>( jump_ptr, 6 ); + else + p->write<I32>( jump_ptr, 4 ); +} + +void hack_run_trigger( CSGO* p ) { + if( !( GetAsyncKeyState( triggerbot_key ) & 0x8000 ) ) + return; + + assert( !!localplayer_ptr ); + assert( !!attack_ptr ); + + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + I32 crosshairid = local.m_iCrosshairID(); + + CSGOPLAYER t_player = CSGOENTITY::from_list( crosshairid - 1 ); + if( t_player.m_iTeamNum( ) == local.m_iTeamNum( ) && !triggerteam_active ) + return; + + if( crosshairid > 0 && crosshairid < 65 ) + p->write< I32 >( attack_ptr, 6 ); +} + +void hack_run_chams( CSGO* p ) { + if( chams_active ) + convar_set<float>( p, ambientmin_ptr, nightmode_active ? 250.f : 50.f ); + else + convar_set<float>( p, ambientmin_ptr, 0.f ); +} + +void hack_run_glow( CSGO* p ) { + if( !glow_active ) + return; + + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + if( !local ) + return; + + U32 local_team = local.m_iTeamNum(); + + GLOW_OBJ_MANAGER glow; + p->read( glow_ptr, &glow, sizeof( GLOW_OBJ_MANAGER ) ); + + if( !glow.count ) + return; + + GLOW_OBJECT* glow_objects = (GLOW_OBJECT*)malloc( sizeof( GLOW_OBJECT ) * glow.count ); + p->read( (U32)( glow.objects ), glow_objects, sizeof( GLOW_OBJECT ) * glow.count ); + + for( U32 i = 0; i < glow.count; ++i ) { + GLOW_OBJECT& o = glow_objects[i]; + + if( !o.ent || local.base == o.ent ) + continue; + + CSGOPLAYER e = o.ent; + CSGO_CLIENT_CLASS cl = e.get_clientclass(); + COLOR color; + + /* clientclass outdated af*/ + if( cl.index == CCSPlayer ) { + I32 team = e.m_iTeamNum(); + if( team == local_team || (team != 2 && team != 3) ) + continue; + + color = ( team == 2 ) ? + COLOR{ 1.0f, 0.17f, 0.37f, 0.7f } : + COLOR{ 0.17f, 0.67f, 0.8f, 0.8f }; + + // TODO: RUN ENTLIST AND CLEAR THIS ONCE CHAMS ARE DISABLED. + if( chams_active ) + e.m_clrRender( BYTECOLOR{ 232, 85, 193, 255 } ); + } + else if( cl.index >= CWeaponAug && cl.index <= CWeaponXM1014 && !o.rwo ) { + color = { 0.8f, 0.8f, 0.8f, 0.6f }; + } + else continue; + + o.rwo = true; + o.rwuo = false; + o.bloom_amt = 0.7f; + o.full_bloom = false; + o.color = color; + + U32 obj_address = (U32)glow.objects + i * sizeof( GLOW_OBJECT ); + p->write( obj_address + 0x8, (void*)( (U32)&glow_objects[i] + 0x8 ), sizeof( GLOW_OBJECT ) - 0x16 ); + } + + free( glow_objects ); +} + +void hack_run_nightmode( CSGO* p ) { + static bool prev_active = false; + + static F32 anim_end = 0.f; + const F32 anim_time = 1.2f; + + if( nightmode_active != prev_active ) { + F32 time = (F32)u_time(); + anim_end = time + anim_time; + + prev_active = nightmode_active; + } + + F32 time = (F32)u_tick() / T_SEC; + if( time < anim_end ) { + F32 delta = ( anim_end - time ) / anim_time; + if( delta > 1.0f ) + delta = 1.0f; + + convar_set<float>( p, tonemap_ptr, nightmode_active ? 0.2f + delta * 0.9f : 1.0f - delta * 0.9f ); + } +} + +void hack_run_noflash( CSGO* p ) { + if( !noflash_active ) + return; + + assert( !!localplayer_ptr ); + + CSGOPLAYER player = p->read<U32>( localplayer_ptr ); + if( !player ) + return; + + if( player.m_flFlashMaxAlpha( ) > 0.f ) + player.m_flFlashMaxAlpha( 0.f ); +} + +void hack_run_crosshair( CSGO* p ) { + if( crosshair_active ) + convar_set<F32>( p, xhair_ptr, 1.f ); + else + convar_set<F32>( p, xhair_ptr, 0.f ); +} + +__declspec( naked ) void __stdcall setclantag_shellcode( void* string ) { + __asm { + push ebp + mov ebp, esp + sub esp, __LOCAL_SIZE + } + + U32 clantag_offset; + clantag_offset = 0xDADADADA; + + using set_clantag = int( __fastcall* )( const char*, const char* ); + ( (set_clantag)(clantag_offset) )( (const char*)string, (const char*)string ); + + DISASM_SIG(); + + __asm { + mov esp, ebp + pop ebp + ret + } +} + +void hack_setclantag( CSGO* csgo, const char* str ) { + static U64 func_address = 0; + static U64 string_address = 0; + + if( !func_address || !string_address ) { + DISASM_INFO disasm = disasm_function( &setclantag_shellcode ); + + U8* func_copy = (U8*)malloc( disasm.func_length ); + memcpy( func_copy, disasm.func_start, disasm.func_length ); + + for( U32 i = 0; i < disasm.func_length; ++i ) { + if( *(U32*)( func_copy + i ) == 0xdadadada ) { + *(U32*)( func_copy + i ) = clantag_ptr; + break; + } + } + + func_address = csgo->allocate( disasm.func_length ); + string_address = csgo->allocate( 16, PAGE_READWRITE ); + csgo->write( func_address, func_copy, disasm.func_length ); + + free( func_copy ); + } + + + U32 len = strlen( str ); + assert( (len < 16) ); + + csgo->write( string_address, str, len ); + u_thread_create( + csgo->get_base(), + (LPTHREAD_START_ROUTINE)(U32)func_address, + (void*)(U32)string_address + ); +} + +void hack_run_clantag( CSGO* csgo ) { + if( !clantag_active || !localplayer_ptr ) + return; + + const char8_t* clantag[] = { + u8"\u30FB\u2605*\u309C\u22C6", + u8"\u309C\u30FB\u2605\u22C6*", + u8"\u22C6\u309C\u30FB*\u2605", + u8"*\u22C6\u309C\u2605\u30FB", + u8"\u2605*\u22C6\u30FB\u309C" + }; + + static I32 counter = 0; + static U64 last_tick = u_tick() + (rand() % 1000 - 500); + U64 tick = u_tick(); + + + if( tick - last_tick > 1000 ) { + counter = (++counter) % 5; + + hack_setclantag( csgo, (const char*)( clantag[counter] ) ); + last_tick = tick; + } +} + +// fix tapfire over-compensation issue +void hack_run_recoil( CSGO* p ) { + if( !rcs_active ) + return; + + assert( !!localplayer_ptr ); + assert( !!clientstate_ptr ); + + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + if( !local ) + return; + + CSGOENTITY wep = CSGOENTITY::from_list( + ( ( local.m_hActiveWeapon( ) & 0xFFF ) - 1 ) + ); + if( !wep.is_weapon( ) ) + return; + + static VEC3 last_punch{ }; + if( local.m_iShotsFired( ) ) { + VEC3 local_view = p->read<VEC3>( clientstate_ptr + 0x4d90 ); + VEC3 rcs_angle = { + local_view.x + last_punch.x - local.m_aimPunchAngle( ).x * 2.f, + local_view.y + last_punch.y - local.m_aimPunchAngle( ).y * 2.f, + 0.f + }; + + p->write<VEC3>( clientstate_ptr + 0x4d90, rcs_angle.clamp( ) ); + + last_punch = { + local.m_aimPunchAngle( ).x * 2.f, + local.m_aimPunchAngle( ).y * 2.f, + 0.f + }; + } else { + // this isnt right iirc + last_punch = { + local.m_aimPunchAngle( ).x * 2.f, + local.m_aimPunchAngle( ).y * 2.f, + 0.f + }; + } + return; +} + +inline void hack_print_offset( U8 line, const char* name, ULONG offset ) { + con_set_line_text( line, name ); + U8 color = offset > 0x1000 ? CONFG_WHITE : CONFG_RED; + + con_set_line_subtext( line, u_num_to_string_hex( offset ), false, color ); +} + +inline U32 get_clantag_offset( CSGO* csgo ) { + const char* const clantag_str = "Current clan ID for name decoration"; + U32 str = csgo->code_match( csgo->engine, (U8*)clantag_str, strlen( clantag_str ) ); + while( csgo->read<U8>( str - 1 ) != 0 ) + str = csgo->code_match( csgo->engine, (U8*)clantag_str, strlen( clantag_str ), str + 1 ); + + U8 str_bytes[] = { + 0x68, + *( (U8*)(&str) + 0 ), + *( (U8*)(&str) + 1 ), + *( (U8*)(&str) + 2 ), + *( (U8*)(&str) + 3 ) + }; + + U32 push_str = csgo->code_match( csgo->engine, str_bytes, sizeof( str_bytes ) ); + U8 func_buffer[100]; + csgo->read( push_str - 100, func_buffer, sizeof( func_buffer ) ); + + U32 cvar_func = 0; + for( U32 i = 0; i < 100; ++i ) { + if( func_buffer[i] == 0x68 && func_buffer[i + 5] == 0x51 ) { + cvar_func = *(U32*)( func_buffer + i + 1 ); + break; + } + } + + U8 cvar_func_buffer[256]; + csgo->read( cvar_func, cvar_func_buffer, sizeof( cvar_func_buffer ) ); + + for( U32 i = 0; i < 256; ++i ) { + if( cvar_func_buffer[i] == 0xe8 + && cvar_func_buffer[i + 5] == 0x5f + && cvar_func_buffer[i + 6] == 0x5e + && cvar_func_buffer[i + 7] == 0x5b ) { + return *(U32*)( cvar_func_buffer + i + 1 ) + cvar_func + i + 5; + } + } + + return 0; +} + +inline U32 get_jump_offset( CSGO* csgo ) { + IFACE_ENTRY chl = u_vector_search<IFACE_ENTRY>( csgo->interfaces, []( IFACE_ENTRY* e ) { + return !!strstr( e->name, "VClient0" ); + } ); + + if( !chl.ptr ) + return 0; + + U32 chl_vtable = csgo->read<U32>( chl.ptr ); + U32 chl_vtable_16 = csgo->read<U32>( chl_vtable + 16 * sizeof(U32) ); + U32 input = csgo->read<U32>( chl_vtable_16 + 1 ); + + U32 input_vtable = csgo->read<U32>( input ); + U32 vtable_3 = csgo->read<U32>( input_vtable + 2 * sizeof(U32) ); + + U8 func_buffer[256]; + csgo->read( vtable_3, func_buffer, sizeof( func_buffer ) ); + + U8 pattern[] = { 0x83, 0xca, 0x02, 0x24, 0x03 }; + for( U32 i = 0; i < sizeof( func_buffer ) - sizeof( pattern ); ++i ) { + if( u_binary_match( func_buffer + i, pattern, sizeof( pattern ) ) ) { + return *(U32*)( func_buffer + i - 8 ); + } + } + + return 0; +} + +inline U32 get_attack_offset( CSGO* csgo ) { + IFACE_ENTRY chl = u_vector_search<IFACE_ENTRY>( csgo->interfaces, []( IFACE_ENTRY* e ) { + return !!strstr( e->name, "VClient0" ); + } ); + + if( !chl.ptr ) + return 0; + + U32 chl_vtable = csgo->read<U32>( chl.ptr ); + U32 chl_vtable_16 = csgo->read<U32>( chl_vtable + 16 * sizeof(U32) ); + U32 input = csgo->read<U32>( chl_vtable_16 + 1 ); + + U32 input_vtable = csgo->read<U32>( input ); + U32 vtable_3 = csgo->read<U32>( input_vtable + 2 * sizeof(U32) ); + + U8 func_buffer[256]; + csgo->read( vtable_3, func_buffer, sizeof( func_buffer ) ); + + U8 pattern[] = { 0x83, 0xca, 0x01, 0x24, 0x03 }; + for( U32 i = 0; i < sizeof( func_buffer ) - sizeof( pattern ); ++i ) { + if( u_binary_match( func_buffer + i, pattern, sizeof( pattern ) ) ) { + return *(U32*)( func_buffer + i - 8 ); + } + } + + return 0; +} + +inline U32 get_clientstate_offset( CSGO* csgo ) { + IFACE_ENTRY engine = u_vector_search<IFACE_ENTRY>( csgo->interfaces, []( IFACE_ENTRY* e ) { + return !!strstr( e->name, "VEngineClient0" ); + } ); + + if( !engine.ptr ) + return 0; + + U32 engine_vtable = csgo->read<U32>( engine.ptr ); + U32 engine_vtable_18 = csgo->read<U32>( engine_vtable + 18 * sizeof(U32) ); + + U8 func_buffer[256]; + csgo->read( engine_vtable_18, func_buffer, sizeof( func_buffer ) ); + + for( U32 i = 0; i < 256; ++i ) { + if( func_buffer[i] == 0x8b + && func_buffer[i+1] == 0x34 + && func_buffer[i+2] == 0x85 ) { + return csgo->read<U32>( *(U32*)( func_buffer + i + 3 ) ); + } + } + + return 0; +} + +#define progress( x ) con_set_line( CON_MAX_HEIGHT - 1, con_progressbar( x ), "" ) + +CSGO* hack_init() { + static CSGO p; + con_clear(); + + while( !p.open() ) { + progress( 0.f ); + con_set_bottomline_text( "waiting for process..." ); + Sleep( 500 ); + } + + progress( .2f ); + do { + p.client = p.get_module32( "client.dll"fnv ); + p.engine = p.get_module32( "engine.dll"fnv ); + if( p.client && p.engine ) + break; + + progress( .3f ); + con_set_bottomline_text( "waiting for modules..." ); + Sleep( 500 ); + } while( true ); + + progress( .4f ); + con_set_bottomline_text( "dumping interfaces..." ); + + do { + p.dump_interfaces(); + if( p.interfaces.size() > 1 ) + break; + + progress( .4f ); + Sleep( 500 ); + } while( true ); + + progress( .5f ); + // preload netvar tables + netvar_get_table( &p, " " ); + progress( .6f ); + + con_set_bottomline_text( "searching for offsets..." ); + + con_set_line_text( 0, "found interfaces: " ); + con_set_line_subtext( 0, u_num_to_string_dec( p.interfaces.size() ), false, CONFG_CYAN ); + + localplayer_ptr = p.read<U32>( p.code_match( p.client, LOCALPLAYER_SIG ) + 3 ) + 4; + hack_print_offset( 1, "localplayer", localplayer_ptr ); progress( .62f ); + jump_ptr = get_jump_offset( &p ); + hack_print_offset( 2, "jump", jump_ptr ); progress( .65f ); + attack_ptr = get_attack_offset( &p ); + hack_print_offset( 3, "attack", attack_ptr ); progress( .7f ); + glow_ptr = p.read<U32>( p.code_match( p.client, GLOWSTRUCT_SIG ) + 1 ) + 4; + hack_print_offset( 4, "glow", glow_ptr ); progress( .74f ); + clantag_ptr = get_clantag_offset( &p ); + hack_print_offset( 5, "SetClanTag", clantag_ptr ); progress( .78f ); + clientstate_ptr = get_clientstate_offset( &p ); + hack_print_offset( 6, "clientstate", clientstate_ptr ); progress( .83f ); + + pitch_ptr = convar_find( &p, "m_pitch" ); + hack_print_offset( 7, "pitch", pitch_ptr ); progress( .90f ); + yaw_ptr = 0xdee938 + p.client; // convar_find( &p, "m_yaw" ); <-- how is this wrong + hack_print_offset( 8, "yaw", yaw_ptr ); progress( 1.f ); + ambientmin_ptr = convar_find( &p, "r_modelAmbientMin" ); + tonemap_ptr = convar_find( &p, "mat_force_tonemap_scale" ); + xhair_ptr = convar_find( &p, "cl_crosshair_recoil" ); + + progress( 1.f ); + CSGOENTITY::csgop = &p; + + return &p; +} + +#undef progress
\ No newline at end of file diff --git a/src/csgo/hack.h b/src/csgo/hack.h new file mode 100644 index 0000000..c10dd7c --- /dev/null +++ b/src/csgo/hack.h @@ -0,0 +1,138 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once + +#include <time.h> + +#include "../conout.h" +#include "../setting.h" + +#include "csgo.h" +#include "csgoentity.h" +#include "csgoplayer.h" + +struct CMD_FUNC { + using func_t = void( __cdecl* )( VECTOR<STR<64>> ); + func_t func; + STR<64> name; +}; + +void __cdecl game_hack_toggle( VECTOR<STR<64>> args ); +static CMD_FUNC g_hack_toggle = { + &game_hack_toggle, + "hg_" +}; + +static CMD_FUNC* cmd_funcs[] = { + &g_hack_toggle, +}; + +extern SETTING_HOLDER settings; +extern F64 perf_ipt; +extern F64 perf_tps; +static I64 perf_drift; +extern U64 perf_tickrate; + +const char* const LOCALPLAYER_SIG = "8D 34 85 ? ? ? ? 89 15 ? ? ? ? 8B 41 08 8B 48 04 83 F9 FF"; +const char* const GLOWSTRUCT_SIG = "A1 ? ? ? ? A8 01 75 4B"; + +extern U32 localplayer_ptr; +extern U32 clientstate_ptr; +extern U32 pitch_ptr; +extern U32 yaw_ptr; + +extern void hack_run_aim( CSGO* p ); +extern void hack_run_bhop( CSGO* p ); +extern void hack_run_chams( CSGO* p ); +extern void hack_run_clantag( CSGO* p ); +extern void hack_run_crosshair( CSGO* p ); +extern void hack_run_glow( CSGO* p ); +extern void hack_run_nightmode( CSGO* p ); +extern void hack_run_noflash( CSGO* p ); +extern void hack_run_recoil( CSGO* p ); +extern void hack_run_trigger( CSGO* p ); +extern CSGO* hack_init(); + +inline U64 hack_calc_perf_metrics( U64 tickrate ) { + static U64 last_tick; + U64 tick = u_tick(); + + static U64 last_tps_tick; + static U64 tick_counter = 0; + + perf_ipt = (tick - last_tick) / (F64)T_SEC; + + if( tick - last_tps_tick < T_SEC * 0.5 ) + ++tick_counter; + else { + perf_tps = (F64)tick_counter * 2; + tick_counter = 0; + last_tps_tick = tick; + + I64 tick_delta = (I64)tickrate - (I64)perf_tps; + F64 tick_ratio = (F64)tick_delta / (F64)( tickrate ) * 10; + if( tick_ratio < 1.0 ) + tick_ratio = 1.0; + + perf_drift += (I64)( 100.0 * tick_ratio ) * ( tick_delta < 0 ? 1 : -1 ); + } + + if( tickrate > 0 ) { + U64 delay = (T_SEC / tickrate); + u_sleep( delay + perf_drift ); + } + else { + u_sleep( 1 ); + } + + last_tick = tick; + return perf_drift; +} + +static bool hack_run( PROCESS32* p ) { + hack_calc_perf_metrics( perf_tickrate ); + + CSGO* csgo = (CSGO*)p; + + hack_run_aim( csgo ); + hack_run_bhop( csgo ); + hack_run_trigger( csgo ); + hack_run_recoil( csgo ); + hack_run_chams( csgo ); + hack_run_glow( csgo ); + hack_run_nightmode( csgo ); + hack_run_noflash( csgo ); + hack_run_crosshair( csgo ); + hack_run_clantag( csgo ); + + + static U32 string_ptr = 0; + if( !string_ptr ) { + string_ptr = p->code_match( csgo->engine, "B9 ? ? ? ? E8 ? ? ? ? 84 C0 75 0E 68 ? ? ? ? FF 15 ? ? ? ? 83 C4 04 83 05 ? ? ? ? ? 75 04" ); + string_ptr = p->read<U32>( string_ptr + 1 ); + } + + STR<64> buf; + p->read( string_ptr, buf, sizeof( buf ) ); + + for( U16 i = 0; i < 1; ++i ) { + CMD_FUNC* fn = cmd_funcs[i]; + + if( strncmp( fn->name.data, buf.data, strlen( fn->name.data ) ) == 0 ) { + fn->func( { buf } ); + p->write<U8>( string_ptr, 0 ); + } + } + + + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + con_set_bottomline_text( + "local: 0x%08x | flags: 0x%03x | tps: %.0f", + local.base, + local.m_fFlags(), + (F32)perf_tps + ); + + return csgo->valid(); +}
\ No newline at end of file diff --git a/src/csgo/hack_aim.cpp b/src/csgo/hack_aim.cpp new file mode 100644 index 0000000..9c95bdf --- /dev/null +++ b/src/csgo/hack_aim.cpp @@ -0,0 +1,110 @@ +#include "hack.h" + +#include "convar.h" +#include "netvar.h" + +SETTING<bool>& aim_active = *settings.find<bool>( "aim_active"fnv ); + +bool aim_check_player( CSGOPLAYER player, CSGO* p ) { + if( !player ) + return true; // if no player + if( player.get_clientclass().index != CCSPlayer ) + return true; // if not player + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + if( player.base == local ) + return true; // if player is you + if( player.m_iTeamNum() == local.m_iTeamNum() ) + return true; + if( player.m_bDormant() ) + return true; // dormant + if( player.m_lifeState() ) + return true; + if( !player.m_bSpottedByMask() ) + return true; + return false; +} + +#define aim_fov 10.f +#define aim_reset( ) { \ + m_pitch = m_yaw = 0.022f; \ + convar_set( p, pitch_ptr, m_pitch ); \ + convar_set( p, yaw_ptr, m_yaw ); \ + return; \ +} + +F32 calc_dist( VEC3 v, F32 distance ) { + F32 sqr1 = sinf( v.x * M_PI / 180.f ) * distance; + F32 sqr2 = sinf( v.y * M_PI / 180.f ) * distance; + return sqrtf( + ( sqr1 * sqr1 ) + ( sqr2 * sqr2 ) + ); +} + +void hack_run_aim( CSGO* p ) { + if( !aim_active ) + return; + + F32 m_pitch, m_yaw; + + CSGOPLAYER local = p->read<U32>( localplayer_ptr ); + if( local.m_iHealth( ) < 1 || !local ) + aim_reset(); + + CSGOENTITY wep = CSGOENTITY::from_list( + ( ( local.m_hActiveWeapon() & 0xFFF ) - 1 ) + ); + + if( !wep.is_weapon( ) ) + aim_reset(); + + F32 lowest_dist{ aim_fov }; + U32 closest{ }; + for( U32 index{}; index <= 64; ++index ) { + CSGOPLAYER player = CSGOENTITY::from_list( index ); + + if( aim_check_player( player, p ) ) + continue; + + VEC3 local_pos = local.m_vecOrigin( ) + local.m_vecViewOffset( ); + VEC3 local_view = p->read<VEC3>( clientstate_ptr + 0x4d90 ); + // could replace this magic number with pattern, but is it worth it ? + VEC3 target_pos; + if( wep.get_clientclass( ).index == CWeaponAWP ) + target_pos = player.get_bone_pos( 6 ); + else + target_pos = player.get_bone_pos( 8 ); + VEC3 target_ang = vector_angles( local_pos, target_pos ); + + //F32 distance = ( local_view - target_ang ).clamp().length2d(); // non-dynamic + F32 distance = calc_dist( + ( local_view - target_ang ), + local_pos.dist_to( target_pos ) + ); + + if( distance > lowest_dist ) + continue; + + lowest_dist = distance; + closest = player; + } + + if( !closest ) + aim_reset(); + + // change this to change strength. this is the minimum allowed by the game. + const F32 min_sens = 0.0001f; + F32 factor = ( lowest_dist / aim_fov ); + if( factor > 1.f ) + factor = 1.f; + + // change this for how aggressively the aim 'comes on'. + // lower values = less assist on outer edge of fov, more on inner. + factor = pow( factor, 3.f ); + + + m_pitch = min_sens + ( 0.022f - min_sens ) * factor, + m_yaw = min_sens + ( 0.022f - min_sens ) * factor; + + convar_set( p, pitch_ptr, m_pitch ); + convar_set( p, yaw_ptr, m_yaw ); +}
\ No newline at end of file diff --git a/src/csgo/interface.h b/src/csgo/interface.h new file mode 100644 index 0000000..62afb4a --- /dev/null +++ b/src/csgo/interface.h @@ -0,0 +1,110 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "../process.h" +#include "../util.h" +#include "../typedef.h" + +struct IFACE_ENTRY { + U32 ptr; + STR<64> name; + U32 module; + STR<64> module_name; +}; + +struct IFACE_REG { + void* create_fn; + const char* name; + U32 next; +}; + +inline bool iface_is_createinterface_export( PROCESS32* proc, U32 exp ) { + U8 buf[12]; + + proc->read( exp, buf, 12 ); + + return( + buf[0] == 0x55 && + buf[4] == 0xe9 && + buf[9] == 0xcc && + buf[10] == 0xcc + ); +} + +inline bool iface_is_createinterface( PROCESS32* proc, U32 fn ) { + U8 buf[12]; + + proc->read( fn, buf, 12 ); + + return ( + buf[0] == 0x55 && + buf[4] == 0x8b && + buf[10] == 0x57 + ); +} + +inline U32 iface_follow_createinterface( PROCESS32* proc, U32 exp ) { + U32 jmp = exp + 0x4; + U32 rel = proc->read<U32>( jmp + 0x1 ); + + return jmp + rel + 0x5; +} + +inline U32 iface_get_list( PROCESS32* proc, U32 exp ) { + return proc->read<U32>( proc->read<U32>( exp + 0x6 ) ); +} + +static VECTOR< IFACE_ENTRY > srceng_get_interfaces( PROCESS32* proc ) { + VECTOR< MODULE_EXPORT64 > exports; + VECTOR< MODULE_ENTRY > modules; + VECTOR< IFACE_ENTRY > ifaces; + MODULE_EXPORT64* create_interface_export; + U32 create_interface; + + modules = proc->dump_modules32(); + for( auto& module : modules ) { + create_interface_export = 0; + exports = module_get_exports( (U32)module.base, proc->get_base() ); + + for( auto& it : exports ) { + if( fnv1a( it.name ) == "CreateInterface"fnv && + iface_is_createinterface_export( proc, (U32)it.base ) + ) { + create_interface_export = ⁢ + break; + } + } + + if( !create_interface_export ) + continue; + + create_interface = iface_follow_createinterface( proc, (U32)create_interface_export->base ); + if( !create_interface || !iface_is_createinterface( proc, create_interface ) ) + continue; + + U32 list_ptr = iface_get_list( proc, create_interface ); + if( !list_ptr ) + continue; + + IFACE_REG reg = proc->read<IFACE_REG>( list_ptr ); + STR<64> name{}; + do { + memset( name.data, 0, 64 ); + proc->read( (U32)reg.name, name.data, 64 ); + name.data[63] = 0; + + IFACE_ENTRY e; + e.module = (U32)module.base; + e.module_name = module.name; + e.name = name; + e.ptr = proc->read<U32>( (U32)(reg.create_fn) + 0x1 ); + + ifaces.push_back( e ); + + reg = proc->read<IFACE_REG>( reg.next ); + } while( list_ptr != reg.next && reg.next ); + } + + return ifaces; +}
\ No newline at end of file diff --git a/src/csgo/materialsystem.h b/src/csgo/materialsystem.h new file mode 100644 index 0000000..263f808 --- /dev/null +++ b/src/csgo/materialsystem.h @@ -0,0 +1,61 @@ +#include "csgo.h" + +class MATERIAL { +private: + static IFACE_ENTRY* get_matsystem( CSGO* csgo ) { + static IFACE_ENTRY* ret = u_vector_search<IFACE_ENTRY>( csgo->interfaces, + []( IFACE_ENTRY i ) { + return fnv1a( "materialsystem.dll" ) == fnv1a( i.module_name ) + && !!strcmp( i.name, "VMaterialSystem" ); + } ); + + return ret; + } + + static IFACE_ENTRY* get_matsystem_cvar( CSGO* csgo ) { + static IFACE_ENTRY* ret = u_vector_search<IFACE_ENTRY>( csgo->interfaces, + []( IFACE_ENTRY i ) { + return fnv1a( "materialsystem.dll" ) == fnv1a( i.module_name ) + && !!strcmp( i.name, "VEngineCvar" ); + } ); + + return ret; + } + +public: + static U32 first_material( CSGO* csgo ) { + IFACE_ENTRY* mat_system = get_matsystem( csgo ); + + U16 mat_handle = csgo->read<U16>( mat_system->ptr + 0x250 ); + + while( mat_handle != 0xffff ) { + U32 handle_entries = csgo->read<U32>( mat_system->ptr + 0x244 ); + U16 next_handle = csgo->read<U16>( handle_entries + 16 * mat_handle ); + + if( next_handle == 0xffff ) + return mat_handle; + + mat_handle = next_handle; + } + + return 0; + } + + static U16 next_material( CSGO* csgo, U16 mat ) { + IFACE_ENTRY* mat_system = get_matsystem( csgo ); + + if( mat == 0xffff ) + return 0; + + U32 handle_array = csgo->read<U32>( mat_system->ptr + 0x244 ); + U16 next_handle = csgo->read<U16>( handle_array + 16 + mat + 2 ); + if( next_handle == 0xffff ) + return 0xffff; + + for( U16 i = next_handle; i != 0xffff; i = csgo->read<U16>( handle_array * 16 + i ) ) { + next_handle = i; + } + + return next_handle; + } +};
\ No newline at end of file diff --git a/src/csgo/netvar.h b/src/csgo/netvar.h new file mode 100644 index 0000000..cd5c702 --- /dev/null +++ b/src/csgo/netvar.h @@ -0,0 +1,142 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once + +#include "csgo.h" +#include "sdk.h" +#include "../conout.h" + +struct NETVAR_TABLE { + U32 ptr; + STR<64> name; +}; + +inline U32 netvar_get_classes( CSGO* csgo ) { + IFACE_ENTRY chl = u_vector_search<IFACE_ENTRY>( + csgo->interfaces, + []( IFACE_ENTRY* in ) { + return !!strstr( in->name, "VClient0" ); + } + ); + + if( !chl.ptr ) + return 0; + + U32 chl_vtable = csgo->read<U32>( chl.ptr ); + U32 vtable_8 = chl_vtable + 8 * sizeof(U32); + + U32 get_allclasses = csgo->read<U32>( vtable_8 ); + U32 class_ptr = csgo->read<U32>( csgo->read<U32>( get_allclasses + 0x1 ) ); + + return class_ptr; +} + +inline VECTOR<NETVAR_TABLE> netvar_get_tables( CSGO* csgo, U32 list ) { + static VECTOR<NETVAR_TABLE> tables{}; + if( !tables.empty() ) + return tables; + + U32 ptr = list; + STR<64> net_name; + do { + CSGO_CLIENT_CLASS cclass = csgo->read<CSGO_CLIENT_CLASS>( ptr ); + RECV_TABLE table = csgo->read<RECV_TABLE>( (U32)cclass.recv ); + csgo->read( (U32)table.table_name, net_name.data, 64 ); + + tables.push_back( { (U32)cclass.recv, net_name } ); + ptr = (U32)cclass.next; + } while( ptr && ptr != list ); + + return tables; +} + +inline U32 netvar_get_table( CSGO* csgo, const char* table_name ) { + static U32 list_ptr = netvar_get_classes( csgo ); + static VECTOR<NETVAR_TABLE> tables = netvar_get_tables( csgo, list_ptr ); + + for( auto& it : tables ) { + if( !strcmp( it.name.data, table_name ) ) + return it.ptr; + } + + return 0; +} + +inline I32 netvar_get_entry( CSGO* csgo, const char* name, U32 table_ptr ) { + I32 ret{}; + RECV_TABLE table = csgo->read<RECV_TABLE>( table_ptr ); + + RECV_PROP* props = (RECV_PROP*)malloc( table.prop_count * sizeof( RECV_PROP ) ); + csgo->read( (U32)table.props, props, sizeof( RECV_PROP ) * table.prop_count ); + + for( I32 i = 0; i < table.prop_count; ++i ) { + RECV_PROP* prop = &props[i]; + + if( prop->table ) { + RECV_TABLE child = csgo->read<RECV_TABLE>( (U32)prop->table ); + if( child.prop_count ) { + U32 tmp = netvar_get_entry( csgo, name, (U32)prop->table ); + if( tmp ) ret += prop->offset + tmp; + } + } + + STR<64> prop_name; + csgo->read( (U32)prop->varname, prop_name.data, 64 ); + + if( !!strcmp( prop_name.data, name ) ) + continue; + + ret += prop->offset; + break; + } + + free( props ); + return ret; +} + +inline I32 netvar_find( CSGO* csgo, const char* table_name, const char* prop ) { + I32 ret; + U32 table = netvar_get_table( csgo, table_name ); + + if( !table ) + return 0; + + ret = netvar_get_entry( csgo, prop, table ); + return ret; +} + +static void csgo_dump_classes( CSGO* csgo ) { + U32 allclasses = netvar_get_classes( csgo ); + + if( !allclasses ) + return; + + char* dump = (char*)malloc( 99999 ); + memset( dump, 0, 99999 ); + strcat( dump, "enum CSGO_CLIENT_CLASS {\n" ); + + U32 ptr = allclasses; + STR<64> net_name; + do { + CSGO_CLIENT_CLASS cclass = csgo->read<CSGO_CLIENT_CLASS>( ptr ); + csgo->read( (U64)cclass.network_name, net_name.data, 64 ); + + strcat( dump, " " ); + strcat( dump, net_name ); + strcat( dump, " = " ); + strcat( dump, "0x" ); + strcat( dump, u_num_to_string_hex( cclass.index ) ); + strcat( dump, ",\n" ); + + ptr = (U32)cclass.next; + } while( ptr && ptr != allclasses ); + + strcat( dump, "};" ); + + FILE* f = fopen( "./classes.dump", "w" ); + fwrite( dump, strlen( dump ), 1, f ); + fclose( f ); + + free( dump ); +}
\ No newline at end of file diff --git a/src/csgo/sdk.h b/src/csgo/sdk.h new file mode 100644 index 0000000..449d8de --- /dev/null +++ b/src/csgo/sdk.h @@ -0,0 +1,528 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include "../vec3.h" + +struct BYTECOLOR { + BYTECOLOR() = default; + BYTECOLOR( U8 r1, U8 g1, U8 b1, U8 a1 ) : r( r1 ), g( g1 ), b( b1 ), a( a1 ) {} + + U8 r; + U8 g; + U8 b; + U8 a; +}; + +struct COLOR { + COLOR() = default; + COLOR( F32 r1, F32 g1, F32 b1, F32 a1 ) : r( r1 ), g( g1 ), b( b1 ), a( a1 ) {} + + F32 r; + F32 g; + F32 b; + F32 a; +}; + +struct GLOW_OBJECT { + U8 pad00[ 4 ]; + U32 ent; //0000 + COLOR color; + U8 pad01[ 8 ]; + F32 bloom_amt; + U8 pad_02[ 4 ]; + bool rwo; //0024 + bool rwuo; //0025 + bool full_bloom; + char pad_002B[1]; //0x002B + I32 fullbloom_stencil; //0x002C + I32 unk; //0x0030 + I32 splitscreen_slot; //0x0034 +}; + +struct GLOW_OBJ_MANAGER { + GLOW_OBJECT* objects; + U32 max; + U32 unk02; + U32 count; + U32 data_ptr_back; + U32 first_free_slot; + U32 unk1; + U32 unk2; + U32 unk3; + U32 unk4; + U32 unk5; +}; + +struct RECV_PROP; +struct RECV_TABLE { + RECV_PROP* props; + I32 prop_count; + void* decoder; + const char* table_name; + + bool initialized; + bool in_main_list; +}; + +struct RECV_PROP { + const char* varname; + I32 recv_type; + I32 flags; + I32 buffer_size; + bool inside_array; + void* extra_data; + + RECV_PROP* array_prop; + void* array_length_proxy; + + void* proxy_fn; + void* dt_proxy_fn; + + RECV_TABLE* table; + I32 offset; + + I32 element_stride; + I32 elements; + + const char* parent_array_name; +}; + +class CSGO_CLIENT_CLASS { +public: + void* create_fn; + void* create_event_fn; + const char* network_name; + void* recv; + CSGO_CLIENT_CLASS* next; + U32 index; +}; + +enum CSGO_CLASS_ID { + CTestTraceline = 0x000000E0, + CTEWorldDecal = 0x000000E1, + CTESpriteSpray = 0x000000DE, + CTESprite = 0x000000DD, + CTESparks = 0x000000DC, + CTESmoke = 0x000000DB, + CTEShowLine = 0x000000D9, + CTEProjectedDecal = 0x000000D6, + CFEPlayerDecal = 0x00000047, + CTEPlayerDecal = 0x000000D5, + CTEPhysicsProp = 0x000000D2, + CTEParticleSystem = 0x000000D1, + CTEMuzzleFlash = 0x000000D0, + CTELargeFunnel = 0x000000CE, + CTEKillPlayerAttachments = 0x000000CD, + CTEImpact = 0x000000CC, + CTEGlowSprite = 0x000000CB, + CTEShatterSurface = 0x000000D8, + CTEFootprintDecal = 0x000000C8, + CTEFizz = 0x000000C7, + CTEExplosion = 0x000000C5, + CTEEnergySplash = 0x000000C4, + CTEEffectDispatch = 0x000000C3, + CTEDynamicLight = 0x000000C2, + CTEDecal = 0x000000C0, + CTEClientProjectile = 0x000000BF, + CTEBubbleTrail = 0x000000BE, + CTEBubbles = 0x000000BD, + CTEBSPDecal = 0x000000BC, + CTEBreakModel = 0x000000BB, + CTEBloodStream = 0x000000BA, + CTEBloodSprite = 0x000000B9, + CTEBeamSpline = 0x000000B8, + CTEBeamRingPoint = 0x000000B7, + CTEBeamRing = 0x000000B6, + CTEBeamPoints = 0x000000B5, + CTEBeamLaser = 0x000000B4, + CTEBeamFollow = 0x000000B3, + CTEBeamEnts = 0x000000B2, + CTEBeamEntPoint = 0x000000B1, + CTEBaseBeam = 0x000000B0, + CTEArmorRicochet = 0x000000AF, + CTEMetalSparks = 0x000000CF, + CSteamJet = 0x000000A8, + CSmokeStack = 0x0000009E, + DustTrail = 0x00000115, + CFireTrail = 0x0000004A, + SporeTrail = 0x0000011B, + SporeExplosion = 0x0000011A, + RocketTrail = 0x00000118, + SmokeTrail = 0x00000119, + CPropVehicleDriveable = 0x00000091, + ParticleSmokeGrenade = 0x00000117, + CParticleFire = 0x00000075, + MovieExplosion = 0x00000116, + CTEGaussExplosion = 0x000000CA, + CEnvQuadraticBeam = 0x00000042, + CEmbers = 0x00000037, + CEnvWind = 0x00000046, + CPrecipitation = 0x0000008A, + CPrecipitationBlocker = 0x0000008B, + CBaseTempEntity = 0x00000012, + NextBotCombatCharacter = 0x00000000, + CEconWearable = 0x00000036, + CBaseAttributableItem = 0x00000004, + CEconEntity = 0x00000035, + CWeaponZoneRepulsor = 0x00000112, + CWeaponXM1014 = 0x00000111, + CWeaponTaser = 0x0000010C, + CTablet = 0x000000AC, + CSnowball = 0x0000009F, + CSmokeGrenade = 0x0000009C, + CWeaponShield = 0x0000010A, + CWeaponSG552 = 0x00000108, + CSensorGrenade = 0x00000098, + CWeaponSawedoff = 0x00000104, + CWeaponNOVA = 0x00000100, + CIncendiaryGrenade = 0x00000063, + CMolotovGrenade = 0x00000071, + CMelee = 0x00000070, + CWeaponM3 = 0x000000F8, + CKnifeGG = 0x0000006C, + CKnife = 0x0000006B, + CHEGrenade = 0x00000060, + CFlashbang = 0x0000004D, + CFists = 0x0000004C, + CWeaponElite = 0x000000EF, + CDecoyGrenade = 0x0000002F, + CDEagle = 0x0000002E, + CWeaponUSP = 0x00000110, + CWeaponM249 = 0x000000F7, + CWeaponUMP45 = 0x0000010F, + CWeaponTMP = 0x0000010E, + CWeaponTec9 = 0x0000010D, + CWeaponSSG08 = 0x0000010B, + CWeaponSG556 = 0x00000109, + CWeaponSG550 = 0x00000107, + CWeaponScout = 0x00000106, + CWeaponSCAR20 = 0x00000105, + CSCAR17 = 0x00000096, + CWeaponP90 = 0x00000103, + CWeaponP250 = 0x00000102, + CWeaponP228 = 0x00000101, + CWeaponNegev = 0x000000FF, + CWeaponMP9 = 0x000000FE, + CWeaponMP7 = 0x000000FD, + CWeaponMP5Navy = 0x000000FC, + CWeaponMag7 = 0x000000FB, + CWeaponMAC10 = 0x000000FA, + CWeaponM4A1 = 0x000000F9, + CWeaponHKP2000 = 0x000000F6, + CWeaponGlock = 0x000000F5, + CWeaponGalilAR = 0x000000F4, + CWeaponGalil = 0x000000F3, + CWeaponG3SG1 = 0x000000F2, + CWeaponFiveSeven = 0x000000F1, + CWeaponFamas = 0x000000F0, + CWeaponBizon = 0x000000EB, + CWeaponAWP = 0x000000E9, + CWeaponAug = 0x000000E8, + CAK47 = 0x00000001, + CWeaponCSBaseGun = 0x000000ED, + CWeaponCSBase = 0x000000EC, + CC4 = 0x00000022, + CBumpMine = 0x00000020, + CBumpMineProjectile = 0x00000021, + CBreachCharge = 0x0000001C, + CBreachChargeProjectile = 0x0000001D, + CWeaponBaseItem = 0x000000EA, + CBaseCSGrenade = 0x00000008, + CSnowballProjectile = 0x000000A1, + CSnowballPile = 0x000000A0, + CSmokeGrenadeProjectile = 0x0000009D, + CSensorGrenadeProjectile = 0x00000099, + CMolotovProjectile = 0x00000072, + CItem_Healthshot = 0x00000068, + CItemDogtags = 0x0000006A, + CDecoyProjectile = 0x00000030, + CPhysPropRadarJammer = 0x0000007F, + CPhysPropWeaponUpgrade = 0x00000080, + CPhysPropAmmoBox = 0x0000007D, + CPhysPropLootCrate = 0x0000007E, + CItemCash = 0x00000069, + CEnvGasCanister = 0x0000003F, + CDronegun = 0x00000032, + CParadropChopper = 0x00000074, + CSurvivalSpawnChopper = 0x000000AB, + CBRC4Target = 0x0000001B, + CInfoMapRegion = 0x00000066, + CFireCrackerBlast = 0x00000048, + CInferno = 0x00000064, + CChicken = 0x00000024, + CDrone = 0x00000031, + CFootstepControl = 0x0000004F, + CCSGameRulesProxy = 0x00000027, + CWeaponCubemap = 0x00000000, + CWeaponCycler = 0x000000EE, + CTEPlantBomb = 0x000000D3, + CTEFireBullets = 0x000000C6, + CTERadioIcon = 0x000000D7, + CPlantedC4 = 0x00000081, + CCSTeam = 0x0000002B, + CCSPlayerResource = 0x00000029, + CCSPlayer = 0x00000028, + CPlayerPing = 0x00000083, + CCSRagdoll = 0x0000002A, + CTEPlayerAnimEvent = 0x000000D4, + CHostage = 0x00000061, + CHostageCarriableProp = 0x00000062, + CBaseCSGrenadeProjectile = 0x00000009, + CHandleTest = 0x0000005F, + CTeamplayRoundBasedRulesProxy = 0x000000AE, + CSpriteTrail = 0x000000A6, + CSpriteOriented = 0x000000A5, + CSprite = 0x000000A4, + CRagdollPropAttached = 0x00000094, + CRagdollProp = 0x00000093, + CPropCounter = 0x0000008E, + CPredictedViewModel = 0x0000008C, + CPoseController = 0x00000088, + CGrassBurn = 0x0000005E, + CGameRulesProxy = 0x0000005D, + CInfoLadderDismount = 0x00000065, + CFuncLadder = 0x00000055, + CTEFoundryHelpers = 0x000000C9, + CEnvDetailController = 0x0000003D, + CDangerZone = 0x0000002C, + CDangerZoneController = 0x0000002D, + CWorldVguiText = 0x00000114, + CWorld = 0x00000113, + CWaterLODControl = 0x000000E7, + CWaterBullet = 0x000000E6, + CMapVetoPickController = 0x0000006E, + CVoteController = 0x000000E5, + CVGuiScreen = 0x000000E4, + CPropJeep = 0x00000090, + CPropVehicleChoreoGeneric = 0x00000000, + CTriggerSoundOperator = 0x000000E3, + CBaseVPhysicsTrigger = 0x00000016, + CTriggerPlayerMovement = 0x000000E2, + CBaseTrigger = 0x00000014, + CTest_ProxyToggle_Networkable = 0x000000DF, + CTesla = 0x000000DA, + CBaseTeamObjectiveResource = 0x00000011, + CTeam = 0x000000AD, + CSunlightShadowControl = 0x000000AA, + CSun = 0x000000A9, + CParticlePerformanceMonitor = 0x00000076, + CSpotlightEnd = 0x000000A3, + CSpatialEntity = 0x000000A2, + CSlideshowDisplay = 0x0000009B, + CShadowControl = 0x0000009A, + CSceneEntity = 0x00000097, + CRopeKeyframe = 0x00000095, + CRagdollManager = 0x00000092, + CPhysicsPropMultiplayer = 0x0000007B, + CPhysBoxMultiplayer = 0x00000079, + CPropDoorRotating = 0x0000008F, + CBasePropDoor = 0x00000010, + CDynamicProp = 0x00000034, + CProp_Hallucination = 0x0000008D, + CPostProcessController = 0x00000089, + CPointWorldText = 0x00000087, + CPointCommentaryNode = 0x00000086, + CPointCamera = 0x00000085, + CPlayerResource = 0x00000084, + CPlasma = 0x00000082, + CPhysMagnet = 0x0000007C, + CPhysicsProp = 0x0000007A, + CStatueProp = 0x000000A7, + CPhysBox = 0x00000078, + CParticleSystem = 0x00000077, + CMovieDisplay = 0x00000073, + CMaterialModifyControl = 0x0000006F, + CLightGlow = 0x0000006D, + CItemAssaultSuitUseable = 0x00000000, + CItem = 0x00000000, + CInfoOverlayAccessor = 0x00000067, + CFuncTrackTrain = 0x0000005C, + CFuncSmokeVolume = 0x0000005B, + CFuncRotating = 0x0000005A, + CFuncReflectiveGlass = 0x00000059, + CFuncOccluder = 0x00000058, + CFuncMoveLinear = 0x00000057, + CFuncMonitor = 0x00000056, + CFunc_LOD = 0x00000051, + CTEDust = 0x000000C1, + CFunc_Dust = 0x00000050, + CFuncConveyor = 0x00000054, + CFuncBrush = 0x00000053, + CBreakableSurface = 0x0000001F, + CFuncAreaPortalWindow = 0x00000052, + CFish = 0x0000004B, + CFireSmoke = 0x00000049, + CEnvTonemapController = 0x00000045, + CEnvScreenEffect = 0x00000043, + CEnvScreenOverlay = 0x00000044, + CEnvProjectedTexture = 0x00000041, + CEnvParticleScript = 0x00000040, + CFogController = 0x0000004E, + CEnvDOFController = 0x0000003E, + CCascadeLight = 0x00000023, + CEnvAmbientLight = 0x0000003C, + CEntityParticleTrail = 0x0000003B, + CEntityFreezing = 0x0000003A, + CEntityFlame = 0x00000039, + CEntityDissolve = 0x00000038, + CDynamicLight = 0x00000033, + CColorCorrectionVolume = 0x00000026, + CColorCorrection = 0x00000025, + CBreakableProp = 0x0000001E, + CBeamSpotlight = 0x00000019, + CBaseButton = 0x00000005, + CBaseToggle = 0x00000013, + CBasePlayer = 0x0000000F, + CBaseFlex = 0x0000000C, + CBaseEntity = 0x0000000B, + CBaseDoor = 0x0000000A, + CBaseCombatCharacter = 0x00000006, + CBaseAnimatingOverlay = 0x00000003, + CBoneFollower = 0x0000001A, + CBaseAnimating = 0x00000002, + CAI_BaseNPC = 0x00000000, + CBeam = 0x00000018, + CBaseViewModel = 0x00000015, + CBaseParticleEntity = 0x0000000E, + CBaseGrenade = 0x0000000D, + CBaseCombatWeapon = 0x00000007, + CBaseWeaponWorldModel = 0x00000017, +}; + +struct CSGO_ANIM_STATE +{ +private: + U32 unk000; //0x0000 + U32 unk001; //0x0004 + char pad_0[4][4]; //0x0008 +public: + float unk_time; //0x0018 wheeee +private: + float point_four; //0x001C always 0.4 + float point_two; //0x0020 always 0.2 + U32 pad_1; //0x0024 +public: + float walk_amt; //0x0028 Resets to 0 when movement stops + float stop_amt; //0x002C Resets to 0 when full run starts (bw/fw) +private: + float point_two2; //0x0030 always 0.2 + float point_four2; //0x0034 always 0.4 + float unk_float_but_special; //0x0038 + float unk_float2; //0x003C Resets to 0 when movement stops + float unk_float3; //0x0040 Resets to 0 when movement starts + float unk_float4; //0x0044 static? 0.3 + float unk_float5; //0x0048 static? 0.3 + float unk_float6; //0x004C 0.0 <-> 1.0 (to 1. when moving) + U32 unk_U32; //0x0050 static? 0x23E + char pad_2[2][4]; //0x0054 + void *curr_weapon_0; //0x005C current weapon + void *static_something; //0x0060 + void *curr_weapon_1; //0x0064 current weapon + void *curr_weapon_2; //0x0068 current weapon + float unk_time1; //0x006C same as +0x18 + U32 unk_time2; //0x0070 increases with time but its an int + U32 what; //0x0074 + float look_dir[3]; //0x0078 + float hell_yaw; //0x0084 + float velocity[3]; //0x0088 + float uppies; //0x0094 + float i_have_no_idea; //0x0098 + float unk_float_the_sixth; //0x009C + float N00000304; //0x00A0 + float jump_something0; //0x00A4 + float jump_something1; //0x00A8 + U32 delaware; //0x00AC + float origin_something[3]; //0x00B0 + float position_something[3]; //0x00BC + float inspector_vector[3]; //0x00C8 + float you_vector_go_catch_it[3]; //0x00D4 + float wow_three_floats[3]; //0x00E0 + float i_cant_believe_its_not_an_array[3]; //0x00EC + float fuel_prices[3]; //0x00F8 + float wow_the_point_FLOATS_get_it; //0x0104 + U8 onGround; //0x0108 + U8 hitGroundAnim; //0x0109 + U16 u_thought; //0x010A + char pad_010C[4]; //0x010C + float N00000387[3]; //0x0110 + float N0000038A; //0x011C + char pad_0120[160]; //0x0120 +}; //Size: 0x01C0 + +class CSGO_NETCHANNEL { + +}; + +struct CSGO_EVENT_INFO { + I16 class_id; + F32 fire_delay; + const void* send_table; + CSGO_CLIENT_CLASS* client_class; + void* data; + I32 packed_bits; + I32 flags; +private: + U8 pad[16]; +}; + +class CSGO_CLIENTSTATE { + char pad[156]; +public: + CSGO_NETCHANNEL* netchannel; + I32 challenge; +private: + U8 pad1[4]; +public: + F64 connect_time; + I32 retry_number; +private: + U8 pad2[84]; +public: + I32 signon_state; +private: + U8 pad3[4]; +public: + F64 next_cmd_time; + I32 server_count; + I32 current_sequence; +private: + U8 pad4[8]; +public: + float clock_offsets[16]; + I32 cur_clock_offset; + I32 server_tick; + I32 client_tick; + I32 delta_tick; +private: + U32 pad5; +public: + char level_name[260]; + char level_name_short[40]; +private: + U8 pad7[212]; +public: + I32 maxclients; +private: + U8 pad8[18836]; +public: + I32 old_tickcount; + F32 tick_remainder; + F32 frame_time; + I32 last_outgoing_command; + I32 choked_commands; + I32 last_command_ack; + I32 last_server_tick; + I32 command_ack; + I32 sound_sequence; + I32 last_progress_percent; + bool is_hltv; +private: + U8 pad9[75]; +public: + VEC3 viewangles; +private: + U8 pad10[204]; +public: + CSGO_EVENT_INFO* events; +};
\ No newline at end of file diff --git a/src/csgo/trace.h b/src/csgo/trace.h new file mode 100644 index 0000000..e496f15 --- /dev/null +++ b/src/csgo/trace.h @@ -0,0 +1,40 @@ +#include "../disasm.h" + +#include "hack.h" + +struct TRACE_ARGS { + U32 ignore_ent; + VEC3 start; + VEC3 end; + U32 mask; + + VEC3 ret_end; + VEC3 ret_normal; + U32 ret_ent; +}; + +__declspec( naked ) void __stdcall trace_shellcode( TRACE_ARGS* args ) { + __asm { + push ebp + mov ebp, esp + sub esp, LOCAL_SIZE + } + + + + DISASM_SIG(); + + __asm { + mov esp, ebp + pop ebp + ret + } +} + +U32 trace_allocate( CSGO* p ) { + DISASM_INFO disasm = disasm_function( &trace_shellcode ); +} + +U32 trace_find_func( CSGO* p ) { + +}
\ No newline at end of file |
