TitanEngine/TitanEngine/TitanEngine.Hooks.cpp

1130 lines
55 KiB
C++

#include "stdafx.h"
#include "definitions.h"
#include "Global.Debugger.h"
#include "Global.Threader.h"
#include "Global.Engine.h"
#include "Global.Handle.h"
#include "Global.Mapping.h"
// Global.Engine.Hooks:
static std::vector<HOOK_ENTRY> hookEntry;
static DWORD buffPatchedEntrySize = 0x3000;
static void* CwpBuffPatchedEntry;
static void* buffPatchedEntry;
// Internal.Engine.Hook.functions:
static bool ProcessHookScanAddNewHook(PHOOK_ENTRY HookDetails, void* ptrOriginalInstructions, PLIBRARY_ITEM_DATAW ModuleInformation, DWORD SizeOfImage)
{
HOOK_ENTRY MyhookEntry = {};
RtlMoveMemory(&MyhookEntry, HookDetails, sizeof HOOK_ENTRY);
hookEntry.push_back(MyhookEntry);
return true;
}
// Global.Engine.Hook.functions:
__declspec(dllexport) bool TITCALL HooksSafeTransitionEx(LPVOID HookAddressArray, int NumberOfHooks, bool TransitionStart)
{
if(dbgProcessInformation.hProcess == NULL) //TODO: check
{
if(!TransitionStart || ThreaderImportRunningThreadData(GetCurrentProcessId()))
{
int threadcount=hListThread.size();
for(int i=0; i<threadcount; i++)
{
PTHREAD_ITEM_DATA hListThreadPtr=&hListThread.at(i);
if(hListThreadPtr->hThread != INVALID_HANDLE_VALUE)
{
if(TransitionStart)
{
if(hListThreadPtr->dwThreadId != GetCurrentThreadId())
{
SuspendThread(hListThreadPtr->hThread);
ULONG_PTR CurrentIP = (ULONG_PTR)GetContextDataEx(hListThreadPtr->hThread, UE_CIP);
PMEMORY_COMPARE_HANDLER myHookAddressArray = (PMEMORY_COMPARE_HANDLER)HookAddressArray;
for(int j=0; j<NumberOfHooks; j++)
{
#if defined (_WIN64)
ULONG_PTR HookAddress = (ULONG_PTR)myHookAddressArray->Array.qwArrayEntry[0];
myHookAddressArray = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)myHookAddressArray + sizeof ULONG_PTR);
#else
ULONG_PTR HookAddress = (ULONG_PTR)myHookAddressArray->Array.dwArrayEntry[0];
myHookAddressArray = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)myHookAddressArray + sizeof ULONG_PTR);
#endif
while(CurrentIP >= (ULONG_PTR)HookAddress && CurrentIP <= (ULONG_PTR)HookAddress + 5)
{
ResumeThread(hListThreadPtr->hThread);
Sleep(5);
SuspendThread(hListThreadPtr->hThread);
CurrentIP = (ULONG_PTR)GetContextDataEx(hListThreadPtr->hThread, UE_CIP);
j = 0;
}
}
}
}
else
{
ResumeThread(hListThreadPtr->hThread);
EngineCloseHandle(hListThreadPtr->hThread);
}
}
}
return true;
}
else
{
return false;
}
}
return false;
}
__declspec(dllexport) bool TITCALL HooksSafeTransition(LPVOID HookAddress, bool TransitionStart)
{
void* aHookAddress[1];
aHookAddress[0] = HookAddress;
return(HooksSafeTransitionEx(&aHookAddress[0], sizeof aHookAddress, TransitionStart));
}
__declspec(dllexport) bool TITCALL HooksIsAddressRedirected(LPVOID HookAddress)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress && hookEntry[i].IATHook == false && hookEntry[i].HookIsEnabled == true)
{
return true;
}
}
return false;
}
__declspec(dllexport) void* TITCALL HooksGetTrampolineAddress(LPVOID HookAddress)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress)
{
return(hookEntry[i].PatchedEntry);
}
}
return(NULL);
}
__declspec(dllexport) void* TITCALL HooksGetHookEntryDetails(LPVOID HookAddress)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress)
{
return(&hookEntry[i]);
}
}
return(NULL);
}
__declspec(dllexport) bool TITCALL HooksInsertNewRedirection(LPVOID HookAddress, LPVOID RedirectTo, int HookType)
{
#if !defined(_WIN64)
int j;
unsigned int i;
#endif
HOOK_ENTRY myHook = {};
DWORD CalculatedRealingJump;
ULONG_PTR x64CalculatedRealingJump;
ULONG_PTR RealignAddressTarget;
int ProcessedBufferSize = NULL;
int CurrentInstructionSize = NULL;
PMEMORY_COMPARE_HANDLER WriteMemory = (PMEMORY_COMPARE_HANDLER)CwpBuffPatchedEntry;
PMEMORY_COMPARE_HANDLER CompareMemory;
#if !defined(_WIN64)
PMEMORY_COMPARE_HANDLER RelocateMemory;
#endif
void* cHookAddress = HookAddress;
DWORD OldProtect = PAGE_READONLY;
void* TempBuffPatchedEntry;
bool returnData;
x64CalculatedRealingJump = NULL;
if(buffPatchedEntry == NULL || (ULONG_PTR)CwpBuffPatchedEntry - (ULONG_PTR)buffPatchedEntry + TEE_MAXIMUM_HOOK_SIZE > buffPatchedEntrySize)
{
buffPatchedEntrySize = buffPatchedEntrySize + 0x1000;
CwpBuffPatchedEntry = (void*)((ULONG_PTR)CwpBuffPatchedEntry - (ULONG_PTR)buffPatchedEntry);
TempBuffPatchedEntry = VirtualAlloc(NULL, buffPatchedEntrySize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(TempBuffPatchedEntry != NULL)
{
if(hookEntry.size() > NULL)
{
RtlMoveMemory(TempBuffPatchedEntry, buffPatchedEntry, (ULONG_PTR)CwpBuffPatchedEntry);
}
#if !defined(_WIN64)
for(i = 0; i < hookEntry.size(); i++)
{
hookEntry[i].PatchedEntry = (void*)((ULONG_PTR)hookEntry[i].PatchedEntry - (ULONG_PTR)buffPatchedEntry + (ULONG_PTR)TempBuffPatchedEntry);
CalculatedRealingJump = (DWORD)((ULONG_PTR)hookEntry[i].PatchedEntry - (ULONG_PTR)hookEntry[i].HookAddress - 5);
RtlMoveMemory(&hookEntry[i].HookBytes[1], &CalculatedRealingJump, 4);
if(hookEntry[i].RelocationCount > NULL)
{
for(j = 0; j < hookEntry[i].RelocationCount; j++)
{
CompareMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)buffPatchedEntry + hookEntry[i].RelocationInfo[j]);
RelocateMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)TempBuffPatchedEntry + hookEntry[i].RelocationInfo[j]);
CurrentInstructionSize = StaticLengthDisassemble((void*)CompareMemory);
RealignAddressTarget = (ULONG_PTR)GetJumpDestination(GetCurrentProcess(), (ULONG_PTR)CompareMemory);
if(RealignAddressTarget != NULL)
{
if(CompareMemory->Array.bArrayEntry[0] == 0xE9 && CurrentInstructionSize == 5)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)RelocateMemory - CurrentInstructionSize);
RtlMoveMemory(&RelocateMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
}
else if(CompareMemory->Array.bArrayEntry[0] >= 0x70 && CompareMemory->Array.bArrayEntry[0] <= 0x7F && CurrentInstructionSize == 2)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)RelocateMemory - CurrentInstructionSize);
RtlMoveMemory(&RelocateMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
}
else if(CompareMemory->Array.bArrayEntry[0] == 0x0F && CompareMemory->Array.bArrayEntry[1] >= 0x80 && CompareMemory->Array.bArrayEntry[1] <= 0x8F && CurrentInstructionSize == 6)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)RelocateMemory - CurrentInstructionSize);
RtlMoveMemory(&RelocateMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
}
else if(CompareMemory->Array.bArrayEntry[0] == 0xE8 && CurrentInstructionSize == 5)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)RelocateMemory - CurrentInstructionSize);
RtlMoveMemory(&RelocateMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
}
}
}
}
}
#endif
if(hookEntry.size() > NULL)
{
VirtualFree(buffPatchedEntry, NULL, MEM_RELEASE);
}
CwpBuffPatchedEntry = (void*)((ULONG_PTR)CwpBuffPatchedEntry + (ULONG_PTR)TempBuffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)CwpBuffPatchedEntry;
buffPatchedEntry = TempBuffPatchedEntry;
}
}
while(ProcessedBufferSize < TEE_MAXIMUM_HOOK_INSERT_SIZE)
{
CompareMemory = (PMEMORY_COMPARE_HANDLER)cHookAddress;
CurrentInstructionSize = StaticLengthDisassemble(cHookAddress);
RealignAddressTarget = (ULONG_PTR)GetJumpDestination(GetCurrentProcess(), (ULONG_PTR)cHookAddress);
if(RealignAddressTarget != NULL)
{
if(CompareMemory->Array.bArrayEntry[0] == 0xE9 && CurrentInstructionSize == 5)
{
if(cHookAddress == HookAddress)
{
if(HooksIsAddressRedirected(HookAddress))
{
if(HooksRemoveRedirection(HookAddress, false))
{
returnData = HooksInsertNewRedirection(HookAddress, RedirectTo, HookType);
if(returnData)
{
return true;
}
else
{
return false;
}
}
}
}
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - CurrentInstructionSize);
WriteMemory->Array.bArrayEntry[0] = 0xE9;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
myHook.RelocationInfo[myHook.RelocationCount] = (DWORD)((ULONG_PTR)WriteMemory - (ULONG_PTR)buffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
myHook.RelocationCount++;
}
else if(CompareMemory->Array.bArrayEntry[0] == 0xEB && CurrentInstructionSize == 2)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - 5);
WriteMemory->Array.bArrayEntry[0] = 0xE9;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
myHook.RelocationInfo[myHook.RelocationCount] = (DWORD)((ULONG_PTR)WriteMemory - (ULONG_PTR)buffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + 5);
myHook.RelocationCount++;
}
else if(CompareMemory->Array.bArrayEntry[0] >= 0x70 && CompareMemory->Array.bArrayEntry[0] <= 0x7F && CurrentInstructionSize == 2)
{
#if !defined(_WIN64)
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - 6);
WriteMemory->Array.bArrayEntry[0] = 0x0F;
WriteMemory->Array.bArrayEntry[1] = CompareMemory->Array.bArrayEntry[0] + 0x10;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
myHook.RelocationInfo[myHook.RelocationCount] = (DWORD)((ULONG_PTR)WriteMemory - (ULONG_PTR)buffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + 6);
myHook.RelocationCount++;
#else
x64CalculatedRealingJump = RealignAddressTarget;
WriteMemory->Array.bArrayEntry[0] = CompareMemory->Array.bArrayEntry[0];
WriteMemory->Array.bArrayEntry[1] = 0x02;
WriteMemory->Array.bArrayEntry[2] = 0xEB;
WriteMemory->Array.bArrayEntry[3] = 0x0E;
WriteMemory->Array.bArrayEntry[4] = 0xFF;
WriteMemory->Array.bArrayEntry[5] = 0x25;
RtlZeroMemory(&WriteMemory->Array.bArrayEntry[6], 4);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[10], &x64CalculatedRealingJump, sizeof x64CalculatedRealingJump);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + 18);
#endif
}
else if(CompareMemory->Array.bArrayEntry[0] == 0x0F && CompareMemory->Array.bArrayEntry[1] >= 0x80 && CompareMemory->Array.bArrayEntry[1] <= 0x8F && CurrentInstructionSize == 6)
{
#if !defined(_WIN64)
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - CurrentInstructionSize);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[0], &CompareMemory->Array.bArrayEntry[0], 2);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
myHook.RelocationInfo[myHook.RelocationCount] = (DWORD)((ULONG_PTR)WriteMemory - (ULONG_PTR)buffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
myHook.RelocationCount++;
#else
x64CalculatedRealingJump = RealignAddressTarget;
WriteMemory->Array.bArrayEntry[0] = CompareMemory->Array.bArrayEntry[0];
WriteMemory->Array.bArrayEntry[1] = CompareMemory->Array.bArrayEntry[1];
WriteMemory->Array.bArrayEntry[2] = 0x02;
WriteMemory->Array.bArrayEntry[3] = 0x00;
WriteMemory->Array.bArrayEntry[4] = 0x00;
WriteMemory->Array.bArrayEntry[5] = 0x00;
WriteMemory->Array.bArrayEntry[6] = 0xEB;
WriteMemory->Array.bArrayEntry[7] = 0x0E;
WriteMemory->Array.bArrayEntry[8] = 0xFF;
WriteMemory->Array.bArrayEntry[9] = 0x25;
RtlZeroMemory(&WriteMemory->Array.bArrayEntry[10], 4);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[14], &x64CalculatedRealingJump, sizeof x64CalculatedRealingJump);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + 22);
#endif
}
else if(CompareMemory->Array.bArrayEntry[0] == 0xE8 && CurrentInstructionSize == 5)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - CurrentInstructionSize);
WriteMemory->Array.bArrayEntry[0] = 0xE8;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
myHook.RelocationInfo[myHook.RelocationCount] = (DWORD)((ULONG_PTR)WriteMemory - (ULONG_PTR)buffPatchedEntry);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
myHook.RelocationCount++;
#if defined(_WIN64)
}
else if(CompareMemory->Array.bArrayEntry[0] == 0xFF && (CompareMemory->Array.bArrayEntry[1] == 0x15 || CompareMemory->Array.bArrayEntry[1] == 0x25) && CurrentInstructionSize == 6)
{
CalculatedRealingJump = (DWORD)((ULONG_PTR)RealignAddressTarget - (ULONG_PTR)WriteMemory - CurrentInstructionSize);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[0], &CompareMemory->Array.bArrayEntry[0], 2);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
#endif
}
else
{
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[0], cHookAddress, CurrentInstructionSize);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
}
}
else
{
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[0], cHookAddress, CurrentInstructionSize);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + CurrentInstructionSize);
}
cHookAddress = (void*)((ULONG_PTR)cHookAddress + CurrentInstructionSize);
ProcessedBufferSize = ProcessedBufferSize + CurrentInstructionSize;
}
if(ProcessedBufferSize >= TEE_MAXIMUM_HOOK_INSERT_SIZE)
{
WriteMemory->Array.bArrayEntry[0] = 0xFF;
WriteMemory->Array.bArrayEntry[1] = 0x25;
#if !defined(_WIN64)
CalculatedRealingJump = (DWORD)((ULONG_PTR)WriteMemory + 6);
#else
CalculatedRealingJump = NULL;
#endif
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[2], &CalculatedRealingJump, sizeof CalculatedRealingJump);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[6], &cHookAddress, sizeof CalculatedRealingJump);
WriteMemory = (PMEMORY_COMPARE_HANDLER)((ULONG_PTR)WriteMemory + 6 + sizeof ULONG_PTR);
myHook.HookIsEnabled = true;
myHook.HookType = (BYTE)HookType;
myHook.HookAddress = HookAddress;
myHook.RedirectionAddress = RedirectTo;
myHook.PatchedEntry = CwpBuffPatchedEntry;
myHook.HookSize = TEE_MAXIMUM_HOOK_SIZE;
RtlMoveMemory(&myHook.OriginalBytes[0], HookAddress, TEE_MAXIMUM_HOOK_SIZE);
CalculatedRealingJump = (DWORD)((ULONG_PTR)RedirectTo - (ULONG_PTR)HookAddress);
CwpBuffPatchedEntry = (void*)((ULONG_PTR)WriteMemory);
WriteMemory = (PMEMORY_COMPARE_HANDLER)HookAddress;
if(HookType == TEE_HOOK_NRM_JUMP)
{
#if !defined(_WIN64)
CalculatedRealingJump = CalculatedRealingJump - 5;
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
WriteMemory->Array.bArrayEntry[0] = 0xE9;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
RtlMoveMemory(&myHook.HookBytes[0], HookAddress, TEE_MAXIMUM_HOOK_SIZE);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.push_back(myHook);
return true;
}
#else
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
WriteMemory->Array.bArrayEntry[0] = 0xFF;
WriteMemory->Array.bArrayEntry[1] = 0x25;
RtlZeroMemory(&WriteMemory->Array.bArrayEntry[2], 4);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[6], &RedirectTo, sizeof RedirectTo);
RtlMoveMemory(&myHook.HookBytes[0], HookAddress, TEE_MAXIMUM_HOOK_SIZE);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.push_back(myHook);
return true;
}
#endif
}
else if(HookType == TEE_HOOK_NRM_CALL)
{
#if !defined(_WIN64)
CalculatedRealingJump = CalculatedRealingJump - 5;
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
WriteMemory->Array.bArrayEntry[0] = 0xE8;
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[1], &CalculatedRealingJump, sizeof CalculatedRealingJump);
RtlMoveMemory(&myHook.HookBytes[0], HookAddress, TEE_MAXIMUM_HOOK_SIZE);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.push_back(myHook);
return true;
}
#else
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
WriteMemory->Array.bArrayEntry[0] = 0xFF;
WriteMemory->Array.bArrayEntry[1] = 0x15;
RtlZeroMemory(&WriteMemory->Array.bArrayEntry[2], 4);
RtlMoveMemory(&WriteMemory->Array.bArrayEntry[6], &RedirectTo, sizeof RedirectTo);
RtlMoveMemory(&myHook.HookBytes[0], HookAddress, TEE_MAXIMUM_HOOK_SIZE);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.push_back(myHook);
return true;
}
#endif
}
}
return false;
}
__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirectionEx(ULONG_PTR FileMapVA, ULONG_PTR LoadedModuleBase, char* szHookFunction, LPVOID RedirectTo)
{
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_IMPORT_DESCRIPTOR ImportIID;
PIMAGE_THUNK_DATA32 ThunkData32;
PIMAGE_THUNK_DATA64 ThunkData64;
DWORD OldProtect = PAGE_READONLY;
ULONG_PTR CurrentThunk;
HOOK_ENTRY myHook = {};
BOOL FileIs64;
if(FileMapVA != NULL && LoadedModuleBase != NULL)
{
myHook.IATHook = true;
myHook.HookIsEnabled = true;
myHook.HookType = TEE_HOOK_IAT;
myHook.HookSize = sizeof ULONG_PTR;
myHook.RedirectionAddress = RedirectTo;
myHook.IATHookModuleBase = (void*)LoadedModuleBase;
myHook.IATHookNameHash = EngineHashString(szHookFunction);
DOSHeader = (PIMAGE_DOS_HEADER)FileMapVA;
if(EngineValidateHeader(FileMapVA, NULL, NULL, DOSHeader, true))
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
return false;
}
if(!FileIs64)
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader32->OptionalHeader.ImageBase), true);
__try
{
while(ImportIID->FirstThunk != NULL)
{
if(ImportIID->OriginalFirstThunk != NULL)
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->OriginalFirstThunk + PEHeader32->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
else
{
ThunkData32 = (PIMAGE_THUNK_DATA32)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->FirstThunk + PEHeader32->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
while(ThunkData32->u1.AddressOfData != NULL)
{
if(!(ThunkData32->u1.Ordinal & IMAGE_ORDINAL_FLAG32))
{
if(lstrcmpiA((char*)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ThunkData32->u1.AddressOfData + 2 + PEHeader32->OptionalHeader.ImageBase), true), szHookFunction) == NULL)
{
myHook.HookAddress = (void*)(CurrentThunk + LoadedModuleBase);
if(VirtualProtect(myHook.HookAddress, myHook.HookSize, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(&myHook.OriginalBytes[0], myHook.HookAddress, myHook.HookSize);
RtlMoveMemory(&myHook.HookBytes[0], &myHook.RedirectionAddress, myHook.HookSize);
RtlMoveMemory(myHook.HookAddress, &myHook.RedirectionAddress, myHook.HookSize);
VirtualProtect(myHook.HookAddress, myHook.HookSize, OldProtect, &OldProtect);
}
hookEntry.push_back(myHook);
}
}
CurrentThunk = CurrentThunk + 4;
ThunkData32 = (PIMAGE_THUNK_DATA32)((ULONG_PTR)ThunkData32 + sizeof IMAGE_THUNK_DATA32);
}
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
return true;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return false;
}
}
}
else
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL)
{
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + PEHeader64->OptionalHeader.ImageBase), true);
__try
{
while(ImportIID->FirstThunk != NULL)
{
if(ImportIID->OriginalFirstThunk != NULL)
{
ThunkData64 = (PIMAGE_THUNK_DATA64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->OriginalFirstThunk + PEHeader64->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->OriginalFirstThunk;
}
else
{
ThunkData64 = (PIMAGE_THUNK_DATA64)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ImportIID->FirstThunk + PEHeader64->OptionalHeader.ImageBase), true);
CurrentThunk = (ULONG_PTR)ImportIID->FirstThunk;
}
while(ThunkData64->u1.AddressOfData != NULL)
{
if(!(ThunkData64->u1.Ordinal & IMAGE_ORDINAL_FLAG64))
{
if(lstrcmpiA((char*)ConvertVAtoFileOffset(FileMapVA, (ULONG_PTR)((ULONG_PTR)ThunkData64->u1.AddressOfData + 2 + PEHeader64->OptionalHeader.ImageBase), true), szHookFunction) == NULL)
{
myHook.HookAddress = (void*)(CurrentThunk + LoadedModuleBase);
if(VirtualProtect(myHook.HookAddress, myHook.HookSize, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(&myHook.OriginalBytes[0], myHook.HookAddress, myHook.HookSize);
RtlMoveMemory(&myHook.HookBytes[0], &myHook.RedirectionAddress, myHook.HookSize);
RtlMoveMemory(myHook.HookAddress, &myHook.RedirectionAddress, myHook.HookSize);
VirtualProtect(myHook.HookAddress, myHook.HookSize, OldProtect, &OldProtect);
}
hookEntry.push_back(myHook);
}
}
CurrentThunk = CurrentThunk + 8;
ThunkData64 = (PIMAGE_THUNK_DATA64)((ULONG_PTR)ThunkData64 + sizeof IMAGE_THUNK_DATA64);
}
ImportIID = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG_PTR)ImportIID + sizeof IMAGE_IMPORT_DESCRIPTOR);
}
return true;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return false;
}
}
}
}
else
{
return false;
}
}
else
{
return false;
}
return false;
}
__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirection(char* szModuleName, char* szHookFunction, LPVOID RedirectTo)
{
HANDLE FileHandle;
DWORD FileSize;
HANDLE FileMap;
ULONG_PTR FileMapVA;
DWORD NewSectionVO = NULL;
DWORD NewSectionFO = NULL;
HMODULE SelectedModule = NULL;
SelectedModule = GetModuleHandleA(szModuleName);
if(SelectedModule != NULL)
{
if(MapFileEx(szModuleName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, NULL))
{
if(HooksInsertNewIATRedirectionEx(FileMapVA, (ULONG_PTR)SelectedModule, szHookFunction, RedirectTo))
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
return true;
}
else
{
UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA);
}
}
}
return false;
}
__declspec(dllexport) bool TITCALL HooksRemoveRedirection(LPVOID HookAddress, bool RemoveAll)
{
DWORD OldProtect = PAGE_READONLY;
if(!RemoveAll)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress && hookEntry[i].IATHook == false)
{
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.erase(hookEntry.begin() + i);
return true;
}
}
}
return false;
}
else
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
}
}
hookEntry.clear();
return true;
}
}
__declspec(dllexport) bool TITCALL HooksRemoveRedirectionsForModule(HMODULE ModuleBase)
{
int j = NULL;
unsigned int i = (unsigned int)hookEntry.size();
DWORD OldProtect = PAGE_READONLY;
MODULEINFO RemoteModuleInfo;
if(GetModuleInformation(GetCurrentProcess(), ModuleBase, &RemoteModuleInfo, sizeof MODULEINFO))
{
while(i > NULL)
{
if((ULONG_PTR)hookEntry[i].HookAddress >= (ULONG_PTR)ModuleBase && (ULONG_PTR)hookEntry[i].HookAddress <= (ULONG_PTR)ModuleBase + RemoteModuleInfo.SizeOfImage)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.erase(hookEntry.begin() + i);
j++;
}
}
i--;
}
if(j == NULL)
{
return false;
}
}
else
{
return false;
}
return true;
}
__declspec(dllexport) bool TITCALL HooksRemoveIATRedirection(char* szModuleName, char* szHookFunction, bool RemoveAll)
{
unsigned int i = (unsigned int)hookEntry.size() - 1;
DWORD OldProtect = PAGE_READONLY;
HMODULE ModuleBase = GetModuleHandleA(szModuleName);
DWORD FunctionNameHash = EngineHashString(szHookFunction);
if(ModuleBase != NULL)
{
while(i > 0)
{
if((hookEntry[i].IATHookModuleBase == (void*)ModuleBase && RemoveAll == true) || (hookEntry[i].IATHookNameHash == FunctionNameHash && hookEntry[i].IATHook == true))
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry.erase(hookEntry.begin() + i);
}
}
i--;
}
}
return false;
}
__declspec(dllexport) bool TITCALL HooksDisableRedirection(LPVOID HookAddress, bool DisableAll)
{
DWORD OldProtect = PAGE_READONLY;
if(!DisableAll)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress && hookEntry[i].HookIsEnabled == true)
{
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = false;
return true;
}
}
}
return false;
}
else
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = false;
}
}
return true;
}
}
__declspec(dllexport) bool TITCALL HooksDisableRedirectionsForModule(HMODULE ModuleBase)
{
int j = NULL;
unsigned int i = (unsigned int)hookEntry.size();
DWORD OldProtect = PAGE_READONLY;
MODULEINFO RemoteModuleInfo;
if(GetModuleInformation(GetCurrentProcess(), ModuleBase, &RemoteModuleInfo, sizeof MODULEINFO))
{
while(i > NULL)
{
if((ULONG_PTR)hookEntry[i].HookAddress >= (ULONG_PTR)ModuleBase && (ULONG_PTR)hookEntry[i].HookAddress <= (ULONG_PTR)ModuleBase + RemoteModuleInfo.SizeOfImage)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = false;
j++;
}
}
i--;
}
if(j == NULL)
{
return false;
}
}
else
{
return false;
}
return true;
}
__declspec(dllexport) bool TITCALL HooksDisableIATRedirection(char* szModuleName, char* szHookFunction, bool DisableAll)
{
unsigned int i = (unsigned int)hookEntry.size() - 1;
DWORD OldProtect = PAGE_READONLY;
HMODULE ModuleBase = GetModuleHandleA(szModuleName);
DWORD FunctionNameHash = EngineHashString(szHookFunction);
if(ModuleBase != NULL)
{
while(i > 0)
{
if((hookEntry[i].IATHookModuleBase == (void*)ModuleBase && DisableAll == true) || (hookEntry[i].IATHookNameHash == FunctionNameHash && hookEntry[i].IATHook == true))
{
if(hookEntry[i].HookIsEnabled)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].OriginalBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = false;
}
}
}
i--;
}
}
return false;
}
__declspec(dllexport) bool TITCALL HooksEnableRedirection(LPVOID HookAddress, bool EnableAll)
{
DWORD OldProtect = PAGE_READONLY;
if(!EnableAll)
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(hookEntry[i].HookAddress == HookAddress && hookEntry[i].HookIsEnabled == false)
{
if(VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(HookAddress, &hookEntry[i].HookBytes, hookEntry[i].HookSize);
VirtualProtect(HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = true;
return true;
}
}
}
return false;
}
else
{
for(unsigned int i = 0; i < hookEntry.size(); i++)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].HookBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = true;
}
}
return true;
}
}
__declspec(dllexport) bool TITCALL HooksEnableRedirectionsForModule(HMODULE ModuleBase)
{
int j = NULL;
unsigned int i = (unsigned int)hookEntry.size();
DWORD OldProtect = PAGE_READONLY;
MODULEINFO RemoteModuleInfo;
if(GetModuleInformation(GetCurrentProcess(), ModuleBase, &RemoteModuleInfo, sizeof MODULEINFO))
{
while(i > NULL)
{
if((ULONG_PTR)hookEntry[i].HookAddress >= (ULONG_PTR)ModuleBase && (ULONG_PTR)hookEntry[i].HookAddress <= (ULONG_PTR)ModuleBase + RemoteModuleInfo.SizeOfImage)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].HookBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = true;
j++;
}
}
i--;
}
if(j == NULL)
{
return false;
}
}
else
{
return false;
}
return true;
}
__declspec(dllexport) bool TITCALL HooksEnableIATRedirection(char* szModuleName, char* szHookFunction, bool EnableAll)
{
unsigned int i = (unsigned int)hookEntry.size() - 1;
DWORD OldProtect = PAGE_READONLY;
HMODULE ModuleBase = GetModuleHandleA(szModuleName);
DWORD FunctionNameHash = EngineHashString(szHookFunction);
if(ModuleBase != NULL)
{
while(i > 0)
{
if((hookEntry[i].IATHookModuleBase == (void*)ModuleBase && EnableAll == true) || (hookEntry[i].IATHookNameHash == FunctionNameHash && hookEntry[i].IATHook == true))
{
if(!hookEntry[i].HookIsEnabled)
{
if(VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
{
RtlMoveMemory(hookEntry[i].HookAddress, &hookEntry[i].HookBytes, hookEntry[i].HookSize);
VirtualProtect(hookEntry[i].HookAddress, TEE_MAXIMUM_HOOK_SIZE, OldProtect, &OldProtect);
hookEntry[i].HookIsEnabled = true;
}
}
}
i--;
}
}
return false;
}
__declspec(dllexport) void TITCALL HooksScanModuleMemory(HMODULE ModuleBase, LPVOID CallBack)
{
unsigned int i;
bool FileIs64 = false;
bool FileError = false;
void* pOriginalInstruction;
bool ManuallyMapped = false;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_NT_HEADERS32 PEHeader32;
PIMAGE_NT_HEADERS64 PEHeader64;
PIMAGE_EXPORT_DIRECTORY PEExports;
HANDLE hProcess = GetCurrentProcess();
LIBRARY_ITEM_DATA RemoteLibInfo = {};
PLIBRARY_ITEM_DATA pRemoteLibInfo = (PLIBRARY_ITEM_DATA)LibrarianGetLibraryInfoEx((void*)ModuleBase);
typedef bool(TITCALL *fEnumCallBack)(PHOOK_ENTRY HookDetails, void* ptrOriginalInstructions, PLIBRARY_ITEM_DATA ModuleInformation, DWORD SizeOfImage);
fEnumCallBack myEnumCallBack = (fEnumCallBack)CallBack;
BYTE CheckHookMemory[TEE_MAXIMUM_HOOK_SIZE];
PMEMORY_COMPARE_HANDLER ExportedFunctions;
PMEMORY_COMPARE_HANDLER FunctionMemory;
ULONG_PTR lpNumberOfBytesWritten;
HOOK_ENTRY MyhookEntry = {};
ULONG_PTR HookDestination;
MODULEINFO ModuleInfo;
BYTE HookType = NULL;
DWORD hSize;
if(pRemoteLibInfo == NULL)
{
RemoteLibInfo.BaseOfDll = (void*)ModuleBase;
GetModuleBaseNameA(hProcess, ModuleBase, &RemoteLibInfo.szLibraryName[0], MAX_PATH);
GetModuleFileNameExA(hProcess, ModuleBase, &RemoteLibInfo.szLibraryPath[0], MAX_PATH);
RemoteLibInfo.hFile = CreateFileA(RemoteLibInfo.szLibraryPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(RemoteLibInfo.hFile != INVALID_HANDLE_VALUE)
{
RemoteLibInfo.hFileMapping = CreateFileMappingA(RemoteLibInfo.hFile, NULL, 2, NULL, GetFileSize(RemoteLibInfo.hFile, NULL), NULL);
if(RemoteLibInfo.hFileMapping != NULL)
{
RemoteLibInfo.hFileMappingView = MapViewOfFile(RemoteLibInfo.hFileMapping, 4, NULL, NULL, NULL);
if(RemoteLibInfo.hFileMappingView == NULL)
{
CloseHandle(RemoteLibInfo.hFile);
CloseHandle(RemoteLibInfo.hFileMapping);
FileError = true;
}
else
{
ManuallyMapped = true;
}
}
else
{
CloseHandle(RemoteLibInfo.hFile);
FileError = true;
}
}
else
{
FileError = true;
}
}
else
{
RtlMoveMemory(&RemoteLibInfo, pRemoteLibInfo, sizeof LIBRARY_ITEM_DATA);
}
if(!FileError)
{
hSize = GetFileSize(RemoteLibInfo.hFile, NULL);
GetModuleInformation(hProcess, ModuleBase, &ModuleInfo, sizeof MODULEINFO);
DOSHeader = (PIMAGE_DOS_HEADER)RemoteLibInfo.hFileMappingView;
__try
{
PEHeader32 = (PIMAGE_NT_HEADERS32)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
PEHeader64 = (PIMAGE_NT_HEADERS64)((ULONG_PTR)DOSHeader + DOSHeader->e_lfanew);
if(PEHeader32->OptionalHeader.Magic == 0x10B)
{
FileIs64 = false;
}
else if(PEHeader32->OptionalHeader.Magic == 0x20B)
{
FileIs64 = true;
}
else
{
FileError = true;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
FileError = true;
}
if(!FileError)
{
FunctionMemory = (PMEMORY_COMPARE_HANDLER)&CheckHookMemory[0];
if(!FileIs64)
{
__try
{
if(PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, PEHeader32->OptionalHeader.ImageBase, PEHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, true, true);
if(PEExports != NULL)
{
ExportedFunctions = (PMEMORY_COMPARE_HANDLER)(ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, PEHeader32->OptionalHeader.ImageBase, PEExports->AddressOfFunctions, true, true));
for(i = 0; i < PEExports->NumberOfFunctions; i++)
{
if(ReadProcessMemory(hProcess, (void*)((ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]), &CheckHookMemory[0], TEE_MAXIMUM_HOOK_SIZE, &lpNumberOfBytesWritten))
{
if(FunctionMemory->Array.bArrayEntry[0] == 0xE9 || FunctionMemory->Array.bArrayEntry[0] == 0xE8)
{
HookDestination = (ULONG_PTR)GetJumpDestination(hProcess, (ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]);
if(HookDestination >= (ULONG_PTR)RemoteLibInfo.BaseOfDll && HookDestination <= (ULONG_PTR)RemoteLibInfo.BaseOfDll + (ULONG_PTR)ModuleInfo.SizeOfImage)
{
if(CallBack != NULL)
{
if(FunctionMemory->Array.bArrayEntry[0] == 0xE9)
{
HookType = TEE_HOOK_NRM_JUMP;
}
else
{
HookType = TEE_HOOK_NRM_CALL;
}
MyhookEntry.HookSize = 5;
MyhookEntry.HookType = HookType;
MyhookEntry.HookIsEnabled = true;
MyhookEntry.RedirectionAddress = (void*)HookDestination;
MyhookEntry.HookAddress = (void*)((ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]);
pOriginalInstruction = (void*)ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, PEHeader32->OptionalHeader.ImageBase, ExportedFunctions->Array.dwArrayEntry[i], true, true);
RtlZeroMemory(&MyhookEntry.HookBytes[0], TEE_MAXIMUM_HOOK_SIZE);
RtlMoveMemory(&MyhookEntry.HookBytes[0], &CheckHookMemory[0], MyhookEntry.HookSize);
RtlZeroMemory(&MyhookEntry.OriginalBytes[0], TEE_MAXIMUM_HOOK_SIZE);
RtlMoveMemory(&MyhookEntry.OriginalBytes[0], pOriginalInstruction, MyhookEntry.HookSize);
RelocaterRelocateMemoryBlock((ULONG_PTR)RemoteLibInfo.hFileMappingView, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase + ExportedFunctions->Array.dwArrayEntry[i], &MyhookEntry.OriginalBytes[0], MyhookEntry.HookSize, (ULONG_PTR)PEHeader32->OptionalHeader.ImageBase, (ULONG_PTR)RemoteLibInfo.BaseOfDll);
if(!myEnumCallBack(&MyhookEntry, pOriginalInstruction, &RemoteLibInfo, ModuleInfo.SizeOfImage))
{
break;
}
}
}
}
}
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
else
{
__try
{
if(PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != NULL)
{
PEExports = (PIMAGE_EXPORT_DIRECTORY)ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, PEHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, true, true);
if(PEExports != NULL)
{
ExportedFunctions = (PMEMORY_COMPARE_HANDLER)(ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, PEExports->AddressOfFunctions, true, true));
for(i = 0; i < PEExports->NumberOfFunctions; i++)
{
if(ReadProcessMemory(hProcess, (void*)((ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]), &CheckHookMemory[0], TEE_MAXIMUM_HOOK_SIZE, &lpNumberOfBytesWritten))
{
if(FunctionMemory->Array.bArrayEntry[0] == 0xE9 || FunctionMemory->Array.bArrayEntry[0] == 0xE8)
{
HookDestination = (ULONG_PTR)GetJumpDestination(hProcess, (ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]);
if(HookDestination >= (ULONG_PTR)RemoteLibInfo.BaseOfDll && HookDestination <= (ULONG_PTR)RemoteLibInfo.BaseOfDll + (ULONG_PTR)ModuleInfo.SizeOfImage)
{
if(CallBack != NULL)
{
if(FunctionMemory->Array.bArrayEntry[0] == 0xE9)
{
HookType = TEE_HOOK_NRM_JUMP;
}
else
{
HookType = TEE_HOOK_NRM_CALL;
}
MyhookEntry.HookSize = 5;
MyhookEntry.HookType = HookType;
MyhookEntry.HookIsEnabled = true;
MyhookEntry.RedirectionAddress = (void*)HookDestination;
MyhookEntry.HookAddress = (void*)((ULONG_PTR)RemoteLibInfo.BaseOfDll + ExportedFunctions->Array.dwArrayEntry[i]);
pOriginalInstruction = (void*)ConvertVAtoFileOffsetEx((ULONG_PTR)RemoteLibInfo.hFileMappingView, hSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, ExportedFunctions->Array.dwArrayEntry[i], true, true);
RtlZeroMemory(&MyhookEntry.HookBytes[0], TEE_MAXIMUM_HOOK_SIZE);
RtlMoveMemory(&MyhookEntry.HookBytes[0], &CheckHookMemory[0], MyhookEntry.HookSize);
RtlZeroMemory(&MyhookEntry.OriginalBytes[0], TEE_MAXIMUM_HOOK_SIZE);
RtlMoveMemory(&MyhookEntry.OriginalBytes[0], pOriginalInstruction, MyhookEntry.HookSize);
RelocaterRelocateMemoryBlock((ULONG_PTR)RemoteLibInfo.hFileMappingView, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase + ExportedFunctions->Array.dwArrayEntry[i], &MyhookEntry.OriginalBytes[0], MyhookEntry.HookSize, (ULONG_PTR)PEHeader64->OptionalHeader.ImageBase, (ULONG_PTR)RemoteLibInfo.BaseOfDll);
if(!myEnumCallBack(&MyhookEntry, pOriginalInstruction, &RemoteLibInfo, ModuleInfo.SizeOfImage))
{
break;
}
}
}
}
}
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
}
if(ManuallyMapped)
{
if(UnmapViewOfFile(RemoteLibInfo.hFileMappingView))
{
CloseHandle(RemoteLibInfo.hFileMapping);
CloseHandle(RemoteLibInfo.hFile);
}
}
}
}
__declspec(dllexport) void TITCALL HooksScanEntireProcessMemory(LPVOID CallBack)
{
unsigned int i;
DWORD cbNeeded = 0;
HMODULE EnumeratedModules[1024] = {0};
hookEntry.clear();
if(EnumProcessModules(GetCurrentProcess(), EnumeratedModules, sizeof(EnumeratedModules), &cbNeeded))
{
for(i = 1; i < (cbNeeded / sizeof(HMODULE)); i++)
{
HooksScanModuleMemory(EnumeratedModules[i], CallBack);
}
}
}
__declspec(dllexport) void TITCALL HooksScanEntireProcessMemoryEx()
{
HooksScanEntireProcessMemory(&ProcessHookScanAddNewHook);
}