From 713c4b4627e31662ac3f46abb4a427664b6b5764 Mon Sep 17 00:00:00 2001 From: aixxe Date: Tue, 14 Mar 2017 19:13:53 +0000 Subject: [PATCH] Use alternative method for finding 's_pInterfaceRegs' list. * No longer relies on a pattern scan. Signed-off-by: aixxe --- src/Basehook.cpp | 8 +++++--- src/Basehook.h | 1 - src/Utilities/Interfaces.h | 41 +++++++++++++++++++++++++++++++------- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/Basehook.cpp b/src/Basehook.cpp index f438950..c12fc67 100644 --- a/src/Basehook.cpp +++ b/src/Basehook.cpp @@ -19,8 +19,10 @@ */ #include "Basehook.h" + #include "Hooks/Hooks.h" #include "Events/TestListener.h" +#include "Utilities/FindPattern.h" ICvar* cvar = nullptr; IPanel* panel = nullptr; @@ -66,14 +68,14 @@ extern "C" void __attribute__((constructor)) css_basehook_open() { engine = GetInterface("bin/engine.so", "VEngineClient0"); modelrender = GetInterface("bin/engine.so", "VEngineModel0"); debugoverlay = GetInterface("bin/engine.so", "VDebugOverlay0"); - clientdll = GetInterface("bin/client.so", "VClient0"); + clientdll = GetInterface("cstrike/bin/client.so", "VClient0"); matsystem = GetInterface("bin/materialsystem.so", "VMaterialSystem0"); - entitylist = GetInterface("bin/client.so", "VClientEntityList0"); + entitylist = GetInterface("cstrike/bin/client.so", "VClientEntityList0"); gameevents = GetInterface("bin/engine.so", "GAMEEVENTSMANAGER002"); // Scan for the 'CRC32_ProcessBuffer' function. (overkill, but why not?) CRC32_ProcessBuffer = reinterpret_cast( - FindPattern("bin/client.so", "\x55\x89\xE5\x57\x56\x53\x83\xEC\x08\x8B\x4D\x10", "xxxxxxxxxxxx") + FindPattern("cstrike/bin/client.so", "\x55\x89\xE5\x57\x56\x53\x83\xEC\x08\x8B\x4D\x10", "xxxxxxxxxxxx") ); // Hook 'FrameStageNotify' and 'CreateMove' from IBaseClientDLL. diff --git a/src/Basehook.h b/src/Basehook.h index 00cbc46..b4459b3 100644 --- a/src/Basehook.h +++ b/src/Basehook.h @@ -7,7 +7,6 @@ #include #include "Utilities/Linker.h" -#include "Utilities/FindPattern.h" #include "Utilities/Interfaces.h" #include "Utilities/NetVars.h" diff --git a/src/Utilities/Interfaces.h b/src/Utilities/Interfaces.h index 7664f96..7dc0b3d 100644 --- a/src/Utilities/Interfaces.h +++ b/src/Utilities/Interfaces.h @@ -1,5 +1,8 @@ #pragma once +#include +#include + typedef void* (*InstantiateInterfaceFn) (); class InterfaceReg { @@ -10,16 +13,40 @@ class InterfaceReg { }; inline const InterfaceReg* GetInterfaces(const char* library) { - // Find the pointer to the 'InterfaceReg::s_pInterfaceRegs' linked list - same on all game libraries. - uintptr_t interface_list_addr = FindPattern(library, "\x89\x10\x8B\x15\x00\x00\x00\x00\xA3", "xxxx????x"); - - if (interface_list_addr) - return **reinterpret_cast(interface_list_addr + 4); + // Open a handle to the library. + void* library_handle = dlopen(library, RTLD_NOLOAD | RTLD_NOW); - return nullptr; + // Check for an exported 's_pInterfaceRegs' symbol. (easy mode) + void* interfaceregs_symbol = dlsym(library_handle, "s_pInterfaceRegs"); + + if (interfaceregs_symbol) { + // Close the handle to the library. + dlclose(library_handle); + + // Return interface list. + return *reinterpret_cast(interfaceregs_symbol); + } + + // Get the address to the exported 'CreateInterface' symbol. + void* createinterface_symbol = dlsym(library_handle, "CreateInterface"); + + // Close the handle to the library. + dlclose(library_handle); + + // Get the jump displacement to the 'CreateInterfaceInternal' function. + uintptr_t jump_instruction = uintptr_t(createinterface_symbol) + 4; + int32_t jump_displacement = *reinterpret_cast(jump_instruction + 1); + + // Calculate the absolute jump address relative to the next instruction. + uintptr_t createinterfaceinternal_addr = (jump_instruction + 5) + jump_displacement; + + // Read the address to the 'InterfaceReg::s_pInterfaceRegs' linked list from 11 bytes in. + uintptr_t interface_list = *reinterpret_cast(createinterfaceinternal_addr + 11); + + return *reinterpret_cast(interface_list); } -template inline T* GetInterface(const char* library, const char* partial_version) { +template inline T* GetInterface(const char* library, const char* partial_version) { for (const InterfaceReg* current = GetInterfaces(library); current; current = current->m_pNext) { if (std::string(current->m_pName).find(partial_version) != std::string::npos) { return reinterpret_cast(current->m_CreateFn());