I’m trying to convert this code which came from CHook forum posting this code which does EAT hooking:
#include <Windows.h>
#include <Psapi.h>
#include <string>
#if PSAPI_VERSION == 1
#pragma comment(lib, "Psapi.lib")
#endif
template <typename DestType, typename SrcType>
DestType* ByteOffset(SrcType* ptr, ptrdiff_t offset)
{
return reinterpret_cast<DestType*>(reinterpret_cast<unsigned char*>(ptr) + offset);
}
bool eat_hook(void* old_function, void* new_function)
{
HMODULE hModule;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)old_function, &hModule);
PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS NtHeader = ByteOffset<IMAGE_NT_HEADERS>(DosHeader, DosHeader->e_lfanew);
if (IMAGE_NT_SIGNATURE != NtHeader->Signature)
{
MessageBox(0, "Bad NT header signature", "Error", 0);
return false;
}
PIMAGE_EXPORT_DIRECTORY ExportDirectory = ByteOffset<IMAGE_EXPORT_DIRECTORY>(DosHeader,
NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
DWORD* functions = ByteOffset<DWORD>(DosHeader, ExportDirectory->AddressOfFunctions);
for (size_t i = 0; i < ExportDirectory->NumberOfFunctions; ++i)
{
if (functions[i] == (DWORD)old_function - (DWORD)hModule)
{
DWORD oldProtection;
if (!VirtualProtect(functions + i, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &oldProtection))
{
MessageBox(0, "VirtualProtect failed", "Error", 0);
return false;
}
functions[i] = reinterpret_cast<DWORD>(new_function) - reinterpret_cast<DWORD>(DosHeader);
if (!VirtualProtect(functions + i, sizeof(DWORD), oldProtection, &oldProtection))
{
MessageBox(0, "VirtualProtect failed", "Error", 0);
return false;
}
return true;
}
}
return false;
}
bool iat_hook(void* old_function, void* new_function)
{
HMODULE hModule;
DWORD sizeNeeded;
if (0 == EnumProcessModules(GetCurrentProcess(), &hModule, sizeof(hModule), &sizeNeeded))
{
MessageBox(0, "EnumProcessModules failed", "Error", 0);
return false;
}
PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS NtHeader = ByteOffset<IMAGE_NT_HEADERS>(DosHeader, DosHeader->e_lfanew);
if (IMAGE_NT_SIGNATURE != NtHeader->Signature)
{
MessageBox(0, "Bad NT header signature", "Error", 0);
return false;
}
PIMAGE_IMPORT_DESCRIPTOR ImportDirectory = ByteOffset<IMAGE_IMPORT_DESCRIPTOR>(DosHeader,
NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
for (size_t i = 0; ImportDirectory[i].Characteristics; ++i)
{
PIMAGE_THUNK_DATA thunk = ByteOffset<IMAGE_THUNK_DATA>(hModule, ImportDirectory[i].FirstThunk);
PIMAGE_THUNK_DATA origThunk = ByteOffset<IMAGE_THUNK_DATA>(hModule, ImportDirectory[i].OriginalFirstThunk);
for (; origThunk->u1.Function; origThunk++, thunk++)
{
if (thunk->u1.Function == (DWORD)old_function)
{
DWORD oldProtection;
if (!VirtualProtect(&thunk->u1.Function, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &oldProtection))
{
MessageBox(0, "VirtualProtect failed", "Error", 0);
return false;
}
thunk->u1.Function = reinterpret_cast<DWORD>(new_function);
if (!VirtualProtect(&thunk->u1.Function, sizeof(DWORD), oldProtection, &oldProtection))
{
MessageBox(0, "VirtualProtect failed", "Error", 0);
return false;
}
return true;
}
}
}
return false;
}
bool hook(void* old_function, void* new_function)
{
return eat_hook(old_function, new_function) && iat_hook(old_function, new_function);
}
From c++ to Delphi, but I’m with problems at var declarations, specifically the “functions” var.
This is my Delphi-converted INCOMPLETE code:
function eat_hook(old_function, new_function:pointer):boolean;
var
Module: HMODULE;
DosHeader: PImageDosHeader;
NtHeaders: PImageNtHeaders;
ExportDirectory: PImageExportDirectory;
functions: PDWORD;
i: size_t;
oldProtection: DWORD;
begin
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, pointer(old_function), Module);
DosHeader := PImageDosHeader(Module);
NTHeaders := PImageNtHeaders(DWORD(DOSHeader) + DWORD(DOSHeader^._lfanew));
if IMAGE_NT_SIGNATURE <> NtHeaders.Signature then begin
MessageBox(0, 'Bad NT header signature', 'Error', 0);
exit;
end;
ExportDirectory := PImageExportDirectory(PAnsiChar(DosHeader) + NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
functions := PDWORD(PAnsiChar(DosHeader)+dword(ExportDirectory.AddressOfFunctions));
for i:=0 to ExportDirectory.NumberOfFunctions do begin
if not VirtualProtect(functions, sizeof(dword), PAGE_EXECUTE_READWRITE, @oldProtection) then begin
MessageBox(0, 'VirtualProtect failed', 'Error', 0);
exit;
end;
functions[i] := DWORD(new_function) - DWORD(DosHeader);
if not VirtualProtect(pointer(functions), sizeof(dword), oldProtection, @oldProtection) then begin
MessageBox(0, 'VirtualProtect failed', 'Error', 0);
exit;
end;
end;
end;
The line which attempts to assign to functions[i] results in a compilation error:
[DCC Error]: E2016 Array type required
How can I fix this?
You can take advantage of the fact that you are writing to the array
functionsin sequential order and increment the pointer rather than use array indexing.The trick here is that each time round the loop
functionspoints to the ith item in the array. When each iteration is done theinc(functions)advances the pointer on to the next item, ready for the next iteration.I also corrected your
forloop. In your Delphi code you performing one iteration too many.