Use alternative method for finding 's_pInterfaceRegs' list.
* No longer relies on a pattern scan. Signed-off-by: aixxe <me@aixxe.net>
This commit is contained in:
parent
0eb481e754
commit
713c4b4627
|
@ -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<IVEngineClient>("bin/engine.so", "VEngineClient0");
|
||||
modelrender = GetInterface<IVModelRender>("bin/engine.so", "VEngineModel0");
|
||||
debugoverlay = GetInterface<IVDebugOverlay>("bin/engine.so", "VDebugOverlay0");
|
||||
clientdll = GetInterface<IBaseClientDLL>("bin/client.so", "VClient0");
|
||||
clientdll = GetInterface<IBaseClientDLL>("cstrike/bin/client.so", "VClient0");
|
||||
matsystem = GetInterface<IMaterialSystem>("bin/materialsystem.so", "VMaterialSystem0");
|
||||
entitylist = GetInterface<IClientEntityList>("bin/client.so", "VClientEntityList0");
|
||||
entitylist = GetInterface<IClientEntityList>("cstrike/bin/client.so", "VClientEntityList0");
|
||||
gameevents = GetInterface<IGameEventManager2>("bin/engine.so", "GAMEEVENTSMANAGER002");
|
||||
|
||||
// Scan for the 'CRC32_ProcessBuffer' function. (overkill, but why not?)
|
||||
CRC32_ProcessBuffer = reinterpret_cast<CRC32_ProcessBufferFn>(
|
||||
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.
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <vmthook/vmthook.h>
|
||||
|
||||
#include "Utilities/Linker.h"
|
||||
#include "Utilities/FindPattern.h"
|
||||
#include "Utilities/Interfaces.h"
|
||||
#include "Utilities/NetVars.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <dlfcn.h>
|
||||
|
||||
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");
|
||||
// Open a handle to the library.
|
||||
void* library_handle = dlopen(library, RTLD_NOLOAD | RTLD_NOW);
|
||||
|
||||
if (interface_list_addr)
|
||||
return **reinterpret_cast<InterfaceReg***>(interface_list_addr + 4);
|
||||
// Check for an exported 's_pInterfaceRegs' symbol. (easy mode)
|
||||
void* interfaceregs_symbol = dlsym(library_handle, "s_pInterfaceRegs");
|
||||
|
||||
return nullptr;
|
||||
if (interfaceregs_symbol) {
|
||||
// Close the handle to the library.
|
||||
dlclose(library_handle);
|
||||
|
||||
// Return interface list.
|
||||
return *reinterpret_cast<InterfaceReg**>(interfaceregs_symbol);
|
||||
}
|
||||
|
||||
template <typename T> inline T* GetInterface(const char* library, const char* partial_version) {
|
||||
// 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<int32_t*>(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<uintptr_t*>(createinterfaceinternal_addr + 11);
|
||||
|
||||
return *reinterpret_cast<InterfaceReg**>(interface_list);
|
||||
}
|
||||
|
||||
template <typename T = void*> 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<T*>(current->m_CreateFn());
|
||||
|
|
Loading…
Reference in New Issue