Delphi 将 VirtualProtect EAT 钩子例程从 C 转换为 Delphi 的问题 [英] Delphi problems converting VirtualProtect EAT hook routines from C to Delphi
问题描述
我正在尝试转换来自 CHook 论坛发布了这段代码,它执行 EAT 挂钩:
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);
}
从 c++ 到 Delphi,但我在 var 声明方面遇到了问题,特别是函数"var.
From c++ to Delp but I'm with problems at var declarations, specifically the "functions" var.
这是我的 Delphi 转换的不完整代码:
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;
尝试分配给 functions[i]
的行导致编译错误:
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?
推荐答案
您可以利用这样一个事实,即按顺序写入数组 functions
并递增指针而不是使用数组索引.
You can take advantage of the fact that you are writing to the array functions
in sequential order and increment the pointer rather than use array indexing.
functions := PDWORD(PAnsiChar(DosHeader)+dword(ExportDirectory.AddressOfFunctions));
for i := 0 to ExportDirectory.NumberOfFunctions-1 do begin
if not VirtualProtect(functions, sizeof(dword), PAGE_EXECUTE_READWRITE, @oldProtection) then begin
MessageBox(0, 'VirtualProtect failed', 'Error', 0);
exit;
end;
functions^ := DWORD(new_function) - DWORD(DosHeader);
if not VirtualProtect(functions, sizeof(dword), oldProtection, @oldProtection) then begin
MessageBox(0, 'VirtualProtect failed', 'Error', 0);
exit;
end;
inc(functions);
end;
这里的技巧是每次循环 functions
都指向数组中的第 ith 项.每次迭代完成后,inc(functions)
将指针移到下一项,为下一次迭代做好准备.
The trick here is that each time round the loop functions
points to the ith item in the array. When each iteration is done the inc(functions)
advances the pointer on to the next item, ready for the next iteration.
我还更正了您的 for
循环.在您的 Delphi 代码中,您执行的迭代次数过多.
I also corrected your for
loop. In your Delphi code you performing one iteration too many.
这篇关于Delphi 将 VirtualProtect EAT 钩子例程从 C 转换为 Delphi 的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!