12 Star 15 Fork 0

nagist / MetaHook

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
metahook.cpp 19.67 KB
一键复制 编辑 原始数据 按行查看 历史
Akatsuki 提交于 2016-11-30 17:32 . plugins loader fixed
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
#include "metahook.h"
#include "LoadBlob.h"
#include "Detours\detours.h"
#include "interface.h"
#include <IPluginsV1.h>
struct hook_s
{
void *pOldFuncAddr;
void *pNewFuncAddr;
void *pClass;
int iTableIndex;
int iFuncIndex;
HMODULE hModule;
const char *pszModuleName;
const char *pszFuncName;
struct hook_s *pNext;
void *pInfo;
};
int (*g_pfnbuild_number)(void);
void *g_pClientDLL_Init;
int (*g_pfnClientDLL_Init)(void);
hook_t *g_phClientDLL_Init;
BOOL g_bEngineIsBlob;
HMODULE g_hEngineModule;
DWORD g_dwEngineBase;
DWORD g_dwEngineSize;
hook_t *g_pHookBase;
cl_exportfuncs_t *g_pExportFuncs;
bool g_bSaveVideo;
char g_szTempFile[MAX_PATH];
bool g_bIsNewEngine;
hook_t *MH_FindInlineHooked(void *pOldFuncAddr);
hook_t *MH_FindVFTHooked(void *pClass, int iTableIndex, int iFuncIndex);
hook_t *MH_FindIATHooked(HMODULE hModule, const char *pszModuleName, const char *pszFuncName);
BOOL MH_UnHook(hook_t *pHook);
hook_t *MH_InlineHook(void *pOldFuncAddr, void *pNewFuncAddr, void *&pCallBackFuncAddr);
hook_t *MH_VFTHook(void *pClass, int iTableIndex, int iFuncIndex, void *pNewFuncAddr, void *&pCallBackFuncAddr);
hook_t *MH_IATHook(HMODULE hModule, const char *pszModuleName, const char *pszFuncName, void *pNewFuncAddr, void *&pCallBackFuncAddr);
void *MH_GetClassFuncAddr(...);
DWORD MH_GetModuleBase(HMODULE hModule);
DWORD MH_GetModuleSize(HMODULE hModule);
void *MH_SearchPattern(void *pStartSearch, DWORD dwSearchLen, char *pPattern, DWORD dwPatternLen);
void MH_WriteDWORD(void *pAddress, DWORD dwValue);
DWORD MH_ReadDWORD(void *pAddress);
void MH_WriteBYTE(void *pAddress, BYTE ucValue);
BYTE MH_ReadBYTE(void *pAddress);
void MH_WriteNOP(void *pAddress, DWORD dwCount);
DWORD MH_WriteMemory(void *pAddress, BYTE *pData, DWORD dwDataSize);
DWORD MH_ReadMemory(void *pAddress, BYTE *pData, DWORD dwDataSize);
DWORD MH_GetVideoMode(int *wide, int *height, int *bpp, bool *windowed);
DWORD MH_GetEngineVersion(void);
#define BUILD_NUMBER_SIG "\xA1\x2A\x2A\x2A\x2A\x83\xEC\x08\x2A\x33\x2A\x85\xC0"
#define BUILD_NUMBER_SIG_NEW "\x55\x8B\xEC\x83\xEC\x08\xA1\x2A\x2A\x2A\x2A\x56\x33\xF6\x85\xC0\x0F\x85\x2A\x2A\x2A\x2A\x53\x33\xDB\x8B\x04\x9D"
#define CLIENTDLL_INIT_SIG "\x81\xEC\x00\x04\x00\x00\x8D\x44\x24\x00\x68\x2A\x2A\x2A\x2A\x68\x00\x02\x00\x00\x50\xE8\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x83\xC4\x0C\x85\xC0"
#define CLIENTDLL_INIT_SIG_NEW "\x55\x8B\xEC\x81\xEC\x00\x02\x00\x00\x68\x2A\x2A\x2A\x2A\x8D\x85\x00\xFE\xFF\xFF\x68\x00\x02\x00\x00\x50\xE8\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x83\xC4\x0C\x85\xC0\x74\x2A\xE8"
typedef struct plugin_s
{
char *filename;
HINTERFACEMODULE module;
IBaseInterface *pPluginAPI;
int iInterfaceVersion;
struct plugin_s *next;
}
plugin_t;
plugin_t *g_pPluginBase;
extern IFileSystem *g_pFileSystem;
mh_interface_t gInterface;
mh_enginesave_t gMetaSave;
extern metahook_api_t gMetaHookAPI;
bool HM_LoadPlugins(char *filename, HINTERFACEMODULE hModule)
{
plugin_t *plug = new plugin_t;
plug->module = hModule;
CreateInterfaceFn fnCreateInterface = Sys_GetFactory(plug->module);
plug->pPluginAPI = fnCreateInterface(METAHOOK_PLUGIN_API_VERSION, NULL);
if (plug->pPluginAPI)
{
((IPlugins *)plug->pPluginAPI)->Init(&gMetaHookAPI, &gInterface, &gMetaSave);
plug->iInterfaceVersion = 2;
}
else
{
plug->pPluginAPI = fnCreateInterface(METAHOOK_PLUGIN_API_VERSION_V1, NULL);
if (plug->pPluginAPI)
plug->iInterfaceVersion = 1;
else
plug->iInterfaceVersion = 0;
}
plug->filename = strdup(filename);
plug->next = g_pPluginBase;
g_pPluginBase = plug;
return true;
}
void MH_Init(const char *pszGameName)
{
g_pfnbuild_number = NULL;
g_pfnClientDLL_Init = NULL;
g_phClientDLL_Init = NULL;
g_dwEngineBase = 0;
g_dwEngineSize = 0;
g_pHookBase = NULL;
g_pExportFuncs = NULL;
g_bSaveVideo = false;
g_szTempFile[0] = 0;
gInterface.CommandLine = CommandLine();
gInterface.FileSystem = g_pFileSystem;
gInterface.Registry = registry;
char metapath[MAX_PATH], filename[MAX_PATH];
sprintf(metapath, "%s/metahook", pszGameName);
sprintf(filename, "%s/configs/plugins.lst", metapath);
FILE *fp = fopen(filename, "rt");
if (fp)
{
static char line[1024];
while (!feof(fp))
{
static char plugins[64];
fgets(line, sizeof(line), fp);
if (line[0] == '\0' || line[0] == ';')
continue;
if (sscanf(line, "%s", plugins) != 1)
continue;
if (!isalnum(plugins[0]))
continue;
sprintf(filename, "%s/plugins/%s", metapath, plugins);
HINTERFACEMODULE hModule = Sys_LoadModule(filename);
if (!hModule)
{
static char msg[512];
wsprintf(msg, "Could not load %s.\nPlease try again at a later time.", plugins);
MessageBox(NULL, msg, "Warning", MB_ICONWARNING);
continue;
}
if (!HM_LoadPlugins(plugins, hModule))
continue;
}
fclose(fp);
}
}
int ClientDLL_Initialize(struct cl_enginefuncs_s *pEnginefuncs, int iVersion)
{
gMetaSave.pExportFuncs = new cl_exportfuncs_t;
gMetaSave.pEngineFuncs = new cl_enginefunc_t;
memcpy(gMetaSave.pExportFuncs, g_pExportFuncs, sizeof(cl_exportfuncs_t));
memcpy(gMetaSave.pEngineFuncs, pEnginefuncs, sizeof(cl_enginefunc_t));
for (plugin_t *plug = g_pPluginBase; plug; plug = plug->next)
{
if (plug->iInterfaceVersion > 1)
((IPlugins *)plug->pPluginAPI)->LoadClient(g_pExportFuncs);
else
((IPluginsV1 *)plug->pPluginAPI)->Init(g_pExportFuncs);
}
return g_pExportFuncs->Initialize(pEnginefuncs, iVersion);
}
void MH_ClientDLL_Init(void)
{
DWORD dwResult = (DWORD)MH_SearchPattern((void *)((DWORD)g_pClientDLL_Init + 0xB0), 0xFF, "\x6A\x07\x68", 3);
if (!dwResult)
return;
g_pExportFuncs = *(cl_exportfuncs_t **)(dwResult + 0x9);
static DWORD dwClientDLL_Initialize[1];
dwClientDLL_Initialize[0] = (DWORD)&ClientDLL_Initialize;
MH_WriteDWORD((void *)(dwResult + 0x9), (DWORD)dwClientDLL_Initialize);
g_pfnClientDLL_Init();
}
void MH_LoadEngine(HMODULE hModule)
{
gInterface.FileSystem = g_pFileSystem;
if (hModule)
{
g_dwEngineBase = MH_GetModuleBase(hModule);
g_dwEngineSize = MH_GetModuleSize(hModule);
g_hEngineModule = hModule;
g_bEngineIsBlob = FALSE;
}
else
{
g_dwEngineBase = 0x1D01000;
g_dwEngineSize = 0x1000000;
g_hEngineModule = GetModuleHandle(NULL);
g_bEngineIsBlob = TRUE;
}
g_bIsNewEngine = false;
g_pfnbuild_number = (int (*)(void))MH_SearchPattern((void *)g_dwEngineBase, g_dwEngineSize, BUILD_NUMBER_SIG, sizeof(BUILD_NUMBER_SIG) - 1);
if (!g_pfnbuild_number)
{
g_pfnbuild_number = (int (*)(void))MH_SearchPattern((void *)g_dwEngineBase, g_dwEngineSize, BUILD_NUMBER_SIG_NEW, sizeof(BUILD_NUMBER_SIG_NEW) - 1);
g_bIsNewEngine = true;
}
if (g_bIsNewEngine)
g_pClientDLL_Init = MH_SearchPattern((void *)g_dwEngineBase, g_dwEngineSize, CLIENTDLL_INIT_SIG_NEW, sizeof(CLIENTDLL_INIT_SIG_NEW) - 1);
else
g_pClientDLL_Init = MH_SearchPattern((void *)g_dwEngineBase, g_dwEngineSize, CLIENTDLL_INIT_SIG, sizeof(CLIENTDLL_INIT_SIG) - 1);
g_phClientDLL_Init = MH_InlineHook(g_pClientDLL_Init, MH_ClientDLL_Init, (void *&)g_pfnClientDLL_Init);
for (plugin_t *plug = g_pPluginBase; plug; plug = plug->next)
{
if (plug->iInterfaceVersion > 1)
((IPlugins *)plug->pPluginAPI)->LoadEngine();
}
}
void MH_ExitGame(int iResult)
{
for (plugin_t *plug = g_pPluginBase; plug; plug = plug->next)
{
if (plug->iInterfaceVersion > 1)
((IPlugins *)plug->pPluginAPI)->ExitGame(iResult);
}
}
void MH_FreeAllPlugin(void)
{
plugin_t *plug = g_pPluginBase;
while (plug)
{
plugin_t *pfree = plug;
plug = plug->next;
if (pfree->pPluginAPI)
{
if (pfree->iInterfaceVersion > 1)
((IPlugins *)pfree->pPluginAPI)->Shutdown();
}
free(pfree->filename);
Sys_FreeModule(pfree->module);
delete pfree;
}
g_pPluginBase = NULL;
}
void MH_ShutdownPlugins(void)
{
plugin_t *plug = g_pPluginBase;
while (plug)
{
plugin_t *pfree = plug;
plug = plug->next;
if (pfree->pPluginAPI)
{
if (pfree->iInterfaceVersion > 1)
((IPlugins *)pfree->pPluginAPI)->Shutdown();
}
free(pfree->filename);
FreeLibrary((HMODULE)pfree->module);
delete pfree;
}
g_pPluginBase = NULL;
}
void MH_Shutdown(void)
{
if (g_pHookBase)
MH_FreeAllHook();
if (g_pPluginBase)
MH_ShutdownPlugins();
if (gMetaSave.pExportFuncs)
{
delete gMetaSave.pExportFuncs;
gMetaSave.pExportFuncs = NULL;
}
if (gMetaSave.pEngineFuncs)
{
delete gMetaSave.pEngineFuncs;
gMetaSave.pEngineFuncs = NULL;
}
}
hook_t *MH_NewHook(void)
{
hook_t *h = new hook_t;
memset(h, 0, sizeof(hook_t));
h->pNext = g_pHookBase;
g_pHookBase = h;
return h;
}
hook_t *MH_FindInlineHooked(void *pOldFuncAddr)
{
for (hook_t *h = g_pHookBase; h; h = h->pNext)
{
if (h->pOldFuncAddr == pOldFuncAddr)
return h;
}
return NULL;
}
hook_t *MH_FindVFTHooked(void *pClass, int iTableIndex, int iFuncIndex)
{
for (hook_t *h = g_pHookBase; h; h = h->pNext)
{
if (h->pClass == pClass && h->iTableIndex == iTableIndex && h->iFuncIndex == iFuncIndex)
return h;
}
return NULL;
}
hook_t *MH_FindIATHooked(HMODULE hModule, const char *pszModuleName, const char *pszFuncName)
{
for (hook_t *h = g_pHookBase; h; h = h->pNext)
{
if (h->hModule == hModule && h->pszModuleName == pszModuleName && h->pszFuncName == pszFuncName)
return h;
}
return NULL;
}
#pragma pack(push, 1)
struct tagIATDATA
{
void *pAPIInfoAddr;
};
struct tagCLASS
{
DWORD *pVMT;
};
struct tagVTABLEDATA
{
tagCLASS *pInstance;
void *pVFTInfoAddr;
};
#pragma pack(pop)
void MH_FreeHook(hook_t *pHook)
{
if (pHook->pClass)
{
tagVTABLEDATA *info = (tagVTABLEDATA *)pHook->pInfo;
MH_WriteMemory(info->pVFTInfoAddr, (BYTE *)pHook->pOldFuncAddr, sizeof(DWORD));
}
else if (pHook->hModule)
{
tagIATDATA *info = (tagIATDATA *)pHook->pInfo;
MH_WriteMemory(info->pAPIInfoAddr, (BYTE *)pHook->pOldFuncAddr, sizeof(DWORD));
}
else
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(void *&)pHook->pOldFuncAddr, pHook->pNewFuncAddr);
DetourTransactionCommit();
}
if (pHook->pInfo)
delete pHook->pInfo;
delete pHook;
}
void MH_FreeAllHook(void)
{
hook_t *next = NULL;
for (hook_t *h = g_pHookBase; h; h = next)
{
next = h->pNext;
MH_FreeHook(h);
}
g_pHookBase = NULL;
}
BOOL MH_UnHook(hook_t *pHook)
{
if (!g_pHookBase)
return FALSE;
hook_t *h, **back;
back = &g_pHookBase;
while (1)
{
h = *back;
if (!h)
break;
if (h == pHook)
{
*back = h->pNext;
MH_FreeHook(h);
return TRUE;
}
back = &h->pNext;
}
return FALSE;
}
hook_t *MH_InlineHook(void *pOldFuncAddr, void *pNewFuncAddr, void *&pCallBackFuncAddr)
{
hook_t *h = MH_NewHook();
h->pOldFuncAddr = pOldFuncAddr;
h->pNewFuncAddr = pNewFuncAddr;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(void *&)h->pOldFuncAddr, pNewFuncAddr);
DetourTransactionCommit();
pCallBackFuncAddr = h->pOldFuncAddr;
return h;
}
hook_t *MH_VFTHook(void *pClass, int iTableIndex, int iFuncIndex, void *pNewFuncAddr, void *&pCallBackFuncAddr)
{
tagVTABLEDATA *info = new tagVTABLEDATA;
info->pInstance = (tagCLASS *)pClass;
DWORD *pVMT = ((tagCLASS *)pClass + iTableIndex)->pVMT;
info->pVFTInfoAddr = pVMT + iFuncIndex;
hook_t *h = MH_NewHook();
h->pOldFuncAddr = (void *)pVMT[iFuncIndex];
h->pNewFuncAddr = pNewFuncAddr;
h->pInfo = info;
h->pClass = pClass;
h->iTableIndex = iTableIndex;
h->iFuncIndex = iFuncIndex;
pCallBackFuncAddr = h->pOldFuncAddr;
MH_WriteMemory(info->pVFTInfoAddr, (BYTE *)&pNewFuncAddr, sizeof(DWORD));
return h;
}
hook_t *MH_IATHook(HMODULE hModule, const char *pszModuleName, const char *pszFuncName, void *pNewFuncAddr, void *&pCallBackFuncAddr)
{
IMAGE_NT_HEADERS *pHeader = (IMAGE_NT_HEADERS *)((DWORD)hModule + ((IMAGE_DOS_HEADER *)hModule)->e_lfanew);
IMAGE_IMPORT_DESCRIPTOR *pImport = (IMAGE_IMPORT_DESCRIPTOR *)((DWORD)hModule + pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
while (pImport->Name && stricmp((const char *)((DWORD)hModule + pImport->Name), pszModuleName))
pImport++;
DWORD dwFuncAddr = (DWORD)GetProcAddress(GetModuleHandle(pszModuleName), pszFuncName);
IMAGE_THUNK_DATA *pThunk = (IMAGE_THUNK_DATA *)((DWORD)hModule + pImport->FirstThunk);
while (pThunk->u1.Function != dwFuncAddr)
pThunk++;
tagIATDATA *info = new tagIATDATA;
info->pAPIInfoAddr = &pThunk->u1.Function;
hook_t *h = MH_NewHook();
h->pOldFuncAddr = (void *)pThunk->u1.Function;
h->pNewFuncAddr = pNewFuncAddr;
h->pInfo = info;
h->hModule = hModule;
h->pszModuleName = pszModuleName;
h->pszFuncName = pszFuncName;
pCallBackFuncAddr = h->pOldFuncAddr;
MH_WriteMemory(info->pAPIInfoAddr, (BYTE *)&pNewFuncAddr, sizeof(DWORD));
return h;
}
void *MH_GetClassFuncAddr(...)
{
DWORD address;
__asm
{
lea eax,address
mov edx, [ebp + 8]
mov [eax], edx
}
return (void *)address;
}
DWORD MH_GetModuleBase(HMODULE hModule)
{
MEMORY_BASIC_INFORMATION mem;
if (!VirtualQuery(hModule, &mem, sizeof(MEMORY_BASIC_INFORMATION)))
return 0;
return (DWORD)mem.AllocationBase;
}
DWORD MH_GetModuleSize(HMODULE hModule)
{
return ((IMAGE_NT_HEADERS *)((DWORD)hModule + ((IMAGE_DOS_HEADER *)hModule)->e_lfanew))->OptionalHeader.SizeOfImage;
}
HMODULE MH_GetEngineModule(void)
{
return g_hEngineModule;
}
DWORD MH_GetEngineBase(void)
{
return g_dwEngineBase;
}
DWORD MH_GetEngineSize(void)
{
return g_dwEngineSize;
}
void *MH_SearchPattern(void *pStartSearch, DWORD dwSearchLen, char *pPattern, DWORD dwPatternLen)
{
DWORD dwStartAddr = (DWORD)pStartSearch;
DWORD dwEndAddr = dwStartAddr + dwSearchLen - dwPatternLen;
while (dwStartAddr < dwEndAddr)
{
bool found = true;
for (DWORD i = 0; i < dwPatternLen; i++)
{
char code = *(char *)(dwStartAddr + i);
if (pPattern[i] != 0x2A && pPattern[i] != code)
{
found = false;
break;
}
}
if (found)
return (void *)dwStartAddr;
dwStartAddr++;
}
return 0;
}
void MH_WriteDWORD(void *pAddress, DWORD dwValue)
{
DWORD dwProtect;
if (VirtualProtect((void *)pAddress, 4, PAGE_EXECUTE_READWRITE, &dwProtect))
{
*(DWORD *)pAddress = dwValue;
VirtualProtect((void *)pAddress, 4, dwProtect, &dwProtect);
}
}
DWORD MH_ReadDWORD(void *pAddress)
{
DWORD dwProtect;
DWORD dwValue = 0;
if (VirtualProtect((void *)pAddress, 4, PAGE_EXECUTE_READWRITE, &dwProtect))
{
dwValue = *(DWORD *)pAddress;
VirtualProtect((void *)pAddress, 4, dwProtect, &dwProtect);
}
return dwValue;
}
void MH_WriteBYTE(void *pAddress, BYTE ucValue)
{
DWORD dwProtect;
if (VirtualProtect((void *)pAddress, 1, PAGE_EXECUTE_READWRITE, &dwProtect))
{
*(BYTE *)pAddress = ucValue;
VirtualProtect((void *)pAddress, 1, dwProtect, &dwProtect);
}
}
BYTE MH_ReadBYTE(void *pAddress)
{
DWORD dwProtect;
BYTE ucValue = 0;
if (VirtualProtect((void *)pAddress, 1, PAGE_EXECUTE_READWRITE, &dwProtect))
{
ucValue = *(BYTE *)pAddress;
VirtualProtect((void *)pAddress, 1, dwProtect, &dwProtect);
}
return ucValue;
}
void MH_WriteNOP(void *pAddress, DWORD dwCount)
{
static DWORD dwProtect;
if (VirtualProtect(pAddress, dwCount, PAGE_EXECUTE_READWRITE, &dwProtect))
{
for (DWORD i = 0; i < dwCount; i++)
*(BYTE *)((DWORD)pAddress + i) = 0x90;
VirtualProtect(pAddress, dwCount, dwProtect, &dwProtect);
}
}
DWORD MH_WriteMemory(void *pAddress, BYTE *pData, DWORD dwDataSize)
{
static DWORD dwProtect;
if (VirtualProtect(pAddress, dwDataSize, PAGE_EXECUTE_READWRITE, &dwProtect))
{
memcpy(pAddress, pData, dwDataSize);
VirtualProtect(pAddress, dwDataSize, dwProtect, &dwProtect);
}
return dwDataSize;
}
DWORD MH_ReadMemory(void *pAddress, BYTE *pData, DWORD dwDataSize)
{
static DWORD dwProtect;
if (VirtualProtect(pAddress, dwDataSize, PAGE_EXECUTE_READWRITE, &dwProtect))
{
memcpy(pData, pAddress, dwDataSize);
VirtualProtect(pAddress, dwDataSize, dwProtect, &dwProtect);
}
return dwDataSize;
}
DWORD MH_GetVideoMode(int *width, int *height, int *bpp, bool *windowed)
{
static int iSaveMode;
static int iSaveWidth, iSaveHeight, iSaveBPP;
static bool bSaveWindowed;
if (g_bSaveVideo)
{
if (width)
*width = iSaveWidth;
if (height)
*height = iSaveHeight;
if (bpp)
*bpp = iSaveBPP;
if (windowed)
*windowed = bSaveWindowed;
}
else
{
const char *pszValues = registry->ReadString("EngineDLL", "hw.dll");
int iEngineD3D = registry->ReadInt("EngineD3D");
if (!strcmp(pszValues, "hw.dll"))
{
if (CommandLine()->CheckParm("-d3d") || (!CommandLine()->CheckParm("-gl") && iEngineD3D))
iSaveMode = VIDEOMODE_D3D;
else
iSaveMode = VIDEOMODE_OPENGL;
}
else
{
iSaveMode = VIDEOMODE_SOFTWARE;
}
bSaveWindowed = registry->ReadInt("ScreenWindowed") != false;
if (CommandLine()->CheckParm("-sw") || CommandLine()->CheckParm("-startwindowed") || CommandLine()->CheckParm("-windowed") || CommandLine()->CheckParm("-window"))
bSaveWindowed = true;
else if (CommandLine()->CheckParm("-full") || CommandLine()->CheckParm("-fullscreen"))
bSaveWindowed = false;
iSaveWidth = registry->ReadInt("ScreenWidth", 640);
if (CommandLine()->CheckParm("-width", &pszValues))
iSaveWidth = atoi(pszValues);
if (CommandLine()->CheckParm("-w", &pszValues))
iSaveWidth = atoi(pszValues);
iSaveHeight = registry->ReadInt("ScreenHeight", 480);
if (CommandLine()->CheckParm("-height", &pszValues))
iSaveHeight = atoi(pszValues);
if (CommandLine()->CheckParm("-h", &pszValues))
iSaveHeight = atoi(pszValues);
iSaveBPP = registry->ReadInt("ScreenBPP", 32);
if (CommandLine()->CheckParm("-16bpp"))
iSaveBPP = 16;
else if (CommandLine()->CheckParm("-24bpp"))
iSaveBPP = 24;
else if (CommandLine()->CheckParm("-32bpp"))
iSaveBPP = 32;
if (width)
*width = iSaveWidth;
if (height)
*height = iSaveHeight;
if (bpp)
*bpp = iSaveBPP;
if (windowed)
*windowed = bSaveWindowed;
g_bSaveVideo = true;
}
return iSaveMode;
}
CreateInterfaceFn MH_GetEngineFactory(void)
{
if (!g_bEngineIsBlob)
return (CreateInterfaceFn)GetProcAddress(g_hEngineModule, "CreateInterface");
static DWORD factoryAddr = 0;
if (!factoryAddr)
{
BlobHeader_t *pHeader = GetBlobHeader();
DWORD base = pHeader->m_dwExportPoint + 0x8;
factoryAddr = ((DWORD (*)(void))(base + *(DWORD *)base + 0x4))();
}
return (CreateInterfaceFn)factoryAddr;
}
DWORD MH_GetNextCallAddr(void *pAddress, DWORD dwCount)
{
static BYTE *pbAddress = NULL;
if (pAddress)
pbAddress = (BYTE *)pAddress;
else
pbAddress = pbAddress + 5;
for (DWORD i = 0; i < dwCount; i++)
{
BYTE code = *(BYTE *)pbAddress;
if (code == 0xFF && *(BYTE *)(pbAddress + 1) == 0x15)
{
return *(DWORD *)(pbAddress + 2);
}
if (code == 0xE8)
{
return (DWORD)(*(DWORD *)(pbAddress + 1) + pbAddress + 5);
}
pbAddress++;
}
return 0;
}
DWORD MH_GetEngineVersion(void)
{
if (!g_pfnbuild_number)
return 0;
return g_pfnbuild_number();
}
metahook_api_t gMetaHookAPI =
{
MH_UnHook,
MH_InlineHook,
MH_VFTHook,
MH_IATHook,
MH_GetClassFuncAddr,
MH_GetModuleBase,
MH_GetModuleSize,
MH_GetEngineModule,
MH_GetEngineBase,
MH_GetEngineSize,
MH_SearchPattern,
MH_WriteDWORD,
MH_ReadDWORD,
MH_WriteMemory,
MH_ReadMemory,
MH_GetVideoMode,
MH_GetEngineVersion,
MH_GetEngineFactory,
MH_GetNextCallAddr,
MH_WriteBYTE,
MH_ReadBYTE,
MH_WriteNOP,
};
C++
1
https://gitee.com/nagist/MetaHook.git
git@gitee.com:nagist/MetaHook.git
nagist
MetaHook
MetaHook
master

搜索帮助