Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #define MAX_HOOKS 1000
- typedef struct _HOOK_INFO
- {
- ULONG_PTR Function;
- ULONG_PTR Hook;
- ULONG_PTR OrigBytes;
- } HOOK_INFO, *PHOOK_INFO;
- HOOK_INFO HookInfo[MAX_HOOKS];
- UINT NumberOfHooks = 0;
- bool hookFailed = false;
- BYTE *pOrigBytesBuffer = NULL;
- HOOK_INFO *GetHookInfoFromFunction(ULONG_PTR OriginalFunction)
- {
- if (NumberOfHooks == 0)
- return NULL;
- for (UINT x = 0; x < NumberOfHooks; x++)
- {
- if (HookInfo[x].Function == OriginalFunction)
- return &HookInfo[x];
- }
- return NULL;
- }
- void WriteJump(void *pAddress, ULONG_PTR JumpTo)
- {
- // be extra safe and overwrite memory with a single memcpy
- BYTE *pJumpInstructionBuffer = (BYTE *)malloc(14);
- BYTE *pCur = pJumpInstructionBuffer;
- *pCur = 0xff; // jmp [rip+addr]
- *(++pCur) = 0x25;
- *((DWORD *) ++pCur) = 0; // addr = 0
- pCur += sizeof(DWORD);
- *((ULONG_PTR *)pCur) = JumpTo;
- DWORD dwOldProtect = 0;
- VirtualProtect(pAddress, 14, PAGE_EXECUTE_READWRITE, &dwOldProtect);
- memcpy(pAddress, pJumpInstructionBuffer, 14);
- DWORD dwBuf = 0;
- VirtualProtect(pAddress, 14, dwOldProtect, &dwBuf);
- free(pJumpInstructionBuffer);
- }
- void *BackupOrigBytes(ULONG_PTR originalFunction)
- {
- if (pOrigBytesBuffer == NULL) {
- pOrigBytesBuffer = (BYTE *)malloc(MAX_HOOKS * 14);
- }
- VOID *pOrigBytes = (VOID *)&pOrigBytesBuffer[NumberOfHooks * 14];
- memcpy(&pOrigBytesBuffer[NumberOfHooks * 14], (void *)originalFunction, 14);
- return pOrigBytes;
- }
- bool hookNative(UINT64 hash, ULONG_PTR hookFunction = NULL)
- {
- auto originalFunction = GetNativeHandler(hash);
- if (originalFunction == 0) {
- hookFailed = true;
- return false;
- }
- HOOK_INFO *hinfo = GetHookInfoFromFunction((ULONG_PTR) originalFunction);
- if (hinfo) {
- WriteJump(originalFunction, hinfo->Hook);
- }
- else
- {
- if (NumberOfHooks == (MAX_HOOKS - 1))
- return false;
- VOID *pOrigBytes = BackupOrigBytes((ULONG_PTR)originalFunction);
- HookInfo[NumberOfHooks].Function = (ULONG_PTR)originalFunction;
- HookInfo[NumberOfHooks].OrigBytes = (ULONG_PTR)pOrigBytes;
- HookInfo[NumberOfHooks].Hook = hookFunction;
- NumberOfHooks++;
- WriteJump(originalFunction, hookFunction);
- }
- return true;
- }
- void unhookNative(UINT64 hash) {
- auto originalFunction = GetNativeHandler(hash);
- HOOK_INFO *hinfo = GetHookInfoFromFunction((ULONG_PTR)originalFunction);
- DWORD dwOldProtect = 0;
- VirtualProtect(originalFunction, 14, PAGE_EXECUTE_READWRITE, &dwOldProtect);
- memcpy((void *)hinfo->Function, (void *)hinfo->OrigBytes, 14);
- DWORD dwBuf = 0;
- VirtualProtect(originalFunction, 14, dwOldProtect, &dwBuf);
- }
- void* __cdecl MY_IS_DLC_PRESENT(NativeContext *cxt)
- {
- Hash DlcHash = cxt->GetArgument<Hash>(0);
- if (DlcHash == 2532323046) { // DEV
- // game game requested dev dlc -> return true;
- cxt->SetResult(0, true);
- return cxt;
- }
- // restore original function
- unhookNative(0x2D6859674806FDCE);
- // get result of original function
- BOOL result = DLC2::IS_DLC_PRESENT(cxt->GetArgument<Hash>(0));
- cxt->SetResult(0, result);
- // hook us up again
- hookNative(0x2D6859674806FDCE);
- return cxt;
- }
- bool AttemptHookNatives() {
- static DWORD64 dwThreadCollectionPtr = 0;
- if (!dwThreadCollectionPtr) {
- // scan for GTA Thread Pool
- dwThreadCollectionPtr = Pattern::Scan(g_MainModuleInfo, "48 8B 05 ? ? ? ? 8B CA 4C 8B 0C C8 45 39 51 08");
- }
- if ( !dwThreadCollectionPtr
- || !Pattern::Scan(g_MainModuleInfo, "76 61 49 8B 7A 40 48 8D 0D") // scan for Native Registration Table
- ) {
- // too early. GetNativeHandler would log a fatal error and exit the process
- return false;
- }
- hookFailed = false;
- hookNative(0x2D6859674806FDCE, (ULONG_PTR)&MY_IS_DLC_PRESENT);
- // add more hooks here
- return !hookFailed;
- }
- DWORD WINAPI lpHookNatives(LPVOID lpParam) {
- while (!AttemptHookNatives()) {
- Sleep(100);
- }
- return 0;
- }
- void SpawnHookNatives() {
- CreateThread(0, 0, lpHookNatives, 0, 0, 0);
- }
Advertisement
Add Comment
Please, Sign In to add comment