From 42223f61bd5b1ae15901c416ea662d6120866667 Mon Sep 17 00:00:00 2001 From: F0RQU1N <108815933+F0RQU1N@users.noreply.github.com> Date: Sat, 9 Mar 2024 10:42:51 +1000 Subject: [PATCH] rewrite --- .clang-format | 6 + core/dota_sdk.hpp | 352 +++++++++++++++++++--------------------------- core/main.cpp | 194 ++++++++++++++++++------- 3 files changed, 294 insertions(+), 258 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..5177106 --- /dev/null +++ b/.clang-format @@ -0,0 +1,6 @@ +Language: Cpp +BasedOnStyle: llvm +Standard: c++17 +TabWidth: 4 +IndentWidth: 4 +UseTab: Never \ No newline at end of file diff --git a/core/dota_sdk.hpp b/core/dota_sdk.hpp index c0a0eff..eb65bed 100644 --- a/core/dota_sdk.hpp +++ b/core/dota_sdk.hpp @@ -1,223 +1,163 @@ -#include -#include #include #include #include +#include #include #include -#include #include -#include +#include +#include +#include -typedef void* ( *CreateInterface )( const char* pName, int* pReturnCode ); -typedef std::uintptr_t( __fastcall* CDOTACamera__Init )( ); -typedef void( __fastcall* SetRenderingEnabled )( std::uintptr_t CParticleCollectionPtr, bool render ); +#pragma warning(disable : 6301) class DefClass { -public: - blackbone::ProcessMemory* memory; - std::uintptr_t baseAddr; - - std::uintptr_t GetVF( unsigned short idx ) noexcept { - const auto VMTAddr = memory->Read( baseAddr ).result( ); - - return memory->Read( VMTAddr + idx * 8 ).result( ); - } - - bool IsValid( ) { - return ( memory && baseAddr ) ? true : false; - } -}; + public: + blackbone::ProcessMemory *memory; + std::uintptr_t baseAddr; -template -inline T GetInterface( blackbone::Process* proc, const wchar_t* dllname, const char* interfacename ) { - const auto aCreateInterface = proc->modules( ).GetExport( dllname, (char*)"CreateInterface" ).result( ).procAddress; - auto iRetCode = 0; + std::uintptr_t GetVF(unsigned short idx) noexcept { + const auto VMTAddr = memory->Read(baseAddr).result(); - blackbone::RemoteFunction pFN( *proc, aCreateInterface ); - if ( const auto callResult = pFN.Call( interfacename, &iRetCode ); callResult.success( ) ) { - return reinterpret_cast( callResult.result( ) ); - } - return (T)nullptr; -} - -std::uintptr_t GetAbsoluteAddress( blackbone::ProcessMemory* mem, std::uintptr_t instruction_ptr, int offset = 3, int size = 7 ) -{ - return instruction_ptr + ( mem->Read( instruction_ptr + offset ).result( ) ) + size; -} + return memory->Read(VMTAddr + idx * 8).result(); + } -class CDOTA_ParticleManager : public DefClass { -public: - CDOTA_ParticleManager( ) { - memory = nullptr; - baseAddr = NULL; - } - - CDOTA_ParticleManager( blackbone::ProcessMemory* memory, std::uintptr_t baseAddr ) { - this->memory = memory; - this->baseAddr = baseAddr; - } - - class NewParticleEffect : DefClass { - public: - NewParticleEffect( ) { - memory = nullptr; - baseAddr = NULL; - } - NewParticleEffect( blackbone::ProcessMemory* memory, std::uintptr_t baseAddr ) { - this->memory = memory; - this->baseAddr = baseAddr; - } - DefClass GetParticleCollection( ) { - auto partCollection = memory->Read( baseAddr + 0x20 ).result( ); - auto res = DefClass( memory, partCollection ); - if ( !baseAddr || !partCollection ) return DefClass( 0, 0 ); - return res; - } - }; - - class ParticleListItem : public DefClass { - public: - ParticleListItem( ) { - memory = nullptr; - baseAddr = NULL; - } - ParticleListItem( blackbone::ProcessMemory* memory, std::uintptr_t baseAddr ) { - this->memory = memory; - this->baseAddr = baseAddr; - } - CDOTA_ParticleManager::NewParticleEffect GetNewParticleEffect( ) { - auto newPartEffect = memory->Read( baseAddr + 0x10 ).result( ); - if ( !newPartEffect || !baseAddr ) return CDOTA_ParticleManager::NewParticleEffect( 0, 0 ); - return CDOTA_ParticleManager::NewParticleEffect( memory, newPartEffect ); - } - }; - - - std::vector GetParticleLists( ) { - std::vector list; - auto particlesBase = memory->Read( baseAddr + 0x88 ).result( ); - const auto pCount = this->GetParticleCount( ) * 8; - for ( int idx = 0x0; idx < pCount; idx += 0x8 ) { - CDOTA_ParticleManager::ParticleListItem thisEffect( memory, memory->Read( particlesBase + idx ).result( ) ); - list.push_back( thisEffect ); - } - - return list; - } - - int GetParticleCount( ) { - return memory->Read( baseAddr + 0x80 ).result( ); - } + bool IsValid() { return (memory && baseAddr) ? true : false; } }; +std::uintptr_t GetAbsoluteAddress(blackbone::ProcessMemory *mem, + std::uintptr_t instruction_ptr, + int offset = 3, int size = 7) { + return instruction_ptr + + (mem->Read(instruction_ptr + offset).result()) + size; +} + class CDOTA_Camera : public DefClass { -public: - CDOTA_Camera( ) { - memory = nullptr; - baseAddr = NULL; - } - - CDOTA_Camera( blackbone::ProcessMemory* memory, std::uintptr_t baseAddr ) { - this->memory = memory; - this->baseAddr = baseAddr; - } - - void SetDistance( float distance ) noexcept { - static bool first = true; - if (first) { - constexpr const char* bytes = "\xF3\x0F\x10\xBF\x5C\x01\x00\x00"; // movss xmm7, dword ptr [rdi+15C] - std::vector search_result; - blackbone::PatternSearch patch_pattern{ "\xF3\x0F\x11\xBF\xCC\xCC\xCC\xCC\x0F\x2F\xB7" }; - patch_pattern.SearchRemote(*memory->process(), 0xCC, memory->process()->modules().GetModule(L"client.dll").get()->baseAddress, memory->process()->modules().GetModule(L"client.dll").get()->size, search_result, 1); - if (!search_result.empty()) { - memory->Write(search_result.front(), 8, bytes); - } - else { - std::cout << "instruction already patched or pattern is outdated\n"; - } - - first = false; - } - - memory->Write( baseAddr + 0x015c, distance ); - } - - void SetFOWAmount( float amount ) // 0x70 - { - memory->Write( baseAddr + 0x70, amount ); - } - - auto GetDistance( ) noexcept { - return memory->Read( baseAddr + 0x270 ).result( ); - } - - auto GetFOWAmount( ) - { - return memory->Read( baseAddr + 0x70 ).result( ); - } - - void ToggleFog( ) { - const auto aGetFog = this->GetVF( 18 ); - const auto instructionBytes = memory->Read( aGetFog ).result( ); - - if ( instructionBytes == 0x83485708245c8948 ) { // not patched - - // 0x0F, 0x57, 0xC0 | xorps xmm0, xmm0 - // 0xC3 | ret - constexpr const char* bytePatch = "\x0F\x57\xC0\xC3"; - memory->Write( aGetFog, 4, bytePatch ); - // std::cout << "Fog instructions patched" << std::endl; - } - else if ( instructionBytes == 0x83485708c3c0570f ) { // already patched - - // 0x48, 0x89, 0x5C, 0x24, 0x08 | mov qword ptr ss:[rsp+8], rbx - // 0x57 | push rdi - constexpr const char* byteRestore = "\x48\x89\x5C\x24\x08\x57"; - memory->Write( aGetFog, 6, byteRestore ); - // std::cout << "Fog instructions restored" << std::endl; - } - else { - std::cout << "Error, unknown fog instructions: " << instructionBytes << std::endl; - std::system( "pause" ); - exit( 1 ); - } - } - - void ToggleMaxZFar( ) { - const auto aGetZFar = this->GetVF( 19 ); - const auto instructionBytes = memory->Read( aGetZFar ).result( ); - - if ( instructionBytes == 0x83485708245c8948 ) { // not patched - - // 0xB8, 0x50, 0x46, 0x00, 0x00 | mov eax, 18000 - // 0xF3, 0x0F, 0x2A, 0xC0 | cvtsi2ss xmm0, eax - // 0xC3 | ret - constexpr const char* bytePatch = "\xB8\x50\x46\x00\x00\xF3\x0F\x2A\xC0\xC3"; - memory->Write( aGetZFar, 10, bytePatch ); - //std::cout << "ZFar instructions patched" << std::endl; - } - else if ( instructionBytes == 0x2a0ff300004650b8 ) { // already patched - - // 0x48, 0x89, 0x5C, 0x24, 0x08 | mov qword ptr ss:[rsp+8], rbx - // 0x57 | push rdi - // 0x48, 0x83, 0xEC, 0x40 | sub rsp, 40 - constexpr const char* byteRestore = "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x40"; - memory->Write( aGetZFar, 10, byteRestore ); - //std::cout << "ZFar instructions restored" << std::endl; - } - } + public: + CDOTA_Camera() { + memory = nullptr; + baseAddr = NULL; + } + + CDOTA_Camera(blackbone::ProcessMemory *memory, std::uintptr_t baseAddr) { + this->memory = memory; + this->baseAddr = baseAddr; + } + + void SetDistance(float distance) { + memory->Write(baseAddr + 0x2e4, distance); + } + + void SetFOWAmount(float amount) { + memory->Write(baseAddr + 0x70, amount); + } + + auto GetDistance() { + return memory->Read(baseAddr + 0x270).result(); + } + + auto GetFOWAmount() { + return memory->Read(baseAddr + 0x70).result(); + } + + void ToggleFog() { + const auto aGetFog = this->GetVF(18); + const auto instructionBytes = memory->Read(aGetFog).result(); + + if (instructionBytes == 0x83485708245c8948) { // not patched + + // 0x0F, 0x57, 0xC0 | xorps xmm0, xmm0 + // 0xC3 | ret + constexpr const char *bytePatch = "\x0F\x57\xC0\xC3"; + memory->Write(aGetFog, 4, bytePatch); + // std::cout << "Fog instructions patched" << std::endl; + } else if (instructionBytes == 0x83485708c3c0570f) { // already patched + + // 0x48, 0x89, 0x5C, 0x24, 0x08 | mov qword ptr ss:[rsp+8], rbx + // 0x57 | push rdi + constexpr const char *byteRestore = "\x48\x89\x5C\x24\x08\x57"; + memory->Write(aGetFog, 6, byteRestore); + // std::cout << "Fog instructions restored" << std::endl; + } else { + std::cout << "Error, unknown fog instructions: " << instructionBytes + << std::endl; + std::system("pause"); + exit(1); + } + } + + void ToggleMaxZFar() { + const auto aGetZFar = this->GetVF(19); + const auto instructionBytes = + memory->Read(aGetZFar).result(); + + if (instructionBytes == 0x83485708245c8948) { // not patched + + // 0xB8, 0x50, 0x46, 0x00, 0x00 | mov eax, 18000 + // 0xF3, 0x0F, 0x2A, 0xC0 | cvtsi2ss xmm0, eax + // 0xC3 | ret + constexpr const char *bytePatch = + "\xB8\x50\x46\x00\x00\xF3\x0F\x2A\xC0\xC3"; + memory->Write(aGetZFar, 10, bytePatch); + // std::cout << "ZFar instructions patched" << std::endl; + } else if (instructionBytes == 0x2a0ff300004650b8) { // already patched + + // 0x48, 0x89, 0x5C, 0x24, 0x08 | mov qword ptr ss:[rsp+8], rbx + // 0x57 | push rdi + // 0x48, 0x83, 0xEC, 0x40 | sub rsp, 40 + constexpr const char *byteRestore = + "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x40"; + memory->Write(aGetZFar, 10, byteRestore); + // std::cout << "ZFar instructions restored" << std::endl; + } + } }; -CDOTA_Camera FindCamera( blackbone::Process& proc ) { - std::vector search_result; - blackbone::PatternSearch aDOTACameraInit_Pattern{ "\x48\x83\xEC\x38\xE8\xCC\xCC\xCC\xCC\x48\x85\xC0\x74\x4D" }; - aDOTACameraInit_Pattern.SearchRemote( proc, 0xCC, proc.modules( ).GetModule( L"client.dll" ).get( )->baseAddress, proc.modules( ).GetModule( L"client.dll" ).get( )->size, search_result, 1 ); - blackbone::RemoteFunction pFN( proc, search_result.front( ) ); - - if ( auto result = pFN.Call( ); result.success( ) && result.result( ) ) { - return CDOTA_Camera{ &proc.memory( ), result.result( ) }; - } - - return CDOTA_Camera{ nullptr, 0 }; -} +CDOTA_Camera FindCamera(blackbone::Process &proc) { + // std::vector search_result; + // typedef std::uintptr_t( __fastcall* CDOTACamera__Init )( ); + // blackbone::PatternSearch aDOTACameraInit_Pattern{ + // "\x48\x83\xEC\x38\xE8\xCC\xCC\xCC\xCC\x48\x85\xC0\x74\x4D" }; + // aDOTACameraInit_Pattern.SearchRemote( proc, 0xCC, proc.modules( + // ).GetModule( L"client.dll" ).get( )->baseAddress, proc.modules( + // ).GetModule( L"client.dll" ).get( )->size, search_result, 1 ); + // blackbone::RemoteFunction pFN( proc, + // search_result.front( ) ); + + // if ( auto result = pFN.Call( ); result.success( ) && result.result( ) ) { + // return CDOTA_Camera{ &proc.memory( ), result.result( ) }; + // } + + // return CDOTA_Camera{ nullptr, 0 }; + + static std::vector search_result; + static bool first_use = true; + if (first_use) { + blackbone::PatternSearch g_pDOTACameraManager_pattern{ + "\x48\x8d\x3d\xcc\xcc\xcc\xcc\x48\x8b\x14\xc8"}; + g_pDOTACameraManager_pattern.SearchRemote( + proc, 0xCC, + proc.modules().GetModule(L"client.dll").get()->baseAddress, + proc.modules().GetModule(L"client.dll").get()->size, search_result, + 1); + first_use = false; + } + + if (search_result.empty()) { + std::cout << "cant find dota camera\n"; + getchar(); + exit(1); + } + + if (std::uintptr_t g_pDOTACameraManager = + GetAbsoluteAddress(&proc.memory(), search_result.front()); + g_pDOTACameraManager) { + auto dotaCamera = + proc.memory().Read(g_pDOTACameraManager + 0x20); + + if (dotaCamera.success() && dotaCamera.result()) + return CDOTA_Camera{&proc.memory(), dotaCamera.result()}; + } + + return CDOTA_Camera{nullptr, 0}; +} \ No newline at end of file diff --git a/core/main.cpp b/core/main.cpp index e188c11..6bc1826 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -1,59 +1,149 @@ #include "dota_sdk.hpp" -[[nodiscard]] inline int req_action( byte w ) { - if ( w == 0 ) { - int act1; - - std::cout << "=================================\n[0] Change camera distance\n[1] Patch ZFar\n[2] Toggle Fog\n=> "; - std::cin >> act1; - return act1; - } - else { - int dist; - std::system( "cls" ); - std::cout << "=> "; - std::cin >> dist; - - return dist; - } +[[nodiscard]] inline int req_action(byte w) { + if (w == 0) { + int act1; + + std::cout << "[!] - patches .text section\n============================\n[1] Change camera " + "distance\n[2] " + "Patch ZFar [!]\n[3] Toggle Fog [!]\n[4] Toggle mana bars [!]\n[5] Toggle particles [!]\n=> "; + std::cin >> act1; + return act1; + } else { + int dist; + std::system("cls"); + std::cout << "=> "; + std::cin >> dist; + + return dist; + } } -void process( blackbone::Process& dota_proc, blackbone::ProcessMemory& pDOTAMemory ) { - std::cout << "PID: " << std::dec << dota_proc.pid( ) << std::endl << "client.dll base: " << (void*)dota_proc.modules( ).GetModule( L"client.dll" ).get( )->baseAddress << std::endl; - - auto DOTACamera = FindCamera( dota_proc ); - - if ( DOTACamera.IsValid( ) ) { - const auto act = req_action( 0 ); - - switch ( act ) - { - case 0: - DOTACamera.SetDistance( req_action( 1 ) ); - break; - case 1: - DOTACamera.ToggleMaxZFar( ); - break; - case 2: - DOTACamera.ToggleFog( ); - break; - default: - exit( 0 ); - } - } - std::system( "cls" ); +void process(blackbone::Process &dota_proc, + blackbone::ProcessMemory &pDOTAMemory) { + static const auto client_module = + dota_proc.modules().GetModule(L"client.dll").get()->baseAddress; + static const auto client_size = + dota_proc.modules().GetModule(L"client.dll").get()->size; + + std::cout << "PID: " << std::dec << dota_proc.pid() << std::endl + << "client.dll base: " << (void *)client_module << std::endl; + + auto DOTACamera = FindCamera(dota_proc); + + // EB, 0E | jmp client.7FF9A7BBCFFA + constexpr const char *bytePatch = "\xEB\x0E"; + // 75, 0E | jne client.7FF9A7BBCFFA + constexpr const char *byteRestore = "\x75\x0E"; + + static uint64_t manabar_addr = 0; + static uint64_t particles_addr = 0; + uint64_t insn_bytes = 0, insn_bytes2 = 0; + + static bool first = true; + if (first) { + // 75 cc c6 44 24 cc cc eb cc 48 8d 9e + blackbone::PatternSearch jmp_insn_manabar{ + "\x75\xcc\xc6\x44\x24\xcc\xcc\xeb\xcc\x48\x8d\x9e"}, + jmp_insn_manabar2{ + "\xeb\xcc\xc6\x44\x24\xcc\xcc\xeb\xcc\x48\x8d\x9e"}; + std::vector search_result, search_result2; + + jmp_insn_manabar.SearchRemote(dota_proc, 0xCC, client_module, + client_size, search_result, 1); + jmp_insn_manabar2.SearchRemote(dota_proc, 0xCC, client_module, + client_size, search_result2, 1); + + if (!search_result.empty()) + manabar_addr = search_result.front(); + else if (!search_result2.empty()) + manabar_addr = search_result2.front(); + + search_result.clear(); + + blackbone::PatternSearch and_al_01{"\x4C\x8B\xDC\x55\x56\x41\x54"}; + and_al_01.SearchRemote( + dota_proc, 0xCC, + dota_proc.modules().GetModule(L"particles.dll").get()->baseAddress, + dota_proc.modules().GetModule(L"particles.dll").get()->size, + search_result, 1); + + if (search_result.empty()) { + std::cout << "cant find particles pattern\n"; + getchar(); + exit(1); + } + + particles_addr = search_result.front() + 0x1a; + + first = false; + } + + if (DOTACamera.IsValid()) { + const auto act = req_action(0); + + switch (act) { + case 1: + DOTACamera.SetDistance(req_action(1)); + break; + case 2: + DOTACamera.ToggleMaxZFar(); + break; + case 3: + DOTACamera.ToggleFog(); + break; + case 4: + if (!manabar_addr) { + std::cout << "cant find manabar pattern\n"; + getchar(); + exit(1); + } + + insn_bytes = pDOTAMemory.Read(manabar_addr).result(); + if (insn_bytes == 0xeb00542444c60e75) { + pDOTAMemory.Write(manabar_addr, 2, bytePatch); + } else if (insn_bytes == 0xeb00542444c60eeb) { // restore + pDOTAMemory.Write(manabar_addr, 2, byteRestore); + } else { + std::cout << "[[unknown bytes at " << std::hex << manabar_addr + << '\n'; + getchar(); + exit(1); + } + + break; + case 5: + insn_bytes2 = pDOTAMemory.Read(particles_addr) + .result(); + if (insn_bytes2 == 0x0124) { + pDOTAMemory.Write(particles_addr, 2, "\xb2\x01"); + } else if (insn_bytes2 == 0x01b2) { + pDOTAMemory.Write(particles_addr, 2, "\x24\x01"); + } else { + std::cout << "[unknown bytes at " << std::hex << manabar_addr + << '\n'; + getchar(); + exit(1); + } + break; + default: + exit(1); + } + } + std::system("cls"); } -int main( ) { - blackbone::Process dota; - - if ( NT_SUCCESS( dota.Attach( L"dota2.exe" ) ) && dota.modules( ).GetModule( L"client.dll" ) ) { - std::cout << "Attached to dota2.exe " << std::endl; - while ( 1 ) process( dota, dota.memory( ) ); - } - else { - std::cout << "dota2.exe not found" << std::endl; - std::system( "pause" ); - exit( 1 ); - } +int main() { + blackbone::Process dota; + + if (NT_SUCCESS(dota.Attach(L"dota2.exe")) && + dota.modules().GetModule(L"client.dll")) { + std::cout << "Attached to dota2.exe " << std::endl; + while (1) + process(dota, dota.memory()); + } else { + std::cout << "dota2.exe not found or not client.dll" << std::endl; + std::system("pause"); + exit(1); + } }