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 "Basehook.h"
|
||||||
|
|
||||||
#include "Hooks/Hooks.h"
|
#include "Hooks/Hooks.h"
|
||||||
#include "Events/TestListener.h"
|
#include "Events/TestListener.h"
|
||||||
|
#include "Utilities/FindPattern.h"
|
||||||
|
|
||||||
ICvar* cvar = nullptr;
|
ICvar* cvar = nullptr;
|
||||||
IPanel* panel = nullptr;
|
IPanel* panel = nullptr;
|
||||||
|
@ -66,14 +68,14 @@ extern "C" void __attribute__((constructor)) css_basehook_open() {
|
||||||
engine = GetInterface<IVEngineClient>("bin/engine.so", "VEngineClient0");
|
engine = GetInterface<IVEngineClient>("bin/engine.so", "VEngineClient0");
|
||||||
modelrender = GetInterface<IVModelRender>("bin/engine.so", "VEngineModel0");
|
modelrender = GetInterface<IVModelRender>("bin/engine.so", "VEngineModel0");
|
||||||
debugoverlay = GetInterface<IVDebugOverlay>("bin/engine.so", "VDebugOverlay0");
|
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");
|
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");
|
gameevents = GetInterface<IGameEventManager2>("bin/engine.so", "GAMEEVENTSMANAGER002");
|
||||||
|
|
||||||
// Scan for the 'CRC32_ProcessBuffer' function. (overkill, but why not?)
|
// Scan for the 'CRC32_ProcessBuffer' function. (overkill, but why not?)
|
||||||
CRC32_ProcessBuffer = reinterpret_cast<CRC32_ProcessBufferFn>(
|
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.
|
// Hook 'FrameStageNotify' and 'CreateMove' from IBaseClientDLL.
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <vmthook/vmthook.h>
|
#include <vmthook/vmthook.h>
|
||||||
|
|
||||||
#include "Utilities/Linker.h"
|
#include "Utilities/Linker.h"
|
||||||
#include "Utilities/FindPattern.h"
|
|
||||||
#include "Utilities/Interfaces.h"
|
#include "Utilities/Interfaces.h"
|
||||||
#include "Utilities/NetVars.h"
|
#include "Utilities/NetVars.h"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
typedef void* (*InstantiateInterfaceFn) ();
|
typedef void* (*InstantiateInterfaceFn) ();
|
||||||
|
|
||||||
class InterfaceReg {
|
class InterfaceReg {
|
||||||
|
@ -10,16 +13,40 @@ class InterfaceReg {
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const InterfaceReg* GetInterfaces(const char* library) {
|
inline const InterfaceReg* GetInterfaces(const char* library) {
|
||||||
// Find the pointer to the 'InterfaceReg::s_pInterfaceRegs' linked list - same on all game libraries.
|
// Open a handle to the library.
|
||||||
uintptr_t interface_list_addr = FindPattern(library, "\x89\x10\x8B\x15\x00\x00\x00\x00\xA3", "xxxx????x");
|
void* library_handle = dlopen(library, RTLD_NOLOAD | RTLD_NOW);
|
||||||
|
|
||||||
if (interface_list_addr)
|
|
||||||
return **reinterpret_cast<InterfaceReg***>(interface_list_addr + 4);
|
|
||||||
|
|
||||||
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<InterfaceReg**>(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<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> inline T* GetInterface(const char* library, const char* partial_version) {
|
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) {
|
for (const InterfaceReg* current = GetInterfaces(library); current; current = current->m_pNext) {
|
||||||
if (std::string(current->m_pName).find(partial_version) != std::string::npos) {
|
if (std::string(current->m_pName).find(partial_version) != std::string::npos) {
|
||||||
return reinterpret_cast<T*>(current->m_CreateFn());
|
return reinterpret_cast<T*>(current->m_CreateFn());
|
||||||
|
|
Loading…
Reference in New Issue