Skip to content

Commit

Permalink
CreateInterface + More std::optional
Browse files Browse the repository at this point in the history
Fully rebuilded CreateInterface function from Dota.
Now we can easily get CSource2Client, CEngineClient and other usefull interfaces.
+ More std::optional (love it alot).
+ Every SourceSDK-related (reversed) files moved into SourceSDK folder.
  • Loading branch information
Wolf49406 committed Jan 12, 2025
1 parent 497573e commit 63be27b
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 87 deletions.
17 changes: 9 additions & 8 deletions Dota2Patcher.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include "Dota2Patcher.h"
#include "ProcessHandle.h"
#include "Memory.h"
#include "CDOTACamera.h"
#include "CDOTAGamerules.h"
#include "Config.h"
#include "SourceSDK/CDOTACamera.h"
#include "SourceSDK/CDOTAGamerules.h"
#include "SourceSDK/CreateInterface.h"

std::vector<Patches::PatchInfo> Patches::patches;

Expand Down Expand Up @@ -61,7 +62,7 @@ int main() {

// FIND GAMERULES

if (!CDOTAGamerules::find_gamerules(Memory::loaded_modules["client.dll"])) {
if (!CDOTAGamerules::find_gamerules()) {
printf("[-] Can't find C_DOTAGamerules_Proxy!\n");
ProcessHandle::close_process_handle();
std::cin.get();
Expand All @@ -74,7 +75,7 @@ int main() {

// CAMERA HACK

if (!CDOTACamera::find_camera(Memory::loaded_modules["client.dll"])) {
if (!CDOTACamera::find_camera()) {
printf("[-] Can't find CDOTACamera! Use ConVars instead...\n");
}
else {
Expand Down Expand Up @@ -115,15 +116,15 @@ int main() {
}

for (const auto& patch : Patches::patches) {
uintptr_t patch_addr = Memory::pattern_scan(Memory::loaded_modules[patch.module], patch.pattern);
if (patch_addr == -1) {
const auto patch_addr = Memory::pattern_scan(patch.module, patch.pattern);
if (!patch_addr) {
printf("[!] Pattern for \"%s\" not found!\n", patch.name.c_str());
continue;
}

printf("[+] \"%s\" patch addr: %p\n", patch.name.c_str(), (void*)patch_addr);
printf("[+] \"%s\" patch addr: %p\n", patch.name.c_str(), (void*)patch_addr.value());

if (!Memory::patch(patch_addr + patch.offset, patch.patch_bytes)) {
if (!Memory::patch(patch_addr.value() + patch.offset, patch.patch_bytes)) {
printf("[-] Failed to patch \"%s\"!\n", patch.name.c_str());
continue;
}
Expand Down
5 changes: 3 additions & 2 deletions Dota2Patcher.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -95,19 +95,20 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="CDOTACamera.h" />
<ClCompile Include="Dota2Patcher.cpp" />
<ClCompile Include="md5.cpp" />
<ClCompile Include="Memory.cpp" />
<ClCompile Include="Updater.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="CDOTAGamerules.h" />
<ClInclude Include="Config.h" />
<ClInclude Include="Dota2Patcher.h" />
<ClInclude Include="md5.h" />
<ClInclude Include="Memory.h" />
<ClInclude Include="ProcessHandle.h" />
<ClInclude Include="SourceSDK\CDOTACamera.h" />
<ClInclude Include="SourceSDK\CDOTAGamerules.h" />
<ClInclude Include="SourceSDK\CreateInterface.h" />
</ItemGroup>
<ItemGroup>
<Text Include="MD5" />
Expand Down
18 changes: 12 additions & 6 deletions Dota2Patcher.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
<Filter Include="Source files\Updater">
<UniqueIdentifier>{12e332a8-c4d7-48a5-ac54-91b0129ce702}</UniqueIdentifier>
</Filter>
<Filter Include="Headers\SourceSDK">
<UniqueIdentifier>{d8a6ef08-9da6-4257-8c7d-67e1c527b1e9}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Dota2Patcher.cpp">
Expand All @@ -26,9 +29,6 @@
<ClCompile Include="md5.cpp">
<Filter>Source files\Updater</Filter>
</ClCompile>
<ClCompile Include="CDOTACamera.h">
<Filter>Headers</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Dota2Patcher.h">
Expand All @@ -43,12 +43,18 @@
<ClInclude Include="md5.h">
<Filter>Source files\Updater</Filter>
</ClInclude>
<ClInclude Include="CDOTAGamerules.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="Config.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="SourceSDK\CDOTACamera.h">
<Filter>Headers\SourceSDK</Filter>
</ClInclude>
<ClInclude Include="SourceSDK\CDOTAGamerules.h">
<Filter>Headers\SourceSDK</Filter>
</ClInclude>
<ClInclude Include="SourceSDK\CreateInterface.h">
<Filter>Headers\SourceSDK</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="MD5">
Expand Down
39 changes: 8 additions & 31 deletions Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ static std::string wchar_to_string(const WCHAR* wcharStr) {
#define getBit(x) (InRange((x & (~0x20)), 'A', 'F') ? ((x & (~0x20)) - 'A' + 0xA): (InRange(x, '0', '9') ? x - '0': 0))
#define getByte(x) (getBit(x[0]) << 4 | getBit(x[1]))

uintptr_t Memory::pattern_scan(const ModuleInfo target_module, const std::string target_pattern) {
auto* buffer = new unsigned char[target_module.region_size];
std::optional<uintptr_t> Memory::pattern_scan(const std::string target_module, const std::string target_pattern) {
auto* buffer = new unsigned char[Memory::loaded_modules[target_module].region_size];
SIZE_T bytesRead;

if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(target_module.start_address), buffer, target_module.region_size, &bytesRead)) {
if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(Memory::loaded_modules[target_module].start_address), buffer, Memory::loaded_modules[target_module].region_size, &bytesRead)) {
printf("[-] (PatternScan) ReadProcessMemory failed: 0x%d\n", GetLastError());
delete[] buffer;
return NULL;
return std::nullopt;
}

const char* pattern = target_pattern.c_str();
Expand All @@ -50,7 +50,7 @@ uintptr_t Memory::pattern_scan(const ModuleInfo target_module, const std::string
for (uintptr_t i = 0; i < bytesRead; ++i) {
if (!*pattern) {
delete[] buffer;
return target_module.start_address + first_match;
return Memory::loaded_modules[target_module].start_address + first_match;
}

// Retarder visual studio
Expand All @@ -67,7 +67,7 @@ uintptr_t Memory::pattern_scan(const ModuleInfo target_module, const std::string

if (!pattern[2]) {
delete[] buffer;
return target_module.start_address + first_match;
return Memory::loaded_modules[target_module].start_address + first_match;
}

pattern += pattern_current != '\?' ? 3 : 2;
Expand All @@ -79,7 +79,7 @@ uintptr_t Memory::pattern_scan(const ModuleInfo target_module, const std::string
}

delete[] buffer;
return -1;
return std::nullopt;
}

bool Memory::load_modules() {
Expand All @@ -101,6 +101,7 @@ bool Memory::load_modules() {
info.start_address = reinterpret_cast<uintptr_t>(module_entry.modBaseAddr);
info.end_address = info.start_address + module_entry.modBaseSize;
info.region_size = info.end_address - info.start_address;
info.hmodule = module_entry.hModule;
modules[wchar_to_string(module_entry.szModule)] = info;
} while (Module32Next(snapshot, &module_entry));
}
Expand Down Expand Up @@ -141,27 +142,3 @@ bool Memory::patch(const uintptr_t patch_addr, const std::string& replace_str) {

return true;
}

uintptr_t Memory::absolute_address(uintptr_t instruction_ptr, ptrdiff_t offset, std::optional<uint32_t> size) {
int32_t relative_offset = 0;

if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(instruction_ptr + offset), &relative_offset, sizeof(relative_offset), nullptr)) {
printf("[-] (absolute_address) ReadProcessMemory failed: 0x%d\n", GetLastError());
return -1;
}

uintptr_t absolute_address = instruction_ptr + relative_offset + size.value_or(offset + sizeof(int32_t));

return absolute_address;
}

uintptr_t Memory::get_pointer(uintptr_t base_address, uintptr_t offset) {
uintptr_t instance_address = 0;

if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(base_address + offset), &instance_address, sizeof(instance_address), nullptr)) {
printf("[-] (get_pointer) ReadProcessMemory failed: 0x%d\n", GetLastError());
return -1;
}

return instance_address;
}
64 changes: 50 additions & 14 deletions Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <string>
#include <unordered_map>
#include <optional>
#include <cstdint>
#include <type_traits>
#include "ProcessHandle.h"

class Memory {
Expand All @@ -12,14 +14,54 @@ class Memory {
uintptr_t start_address;
uintptr_t end_address;
size_t region_size;
HMODULE hmodule;
};

static bool load_modules();
static uintptr_t pattern_scan(const ModuleInfo target_module, const std::string target_pattern);
static std::optional<uintptr_t> pattern_scan(const std::string target_module, const std::string target_pattern);
static bool patch(const uintptr_t patch_addr, const std::string& replace_str);
static uintptr_t absolute_address(uintptr_t instruction_ptr, ptrdiff_t offset, std::optional<uint32_t> size);
static uintptr_t get_pointer(uintptr_t base_address, uintptr_t offset);


template<typename T, typename N>
static std::optional<T> absolute_address(N instruction_ptr, ptrdiff_t offset, std::optional<uint32_t> size) {
uintptr_t address = 0;

if constexpr (std::is_pointer_v<N>) {
address = reinterpret_cast<uintptr_t>(instruction_ptr);
}
else if constexpr (std::is_integral_v<N>) {
address = static_cast<uintptr_t>(instruction_ptr);
}

int32_t relative_offset = 0;

if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(address + offset), &relative_offset, sizeof(relative_offset), nullptr)) {
printf("[-] (absolute_address) ReadProcessMemory failed: 0x%d\n", GetLastError());
return std::nullopt;
}

uintptr_t absolute_address = address + relative_offset + size.value_or(offset + sizeof(int32_t));

return absolute_address;
}

template<typename T, typename N>
static std::optional<T> read_memory(N address) {
T value{};
SIZE_T bytesRead;

if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(address), &value, sizeof(T), &bytesRead)) {
printf("[-] Failed to read memory: 0x%X\n", GetLastError());
return std::nullopt;
}

if (bytesRead != sizeof(T)) {
printf("[-] Partial read at 0x%p\n", (void*)address);
return std::nullopt;
}

return value;
}

template<typename T>
static bool write_memory(uintptr_t address, const T& value) {
SIZE_T bytesWritten;
Expand All @@ -37,20 +79,14 @@ class Memory {
}

template<typename T>
static std::optional<T> read_memory(uintptr_t address) {
T value{};
static std::optional<std::string> read_string(const T address, size_t maxLength = 512) {
std::vector<char> buffer(maxLength, 0);
SIZE_T bytesRead;
if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(address), &value, sizeof(T), &bytesRead)) {
printf("[-] Failed to read memory at 0x%llX: 0x%X\n", address, GetLastError());
return std::nullopt;
}

if (bytesRead != sizeof(T)) {
printf("[-] Partial read at 0x%llX\n", address);
if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(static_cast<uintptr_t>(address)), buffer.data(), buffer.size(), &bytesRead) && bytesRead == buffer.size())
return std::nullopt;
}

return value;
return std::string(buffer.data());
}

static std::unordered_map<std::string, ModuleInfo> loaded_modules;
Expand Down
22 changes: 10 additions & 12 deletions CDOTACamera.h → SourceSDK/CDOTACamera.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once
#include "Dota2Patcher.h"
#include "Memory.h"
#include "../Dota2Patcher.h"
#include "../Memory.h"

// CDOTA_Camera 21 vfunc
//
Expand All @@ -12,8 +12,6 @@

class CDOTACamera {
public:
CDOTACamera() = default;

static void set_distance(float distance) {
Memory::write_memory(camera_base_, distance);
}
Expand All @@ -26,7 +24,7 @@ class CDOTACamera {
Memory::write_memory(camera_base_ + 0x14, r_farz);
}

static bool find_camera(const Memory::ModuleInfo& module) {
static bool find_camera() {
// mov edx, cs:TlsIndex
// mov rax, gs:58h
// mov ecx, 40h ; '@'
Expand All @@ -39,19 +37,19 @@ class CDOTACamera {
// pop rbx
// retn

const uintptr_t base = Memory::pattern_scan(module, Patches::Patterns::CDOTACamera);
if (base == -1)
const auto base = Memory::pattern_scan("client.dll", Patches::Patterns::CDOTACamera);
if (!base)
return false;

const uintptr_t camera_base_address = Memory::absolute_address(base, 3, 7);
if (camera_base_address == -1)
const auto camera_base_address = Memory::absolute_address<uintptr_t>(base.value(), 3, 7);
if (!camera_base_address)
return false;

printf("[+] CDOTA_Camera: %p\n", (void*)camera_base_address);
camera_base_ = camera_base_address;
printf("[+] CDOTA_Camera: %p\n", reinterpret_cast<void*>(camera_base_address.value()));
camera_base_ = camera_base_address.value();
return true;
}

private:
static inline uintptr_t camera_base_ = static_cast<uintptr_t>(-1);
static inline uintptr_t camera_base_;
};
Loading

0 comments on commit 63be27b

Please sign in to comment.