rendered paste body// vfn_hook.h#define VTBL( classptr ) (*(DWORD*)classptr)#define PVFN_( classptr , offset ) (VTBL( classptr ) + offset)#define VFN_( classptr , offset ) *(DWORD*)PVFN_( classptr , offset )#define PVFN( classptr , offset ) PVFN_( classptr , ( offset * sizeof(void*) ) )#define VFN( classptr , offset ) VFN_( classptr , ( offset * sizeof(void*) ) )#ifdef WIN32class CCallGate {public: void Gate(void* pOrigFunc) { origFunc = *(int*)pOrigFunc; m_szGate[0] = '\x58'; //pop eax m_szGate[1] = '\x59'; //pop ecx m_szGate[2] = '\x50'; //push eax m_szGate[3] = '\x68'; //push u32 *(unsigned long*)&m_szGate[4] = *(unsigned long*)pOrigFunc; // orgfunc //m_szGate[8] = '\x58'; //pop eax //m_szGate[9] = '\x51'; //push ecx //m_szGate[10] = '\x50'; //push eax m_szGate[8] = '\xC3'; //ret *(unsigned long*)pOrigFunc = (unsigned long)&m_szGate[0]; } int origFunc;private: char m_szGate[18]; };class CVirtualCallGate {public: CVirtualCallGate() { m_bGateBuilt = false; } void Build(void* pOrigFunc, void* pNewFunc, void* pOrgFuncCaller){ if (m_bGateBuilt) return; m_szGate[0] = '\x58'; //pop eax m_szGate[1] = '\x51'; //push ecx m_szGate[2] = '\x50'; //push eax m_szGate[3] = '\x68'; //push u32 *(unsigned long*)&m_szGate[4] = (unsigned long)pNewFunc; // newfunc m_szGate[8] = '\xC3'; //ret *(unsigned long*)pOrgFuncCaller = (unsigned long)&m_szGate[9]; m_szGate[9] = '\x58'; //pop eax m_szGate[10] = '\x59'; //pop ecx m_szGate[11] = '\x50'; //push eax m_szGate[12] = '\x68'; //push u32 *(unsigned long*)&m_szGate[13] = (unsigned long)pOrigFunc; // orgfunc m_szGate[17] = '\xC3'; //ret m_bGateBuilt = true; } unsigned long Gate(){ return (unsigned long)&m_szGate[0]; } bool IsBuilt() { return m_bGateBuilt; }private: bool m_bGateBuilt; char m_szGate[18];};inline bool DeProtect(void* pMemory, unsigned int uiLen){ DWORD dwIDontCare; return (VirtualProtect(pMemory, uiLen, PAGE_EXECUTE_READWRITE, &dwIDontCare) ? true : false);}// prototype#define HVFUNC( funcname, returntype, proto) \ typedef returntype ( __stdcall * funcname##Func ) proto ; \ extern funcname##Func funcname; \ extern CVirtualCallGate funcname##Gate; \ returntype __stdcall funcname##_hook proto;// function itself#define DEFVFUNC( funcname , returntype , proto ) \ funcname##Func funcname = NULL; \ CVirtualCallGate funcname##Gate; \ returntype __stdcall funcname##_hook proto // hook#define HOOKVFUNC( classptr , index , funcname ) \ if (! funcname##Gate.IsBuilt() ) { \ DeProtect((void*)VTBL( classptr ), ( index * sizeof(void*)) + 4 ); \ funcname##Gate.Build((void*)VFN( classptr , index ), funcname##_hook , & funcname ); \ *(DWORD*)PVFN( classptr , index ) = funcname##Gate.Gate(); \ }DWORD __cdecl ToDWORD( ... );/* TED HELP ME! YAY */#define HOOKVFUNCD( classptr , indexptr , funcname ) \ if (! funcname##Gate.IsBuilt() ) { \ Warn("gah-1\n"); \ unsigned long * A = (unsigned long *)ToDWORD(indexptr); \ unsigned long * X = (unsigned long *)ToDWORD(*A); /* *(reinterpret_cast<void*>(ToDWORD(indexptr))); */ \ Warn("classptr 0x%x, indexptr 0x%x, funcname %s, A(indexptr) 0x%x, X(*A) 0x%x, *X 0x%x\n", classptr, indexptr, #funcname, A, X, 0);\ Warn("Instance Pointer 0x%x, Class Pointer 0x%x VTable Pointer 0x%x\n", classptr, *((unsigned long *)classptr), **((unsigned long **)classptr));\ DeProtect((void*)VTBL( classptr ), ( ToDWORD(*A) - ToDWORD(classptr)) + 4 ); \ DeProtect((void *)(X-1), 20 ); \ Warn("gah1\n"); \ funcname##Gate.Build( (void *)X, funcname##_hook , & funcname ); \ Warn("gah2\n"); \ *X = ToDWORD(funcname##Gate.Gate()); \ Warn("gah3\n"); \ }#define HOOKVFUNCX( classptr, indexptr, funcname) \ { \ unsigned long taddr = *(unsigned long*)(ToDWORD(indexptr)+1); \ unsigned long *addr = (unsigned long*)((unsigned long)ToDWORD(indexptr)); \ Warn("funcname %s, indexptr: 0x%x, classptr: 0x%x, *classptr: 0x%x, taddr: 0x%x, *addr: 0x%x, index: xd\n", #funcname, indexptr, classptr, *classptr, taddr, *addr); \ if (*addr == 0xA0FF018B) { \ addr += 1; \ unsigned long ___index = *addr; \ ___index /= 4; \ HOOKVFUNC(classptr, ___index, funcname); \ } else if (*addr == 0x60FF018B) { \ addr += 1; \ unsigned long ___index = *addr & 0xFF; \ ___index /= 4; \ HOOKVFUNC(classptr, ___index, funcname); \ } else if (*addr == 0x20FF018B) { \ HOOKVFUNC(classptr, 0, funcname); \ } else {\ Warn("ERROR: 0x%x IS NOT A VIRTUAL FUNCTION IN 0x%x\n", ToDWORD(indexptr), classptr); \ } \ }/* unsigned long taddr = *(unsigned long*)(ToDWORD(indexptr)+1); \// Get the first relative jump target Warn("ERRORE: 0x%x IS NOT A VIRTUAL FUNCTION IN 0x%x\n", indexptr, classptr); \// unsigned long *addr = (unsigned long*)((unsigned long)ToDWORD(indexptr) + 1 + 4 + taddr); \// Do the the first relative jump */// This virtual function hooker works with a DEBUG build of the plugin. It // seems the vtable access is configured differently depending on whether// you're in DEBUG or RETAIL.#define HOOKVFUNCQ( classptr, indexptr, funcname) \ { \ unsigned long taddr = *(unsigned long*)(ToDWORD(indexptr)+1); \ Warn("[%s] Calculating first relative jump. classptr 0x%x, indexptr 0x%x\n", #funcname, classptr, indexptr); \ unsigned long *addr = (unsigned long*)((unsigned long)ToDWORD(indexptr) + 1 + 4 + taddr); \ Warn("[%s] Do first relative jump. Pointer to target: 0x%x.\n", #funcname, addr); \ if (*addr == 0xA0FF018B) { \ addr += 1; \ unsigned long ___index = *addr; \ ___index /= 4; \ Warn("[%s] Instruction set 0xA0FF018B yields index %d\n", #funcname, ___index); \ HOOKVFUNC(classptr, ___index, funcname); \ } else if (*addr == 0x60FF018B) { \ addr += 1; \ unsigned long ___index = *addr & 0xFF; \ ___index /= 4; \ Warn("[%s] Instruction set 0x60FF018B yields index %d\n", #funcname, ___index); \ HOOKVFUNC(classptr, ___index, funcname); \ } else if (*addr == 0x20FF018B) { \ Warn("[%s] Instruction set 0x20FF018B yields index %d\n", #funcname, 0); \ HOOKVFUNC(classptr, 0, funcname); \ } else {\ Warn("[%s] Instruction set 0x%x is unknown!\n", #funcname, *addr); \ } \ }// This virtual function hooker works with a Retail build of the plugin. It // seems the vtable access is configured differently depending on whether// you're in DEBUG or RETAIL.#define HOOKVFUNCP( classptr, indexptr, funcname) \ { \ unsigned long *addr = (unsigned long*)(ToDWORD(indexptr)); \ /*Warn("[%s] Do first relative jump. Pointer to target: 0x%x.\n", #funcname, addr);*/ \ if (*addr == 0xA0FF018B) { \ addr += 1; \ unsigned long ___index = *addr; \ ___index /= 4; \ Warn("[%s] Instruction set 0xA0FF018B yields index %d\n", #funcname, ___index);\ HOOKVFUNC(classptr, ___index, funcname); \ } else if (*addr == 0x60FF018B) { \ addr += 1; \ unsigned long ___index = *addr & 0xFF; \ ___index /= 4; \ Warn("[%s] Instruction set 0x60FF018B yields index %d\n", #funcname, ___index); \ HOOKVFUNC(classptr, ___index, funcname); \ } else if (*addr == 0x20FF018B) { \ Warn("[%s] Instruction set 0x20FF018B yields index %d\n", #funcname, 0); \ HOOKVFUNC(classptr, 0, funcname); \ } else {\ Warn("[%s] Instruction set 0x%x is unknown!\n", #funcname, *addr); \ } \ }/* unsigned long *tableAddress;\ unsigned long *functionAddress;\ tableAddress = (unsigned long *)classptr;\ tableAddress = (unsigned long *)*tableAddress;\ tableAddress = (unsigned long *)*tableAddress; \ functionAddress = (unsigned long *)ToDWORD(indexptr);\ unsigned char ___index = ((char)(*functionAddress - *tableAddress)) / sizeof(void *);\ Warn("indexptr: 0x%x, classptr: 0x%x, *classptr: 0x%x, tableAddress: 0x%x, functonAddress: 0x%x, index: %d\n", indexptr, classptr, *classptr, tableAddress, functionAddress, ___index); \ HOOKVFUNC(classptr, ___index, funcname); \ } //unsigned char ___index = ((void*)(indexptr) - *((void*)(*((void *)classptr))) ) / 4; \///* //unsigned long taddr = *(unsigned long*)(ToDWORD(indexptr)+1); \// Get the first relative jump target //Warn("ERRORE: 0x%x IS NOT A VIRTUAL FUNCTION IN 0x%x\n", indexptr, classptr); \// //unsigned long *addr = (unsigned long*)((unsigned long)ToDWORD(indexptr) + 1 + 4 + taddr); \// Do the the first relative jump Warn("ERRORF: 0x%x IS NOT A VIRTUAL FUNCTION IN 0x%x\n", indexptr, classptr); \ MessageBox(NULL, "", "ShIT", 0);\ if (*addr == 0xA0FF018B) { \ addr += 1; \ unsigned long ___index = *addr; \ ___index /= 4; \ Warn("ERROR1: 0x%x IS NOT A VIRTUAL FUNCTION IN 0x%x\n", ToDWORD(indexptr), classptr); \ HOOKVFUNC(classptr, ___index, funcname); \ } else if (*addr == 0x60FF018B) { \ addr += 1; \ unsigned char ___index = *(unsigned char*)addr; \ ___index /= 4; \ Warn("ERROR2: 0x%x IS NOT A VIRTUAL FUNCTION IN 0x%x\n", ToDWORD(indexptr), classptr); \ HOOKVFUNC(classptr, ___index, funcname); \ } else if (*addr == 0x20FF018B) { \ Warn("ERROR3: 0x%x IS NOT A VIRTUAL FUNCTION IN 0x%x\n", ToDWORD(indexptr), classptr); \ HOOKVFUNC(classptr, 0, funcname); \ } else {\ Warn("ERROR4: 0x%x IS NOT A VIRTUAL FUNCTION IN 0x%x\n", ToDWORD(indexptr), classptr); \ } \ }*/#else#include <sys/user.h>DWORD ToDWORD(...);#define HVFUNC( funcname, returntype, proto) \ typedef returntype (*funcname##Func) proto; \ extern funcname##Func funcname; \ returntype funcname##_hook proto; #define DEFVFUNC( funcname , returntype , proto ) \ funcname##Func funcname = NULL; \ returntype funcname##_hook proto #define HOOKVFUNC( classptr , index , funcname) \ if (*(DWORD*)PVFN( classptr , index ) != ToDWORD(funcname##_hook)) { \ if (funcname) { Msg("WARNING: FUNCTION 0x%x ALREADY HOOKED WITH DIFFERENT CLASS, NOT HOOKING!\n", funcname##_hook); } else { \ mprotect((char*)((int)(*(void**)classptr) & ~(PAGE_SIZE-1)), (int)(*(char**)classptr - (char*)((int)(*(void**)classptr) & ~(PAGE_SIZE-1))) + ( index * sizeof(void*)) + 4, PROT_READ | PROT_WRITE | PROT_EXEC); \ funcname = (funcname##Func)VFN( classptr , index ); \ *(DWORD*)PVFN( classptr , index ) = funcname##_hook; } }#define HOOKVFUNCN( classptr, indexptr, funcname) \ { \ int ___index = (((int)ToDWORD( & indexptr)) - 1); \ if (___index > 0) { ___index /= 4; } \ if ((___index < 0) || (___index > 10000)) { \ Warn("ERROR: 0x%x IS NOT A VIRTUAL FUNCTION IN 0x%x\n", & indexptr, classptr); \ } else { \ HOOKVFUNC(classptr, ___index, funcname); \ } \ }#define VFUNCINDEX(indexptr) ((((int)ToDWORD(indexptr)) - 1) / 4);#endif/* void Build(void* pOrigFunc, void* pNewFunc, void* pOrgFuncCaller){ if (m_bGateBuilt) return; m_szGate[0] = '\x58'; //pop eax m_szGate[1] = '\x51'; //push ecx m_szGate[2] = '\x50'; //push eax m_szGate[3] = '\x68'; //push u32 *(unsigned long*)&m_szGate[4] = (unsigned long)pNewFunc; // newfunc m_szGate[8] = '\xC3'; //ret *(unsigned long*)pOrgFuncCaller = (unsigned long)&m_szGate[9]; m_szGate[9] = '\x58'; //pop eax m_szGate[10] = '\x59'; //pop ecx m_szGate[11] = '\x50'; //push eax m_szGate[12] = '\x68'; //push u32 *(unsigned long*)&m_szGate[13] = (unsigned long)pOrigFunc; // orgfunc m_szGate[17] = '\xC3'; //ret m_bGateBuilt = true; }*/