diff options
| author | jz0 <[email protected]> | 2020-05-03 22:38:59 +0300 |
|---|---|---|
| committer | jz0 <[email protected]> | 2020-05-03 22:38:59 +0300 |
| commit | fdb81a898151278a66af544dfae6bfcbbf9dc3d2 (patch) | |
| tree | 8884fc5c21b3daf0a32cc145c4488b9e708deec4 /source2-basehook/Utilities | |
| download | archived-source2-basehook-fdb81a898151278a66af544dfae6bfcbbf9dc3d2.tar.xz archived-source2-basehook-fdb81a898151278a66af544dfae6bfcbbf9dc3d2.zip | |
Initial commit
Diffstat (limited to 'source2-basehook/Utilities')
| -rw-r--r-- | source2-basehook/Utilities/Utilities.cpp | 74 | ||||
| -rw-r--r-- | source2-basehook/Utilities/Utilities.hpp | 9 | ||||
| -rw-r--r-- | source2-basehook/Utilities/VMTHook.hpp | 67 |
3 files changed, 150 insertions, 0 deletions
diff --git a/source2-basehook/Utilities/Utilities.cpp b/source2-basehook/Utilities/Utilities.cpp new file mode 100644 index 0000000..ea64909 --- /dev/null +++ b/source2-basehook/Utilities/Utilities.cpp @@ -0,0 +1,74 @@ +#include "Utilities.hpp" + +uintptr_t Utilities::FindPattern(const char* Module, const char* Sig) +{ +#define IN_RANGE(x, a, b) (x >= a && x <= b) +#define GET_BITS(x) (IN_RANGE((x & (~0x20)), 'A', 'F') ? ((x & (~0x20)) - 'A' + 0xA): (IN_RANGE(x, '0', '9') ? x - '0': 0)) +#define GET_BYTE(x) (GET_BITS(x[0]) << 4 | GET_BITS(x[1])) + + const auto ModuleHandle = GetModuleHandleA(Module); + const auto DOSHeader = PIMAGE_DOS_HEADER(ModuleHandle); + const auto NTHeaders = PIMAGE_NT_HEADERS(reinterpret_cast<std::uint8_t*>(ModuleHandle) + DOSHeader->e_lfanew); + + uintptr_t StartAddress = (uintptr_t)GetModuleHandleA(Module); + uintptr_t Size = (StartAddress + (uintptr_t)NTHeaders->OptionalHeader.SizeOfImage); + + const char* Pat = Sig; + uintptr_t FirstMatch = 0; + for (uintptr_t pCur = StartAddress; pCur < Size; pCur++) + { + if (!*Pat) return FirstMatch; + if (*(PBYTE)Pat == ('\?') || *(BYTE*)pCur == GET_BYTE(Pat)) + { + if (!FirstMatch) FirstMatch = pCur; + if (!Pat[2]) return FirstMatch; + if (*(PWORD)Pat == ('\?\?') || *(PBYTE)Pat != ('\?')) Pat += 3; + else Pat += 2; + } + else + { + Pat = Sig; + FirstMatch = 0; + } + } + return NULL; +} + +uintptr_t Utilities::Dereference(uintptr_t Address, unsigned int Offset) +{ + if (Address == 0) + return 0; + + if (sizeof(uintptr_t) == 8) + return Address + (int)((*(int*)(Address + Offset) + Offset) + sizeof(int)); + + return (uintptr_t) * (unsigned long*)(Address + Offset); +} + +void Utilities::DumpNetVars() +{ + FILE* FileHandle; + FileHandle = fopen("G:\\NetVar_Dump.txt", "w"); + + for (ClientClass* ClientClasses = pClient->GetAllClasses(); ClientClasses; ClientClasses = ClientClasses->m_pNext) + { + if (!ClientClasses->RecvTable || !ClientClasses->RecvTable->NetvarsArray || !ClientClasses->m_pClassName) + continue; + + Msg(Color(151, 173, 209, 255), "%s : [%d] \n", ClientClasses->m_pClassName, ClientClasses->RecvTable->NumOfNetvars); + fprintf(FileHandle, "%s : [%d] \n", ClientClasses->m_pClassName, ClientClasses->RecvTable->NumOfNetvars); + + for (int i = 0; i < ClientClasses->RecvTable->NumOfNetvars; i++) + { + Netvar* Var = ClientClasses->RecvTable->NetvarsArray[i].Netvar; + + if (!Var || !Var->NetvarName || !Var->TypeName || !Var->Offset) + break; + + Msg(Color(91, 141, 222, 255), "\t[%d] %s -> 0x%x [%s] \n", i + 1, Var->NetvarName, Var->Offset, Var->TypeName); + fprintf(FileHandle, "\t[%d] %s -> 0x%x [%s] \n", i + 1, Var->NetvarName, Var->Offset, Var->TypeName); + } + } + + fclose(FileHandle); +}
\ No newline at end of file diff --git a/source2-basehook/Utilities/Utilities.hpp b/source2-basehook/Utilities/Utilities.hpp new file mode 100644 index 0000000..b94ba98 --- /dev/null +++ b/source2-basehook/Utilities/Utilities.hpp @@ -0,0 +1,9 @@ +#pragma once +#include "../Include.hpp" + +namespace Utilities +{ + uintptr_t FindPattern(const char* module, const char* sig); + uintptr_t Dereference(uintptr_t address, unsigned int offset); + void DumpNetVars(); +}
\ No newline at end of file diff --git a/source2-basehook/Utilities/VMTHook.hpp b/source2-basehook/Utilities/VMTHook.hpp new file mode 100644 index 0000000..b25b2af --- /dev/null +++ b/source2-basehook/Utilities/VMTHook.hpp @@ -0,0 +1,67 @@ +#pragma once +#include "../Include.hpp" + +class VMTHook +{ +public: + explicit VMTHook(void* ptr) + { + if (!ptr) + return; + + pClass = reinterpret_cast<uintptr_t**>(ptr); + pOriginalVMT = *pClass; + + const auto Size = Length(); + pHookedVMT = std::make_unique<uint64_t[]>(Size + 1); + + memcpy(&pHookedVMT.get()[1], pOriginalVMT, Size * sizeof uint64_t); + + pHookedVMT.get()[0] = static_cast<uintptr_t>(pOriginalVMT[-1]); + + PatchPtr(pHookedVMT.get()); + } + + ~VMTHook() + { + PatchPtr(pOriginalVMT); + } + + template<typename Function, typename Original> + Function HookFunction(uint64_t Index, Original _Function) + { + auto Old = pOriginalVMT[Index]; + pHookedVMT.get()[Index + 1] = reinterpret_cast<uintptr_t>(_Function); + return reinterpret_cast<Function>(Old); + } + +private: + + uint64_t Length() + { + uint64_t Index = 0; + const auto VMT = pOriginalVMT; + + for (Index = 0; VMT[Index]; Index++) + if (IS_INTRESOURCE(VMT[Index])) + break; + + return Index; + } + + void PatchPtr(uintptr_t* Replacement) + { + if (!pClass) + return; + + DWORD Old; + + VirtualProtect(pClass, sizeof uintptr_t, PAGE_READWRITE, &Old); + Replacement == pOriginalVMT ? *pClass = Replacement : *pClass = &Replacement[1]; + VirtualProtect(pClass, sizeof uintptr_t, Old, &Old); + } + + std::uintptr_t** pClass; + std::uintptr_t* pOriginalVMT; + std::unique_ptr<uint64_t[]> pHookedVMT; +};
\ No newline at end of file |