Skip to content

Commit

Permalink
rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
tranqu1lizer committed Mar 9, 2024
1 parent d32c55c commit 42223f6
Show file tree
Hide file tree
Showing 3 changed files with 294 additions and 258 deletions.
6 changes: 6 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Language: Cpp
BasedOnStyle: llvm
Standard: c++17
TabWidth: 4
IndentWidth: 4
UseTab: Never
352 changes: 146 additions & 206 deletions core/dota_sdk.hpp
Original file line number Diff line number Diff line change
@@ -1,223 +1,163 @@
#include <iostream>
#include <format>
#include <BlackBone/Asm/AsmFactory.h>
#include <BlackBone/Asm/AsmHelper64.h>
#include <BlackBone/Asm/IAsmHelper.h>
#include <BlackBone/Patterns/PatternSearch.h>
#include <BlackBone/Process/Process.h>
#include <BlackBone/Process/ProcessMemory.h>
#include <BlackBone/Process/RPC/RemoteHook.h>
#include <BlackBone/Process/RPC/RemoteFunction.hpp>
#include <BlackBone/Patterns/PatternSearch.h>
#include <BlackBone/Process/RPC/RemoteHook.h>
#include <format>
#include <iostream>

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<std::uintptr_t>( baseAddr ).result( );

return memory->Read<std::uintptr_t>( VMTAddr + idx * 8 ).result( );
}

bool IsValid( ) {
return ( memory && baseAddr ) ? true : false;
}
};
public:
blackbone::ProcessMemory *memory;
std::uintptr_t baseAddr;

template<typename T>
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<std::uintptr_t>(baseAddr).result();

blackbone::RemoteFunction<CreateInterface> pFN( *proc, aCreateInterface );
if ( const auto callResult = pFN.Call( interfacename, &iRetCode ); callResult.success( ) ) {
return reinterpret_cast<T>( 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<std::int32_t>( instruction_ptr + offset ).result( ) ) + size;
}
return memory->Read<std::uintptr_t>(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<std::uintptr_t>( 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<std::uintptr_t>( baseAddr + 0x10 ).result( );
if ( !newPartEffect || !baseAddr ) return CDOTA_ParticleManager::NewParticleEffect( 0, 0 );
return CDOTA_ParticleManager::NewParticleEffect( memory, newPartEffect );
}
};


std::vector<CDOTA_ParticleManager::ParticleListItem> GetParticleLists( ) {
std::vector<ParticleListItem> list;
auto particlesBase = memory->Read<std::uintptr_t>( baseAddr + 0x88 ).result( );
const auto pCount = this->GetParticleCount( ) * 8;
for ( int idx = 0x0; idx < pCount; idx += 0x8 ) {
CDOTA_ParticleManager::ParticleListItem thisEffect( memory, memory->Read<std::uintptr_t>( particlesBase + idx ).result( ) );
list.push_back( thisEffect );
}

return list;
}

int GetParticleCount( ) {
return memory->Read<int>( 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<std::int32_t>(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<blackbone::ptr_t> 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<float>( baseAddr + 0x015c, distance );
}

void SetFOWAmount( float amount ) // 0x70
{
memory->Write<float>( baseAddr + 0x70, amount );
}

auto GetDistance( ) noexcept {
return memory->Read<float>( baseAddr + 0x270 ).result( );
}

auto GetFOWAmount( )
{
return memory->Read<float>( baseAddr + 0x70 ).result( );
}

void ToggleFog( ) {
const auto aGetFog = this->GetVF( 18 );
const auto instructionBytes = memory->Read<uintptr_t>( 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<uintptr_t>( 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<float>(baseAddr + 0x2e4, distance);
}

void SetFOWAmount(float amount) {
memory->Write<float>(baseAddr + 0x70, amount);
}

auto GetDistance() {
return memory->Read<float>(baseAddr + 0x270).result();
}

auto GetFOWAmount() {
return memory->Read<float>(baseAddr + 0x70).result();
}

void ToggleFog() {
const auto aGetFog = this->GetVF(18);
const auto instructionBytes = memory->Read<uintptr_t>(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<uintptr_t>(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<blackbone::ptr_t> 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<CDOTACamera__Init> 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<blackbone::ptr_t> 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<CDOTACamera__Init> 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<blackbone::ptr_t> 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<std::uintptr_t>(g_pDOTACameraManager + 0x20);

if (dotaCamera.success() && dotaCamera.result())
return CDOTA_Camera{&proc.memory(), dotaCamera.result()};
}

return CDOTA_Camera{nullptr, 0};
}
Loading

0 comments on commit 42223f6

Please sign in to comment.