aboutsummaryrefslogtreecommitdiff
path: root/source2-basehook/Utilities
diff options
context:
space:
mode:
authorjz0 <[email protected]>2020-05-03 22:38:59 +0300
committerjz0 <[email protected]>2020-05-03 22:38:59 +0300
commitfdb81a898151278a66af544dfae6bfcbbf9dc3d2 (patch)
tree8884fc5c21b3daf0a32cc145c4488b9e708deec4 /source2-basehook/Utilities
downloadarchived-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.cpp74
-rw-r--r--source2-basehook/Utilities/Utilities.hpp9
-rw-r--r--source2-basehook/Utilities/VMTHook.hpp67
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