Skip to content

Commit

Permalink
export BlobThreadManager
Browse files Browse the repository at this point in the history
  • Loading branch information
hzqst committed Dec 23, 2023
1 parent 9871246 commit 2b76ddc
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 35 deletions.
56 changes: 50 additions & 6 deletions include/metahook.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,52 @@ typedef void (*DisasmSingleCallback)(void *inst, PUCHAR address, size_t instLen,
typedef BOOL (*DisasmCallback)(void *inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context);
typedef BOOL (*FindAddressCallback)(PUCHAR address);

typedef struct blob_thread_manager_api_s
{
void (*InitBlobThreadManager)(void);
void (*ShutdownBlobThreadManager)(void);
void (*EnterCritSection)(void);
void (*LeaveCritSection)(void);
bool (*FindAliveThread)(HANDLE hThread);
bool (*FindAndRemoveAliveThread)(HANDLE hThread);
bool (*AddAliveThread)(HANDLE hThread);
bool (*FindClosedThread)(HANDLE hThread);
bool (*AddClosedThread)(HANDLE hThread);
bool (*FindAndRemoveSignaledAliveThread)(DWORD* pIndex);
bool (*FindAndRemoveSignaledClosedThread)(DWORD* pIndex);

HANDLE(WINAPI** PointerToOriginalCreateThread)(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);

BOOL(WINAPI** PointerToOriginalCloseHandle)(HANDLE hObject);

BOOL(WINAPI** PointerToOriginalTerminateThread)( HANDLE hThread, DWORD dwExitCode );

HANDLE(WINAPI* BlobCreateThread)(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);

BOOL (WINAPI* BlobCloseHandle)(HANDLE hObject);

BOOL (WINAPI* BlobTerminateThread)( HANDLE hThread, DWORD dwExitCode );

}blob_thread_manager_api_t;

typedef struct metahook_api_s
{
BOOL (*UnHook)(hook_t *pHook);

hook_t *(*InlineHook)(void *pOldFuncAddr, void *pNewFuncAddr, void **pOrginalCall);
/*
Install JMP hook at begin of function,
Expand Down Expand Up @@ -283,15 +326,17 @@ typedef struct metahook_api_s
Basically the name
*/

bool(*RegisterCvarCallback)(const char* cvar_name, cvar_callback_t callback, cvar_callback_t *poldcallback);
bool(*RegisterCvarCallback)(const char* cvar_name, cvar_callback_t callback, cvar_callback_t *pOldCallback);
/*
Find existing cvar, and register a Cvar-Set callback for it, return original callback function pointer in the poldcallback if exists.
Find existing cvar, and register a Cvar-Set callback for it, return original callback function pointer in the pOldCallback if exists.
Register on existing callback will override the old one (the old one will be in poldcallback)
Important: Cvar-Set callback only get called when changing cvar value from console.
*/
}
metahook_api_t;

blob_thread_manager_api_t* BlobThreadManagerAPI;

}metahook_api_t;

typedef struct mh_enginesave_s
{
Expand All @@ -317,8 +362,7 @@ typedef struct mh_interface_s
IFileSystem *FileSystem;
IRegistry *Registry;
IFileSystem_HL25* FileSystem_HL25;
}
mh_interface_t;
}mh_interface_t;

#include <IPlugins.h>

