From 1745fda62e30cc526d6e0110591009310b87c3de Mon Sep 17 00:00:00 2001
From: F0RQU1N <108815933+F0RQU1N@users.noreply.github.com>
Date: Sun, 9 Apr 2023 22:08:27 +1000
Subject: [PATCH] Add files via upload
---
camera_patch.vcxproj | 157 +++++++++++++++++++++++++++++++++++++++
core/dota_sdk.hpp | 172 +++++++++++++++++++++++++++++++++++++++++++
core/main.cpp | 86 ++++++++++++++++++++++
3 files changed, 415 insertions(+)
create mode 100644 camera_patch.vcxproj
create mode 100644 core/dota_sdk.hpp
create mode 100644 core/main.cpp
diff --git a/camera_patch.vcxproj b/camera_patch.vcxproj
new file mode 100644
index 0000000..0d3e485
--- /dev/null
+++ b/camera_patch.vcxproj
@@ -0,0 +1,157 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+
+
+
+
+ {a2c53563-46f5-4d87-903f-3f1f2fdb2deb}
+
+
+
+
+
+
+
+ 16.0
+ Win32Proj
+ {c15e6bb1-4a30-4d37-9b96-3fc80e58cd4b}
+ camerapatch
+ 10.0
+
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+ stdc17
+ $(ProjectDir)core\include;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ false
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+ stdc17
+ MultiThreaded
+ false
+ $(ProjectDir)core\include;%(AdditionalIncludeDirectories)
+ AnySuitable
+ Speed
+ true
+ true
+
+
+ Console
+ true
+ true
+ false
+ AsInvoker
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/dota_sdk.hpp b/core/dota_sdk.hpp
new file mode 100644
index 0000000..d7c9c45
--- /dev/null
+++ b/core/dota_sdk.hpp
@@ -0,0 +1,172 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+typedef std::uintptr_t( __fastcall* CDOTACamera__Init )( );
+typedef void( __fastcall* SetRenderingEnabled )( std::uintptr_t CParticleCollectionPtr, bool render );
+
+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( );
+ }
+};
+
+class CDOTA_ParticleManager : 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 : 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( );
+ }
+};
+
+class CDOTA_Camera : 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 { // 0x270
+ memory->Write( baseAddr + 0x270, 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;
+ }
+ }
+};
\ No newline at end of file
diff --git a/core/main.cpp b/core/main.cpp
new file mode 100644
index 0000000..722d92a
--- /dev/null
+++ b/core/main.cpp
@@ -0,0 +1,86 @@
+#include "dota_sdk.hpp"
+
+// bool showParticles = false;
+
+int main( )
+{
+ blackbone::Process dota;
+
+ if ( NT_SUCCESS( dota.Attach( L"dota2.exe" ) ) ) {
+ auto pClientModule = dota.modules( ).GetModule( L"client.dll" );
+ auto& pDOTAMemory = dota.memory( );
+
+ if ( pClientModule ) {
+ std::cout << "Attached to dota2.exe " << std::endl;
+ std::vector search_result;
+ blackbone::PatternSearch aDOTACameraInit_Pattern{ "\x48\x83\xEC\x38\xE8\xCC\xCC\xCC\xCC\x48\x85\xC0\x74\x4D" };
+ //blackbone::PatternSearch aDOTAParticleManager_Pattern{ xorstr_( "\xE8\xCC\xCC\xCC\xCC\x8B\x14\x9F" ) };
+
+ //aDOTAParticleManager_Pattern.SearchRemote( dota, 0xCC, pClientModule.get( )->baseAddress, pClientModule.get( )->size, search_result, 1 );
+ //search_result[0] = search_result[0] + ( pDOTAMemory.Read( search_result[0] + 1 ).result( ) + 5 );
+ //const auto pDOTAParticleManager = search_result[0] + ( pDOTAMemory.Read( search_result[0] + 3 ).result( ) + 7 );
+ //search_result.clear( );
+
+ while ( 1 ) {
+ std::cout << "PID: " << std::dec << dota.pid( ) << std::endl << "client.dll base: " << (void*)pClientModule.get( )->baseAddress << std::endl;
+ aDOTACameraInit_Pattern.SearchRemote( dota, 0xCC, pClientModule.get( )->baseAddress, pClientModule.get( )->size, search_result, 1 );
+ const auto aGetCamera = search_result[0];
+
+ if ( aGetCamera /* && pDOTAParticleManager */ ) {
+ std::cout << "=================================\n[0] Change camera distance\n[1] Patch ZFar\n[2] Toggle Fog\n=> ";
+ int act;
+ std::cin >> act;
+ blackbone::RemoteFunction pFN( dota, aGetCamera );
+ if ( auto result = pFN.Call( ); result.success( ) && result.result( ) ) {
+
+ CDOTA_Camera DOTACamera( &pDOTAMemory, result.result( ) );
+
+ if ( act == 0 ) {
+ float dist;
+ std::system( "cls" );
+ std::cout << "=> ";
+ std::cin >> dist;
+ DOTACamera.SetDistance( dist );
+ }
+ else if ( act == 1 ) {
+ DOTACamera.ToggleMaxZFar( );
+ }
+ else if ( act == 2 ) {
+ DOTACamera.ToggleFog( );
+ }
+ /*else if ( act == 3 ) {
+ showParticles = !showParticles;
+ auto addr = pDOTAMemory.Read( pDOTAParticleManager ).result( );
+ CDOTA_ParticleManager ParticleManager( &pDOTAMemory, addr );
+
+ std::cout << addr << std::endl;;
+ auto particlesList = ParticleManager.GetParticleLists( );
+ for ( auto& particle : particlesList ) {
+ if ( auto particleCollection = particle.GetNewParticleEffect( ).GetParticleCollection( ); particleCollection.baseAddr ) {
+ blackbone::RemoteFunction pFNRendering( dota, particle.GetNewParticleEffect( ).GetParticleCollection( ).GetVF( 95 ) );
+ pFNRendering.Call( particleCollection.baseAddr, true );
+ }
+ }
+
+ }
+ else if ( act == 4 ) {
+ exit( 0 );
+ }*/
+ else exit( 0 );
+ }
+ else {
+ std::cout << "CDOTACamera or SetRenderingEnabled not found" << std::endl;
+ std::system( "pause" );
+ exit( 1 );
+ }
+ }
+ std::system( "cls" );
+ }
+ }
+ }
+ else {
+ std::cout << "dota2.exe not found" << std::endl;
+ std::system( "pause" );
+ exit( 1 );
+ }
+}
\ No newline at end of file