Expand Down
4 changes: 4 additions & 0 deletions src/LoadBlob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ BlobHandle_t LoadBlobFromBuffer(BYTE* pBuffer, DWORD dwBufferSize, PVOID BlobSec
{
pThunk->u1.AddressOfData = (DWORD)BlobCreateThread;
}
else if (!bIsLoadByOrdinal && !strcmp(pszProcName, "TerminateThread"))
{
pThunk->u1.AddressOfData = (DWORD)BlobTerminateThread;
}
else if (!bIsLoadByOrdinal && !strcmp(pszProcName, "CloseHandle"))
{
pThunk->u1.AddressOfData = (DWORD)BlobCloseHandle;
Expand Down
84 changes: 55 additions & 29 deletions src/metahook.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "metahook.h"
#include "LoadBlob.h"
#include "BlobThreadManager.h"
#include <detours.h>
#include "interface.h"
#include <capstone.h>
Expand Down Expand Up @@ -1535,6 +1536,12 @@ void MH_LoadEngine(HMODULE hEngineModule, BlobHandle_t hBlobEngine, const char *
}

MH_InlineHook(g_pfnClientDLL_Init, MH_ClientDLL_Init, (void **)&g_original_ClientDLL_Init);

if (g_hEngineModule)
{
MH_IATHook(g_hEngineModule, "kernel32.dll", "CreateThread", BlobCreateThread, NULL);
MH_IATHook(g_hEngineModule, "kernel32.dll", "TerminateThread", BlobTerminateThread, NULL);
}

MH_LoadPlugins(szGameName);

Expand Down Expand Up @@ -1687,11 +1694,16 @@ void MH_Shutdown(void)

hook_t *MH_NewHook(int iType)
{
hook_t *h = new hook_t;
hook_t *h = new (std::nothrow) hook_t;
if (!h)
return NULL;

memset(h, 0, sizeof(hook_t));
h->iType = iType;
h->pNext = g_pHookBase;

g_pHookBase = h;

return h;
}

Expand Down Expand Up @@ -1874,18 +1886,27 @@ hook_t *MH_VFTHook(void *pClass, int iTableIndex, int iFuncIndex, void *pNewFunc

hook_t *MH_IATHook(HMODULE hModule, const char *pszModuleName, const char *pszFuncName, void *pNewFuncAddr, void **pOrginalCall)
{
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);
auto pNtHeader = RtlImageNtHeader(hModule);//(IMAGE_NT_HEADERS *)((ULONG_PTR)hModule + ((IMAGE_DOS_HEADER *)hModule)->e_lfanew);

while (pImport->Name && stricmp((const char *)((DWORD)hModule + pImport->Name), pszModuleName))
if (!pNtHeader)
return NULL;

auto pImport = (IMAGE_IMPORT_DESCRIPTOR *)((ULONG_PTR)hModule + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

while (pImport->Name && stricmp((const char *)((ULONG_PTR)hModule + pImport->Name), pszModuleName))
pImport++;

ULONG_PTR dwFuncAddr = (ULONG_PTR)GetProcAddress(GetModuleHandle(pszModuleName), pszFuncName);
auto hProcModule = GetModuleHandle(pszModuleName);

if(!hProcModule)
return NULL;

ULONG_PTR dwFuncAddr = (ULONG_PTR)GetProcAddress(hProcModule, pszFuncName);

if (!dwFuncAddr)
return NULL;

IMAGE_THUNK_DATA *pThunk = (IMAGE_THUNK_DATA *)((DWORD)hModule + pImport->FirstThunk);
auto pThunk = (IMAGE_THUNK_DATA *)((ULONG_PTR)hModule + pImport->FirstThunk);

while (pThunk->u1.Function != dwFuncAddr)
pThunk++;
Expand All @@ -1901,10 +1922,12 @@ hook_t *MH_IATHook(HMODULE hModule, const char *pszModuleName, const char *pszFu
h->pszModuleName = pszModuleName;
h->pszFuncName = pszFuncName;

*pOrginalCall = h->pOldFuncAddr;
if(pOrginalCall)
*pOrginalCall = h->pOldFuncAddr;

h->bCommitted = true;

MH_WriteMemory(info->pAPIInfoAddr, (BYTE *)&pNewFuncAddr, sizeof(DWORD));
MH_WriteMemory(info->pAPIInfoAddr, (BYTE *)&pNewFuncAddr, sizeof(ULONG_PTR));
return h;
}

Expand Down Expand Up @@ -2030,88 +2053,88 @@ void *MH_ReverseSearchPattern(void *pStartSearch, DWORD dwSearchLen, const char

void MH_WriteDWORD(void *pAddress, DWORD dwValue)
{
DWORD dwProtect;
DWORD dwOldProtect = 0;

if (VirtualProtect((void *)pAddress, 4, PAGE_EXECUTE_READWRITE, &dwProtect))
if (VirtualProtect((void *)pAddress, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
*(DWORD *)pAddress = dwValue;
VirtualProtect((void *)pAddress, 4, dwProtect, &dwProtect);
VirtualProtect((void *)pAddress, 4, dwOldProtect, &dwOldProtect);
}
}

DWORD MH_ReadDWORD(void *pAddress)
{
DWORD dwProtect;
DWORD dwOldProtect = 0;
DWORD dwValue = 0;

if (VirtualProtect((void *)pAddress, 4, PAGE_EXECUTE_READWRITE, &dwProtect))
if (VirtualProtect((void *)pAddress, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
dwValue = *(DWORD *)pAddress;
VirtualProtect((void *)pAddress, 4, dwProtect, &dwProtect);
VirtualProtect((void *)pAddress, 4, dwOldProtect, &dwOldProtect);
}

return dwValue;
}

void MH_WriteBYTE(void *pAddress, BYTE ucValue)
{
DWORD dwProtect;
DWORD dwOldProtect = 0;

if (VirtualProtect((void *)pAddress, 1, PAGE_EXECUTE_READWRITE, &dwProtect))
if (VirtualProtect((void *)pAddress, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
*(BYTE *)pAddress = ucValue;
VirtualProtect((void *)pAddress, 1, dwProtect, &dwProtect);
VirtualProtect((void *)pAddress, 1, dwOldProtect, &dwOldProtect);
}
}

BYTE MH_ReadBYTE(void *pAddress)
{
DWORD dwProtect;
DWORD dwOldProtect = 0;
BYTE ucValue = 0;

if (VirtualProtect((void *)pAddress, 1, PAGE_EXECUTE_READWRITE, &dwProtect))
if (VirtualProtect((void *)pAddress, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
ucValue = *(BYTE *)pAddress;
VirtualProtect((void *)pAddress, 1, dwProtect, &dwProtect);
VirtualProtect((void *)pAddress, 1, dwOldProtect, &dwOldProtect);
}

return ucValue;
}

void MH_WriteNOP(void *pAddress, DWORD dwCount)
{
static DWORD dwProtect;
DWORD dwOldProtect = 0;

if (VirtualProtect(pAddress, dwCount, PAGE_EXECUTE_READWRITE, &dwProtect))
if (VirtualProtect(pAddress, dwCount, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
for (DWORD i = 0; i < dwCount; i++)
*(BYTE *)((DWORD)pAddress + i) = 0x90;

VirtualProtect(pAddress, dwCount, dwProtect, &dwProtect);
VirtualProtect(pAddress, dwCount, dwOldProtect, &dwOldProtect);
}
}

DWORD MH_WriteMemory(void *pAddress, void *pData, DWORD dwDataSize)
{
static DWORD dwProtect;
DWORD dwOldProtect = 0;

if (VirtualProtect(pAddress, dwDataSize, PAGE_EXECUTE_READWRITE, &dwProtect))
if (VirtualProtect(pAddress, dwDataSize, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
memcpy(pAddress, pData, dwDataSize);
VirtualProtect(pAddress, dwDataSize, dwProtect, &dwProtect);
VirtualProtect(pAddress, dwDataSize, dwOldProtect, &dwOldProtect);
}

return dwDataSize;
}

DWORD MH_ReadMemory(void *pAddress, void *pData, DWORD dwDataSize)
{
static DWORD dwProtect;
DWORD dwOldProtect = 0;

if (VirtualProtect(pAddress, dwDataSize, PAGE_EXECUTE_READWRITE, &dwProtect))
if (VirtualProtect(pAddress, dwDataSize, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
memcpy(pData, pAddress, dwDataSize);
VirtualProtect(pAddress, dwDataSize, dwProtect, &dwProtect);
VirtualProtect(pAddress, dwDataSize, dwOldProtect, &dwOldProtect);
}

return dwDataSize;
Expand Down Expand Up @@ -2882,6 +2905,8 @@ BOOL MH_GetPluginInfo(const char *name, mh_plugininfo_t *info)
return FALSE;
}

extern blob_thread_manager_api_t g_BlobThreadManagerAPI;

metahook_api_t gMetaHookAPI =
{
MH_UnHook,
Expand Down Expand Up @@ -2926,4 +2951,5 @@ metahook_api_t gMetaHookAPI =
MH_ReverseSearchFunctionBeginEx,
MH_IsDebuggerPresent,
MH_RegisterCvarCallback,
&g_BlobThreadManagerAPI,
};

0 comments on commit 2b76ddc

Please sign in to comment.