- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试转换来自 CHook 的代码论坛发布了这段代码,它执行 EAT Hook :
#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。
这是我的 Delphi 转换的不完整代码:
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]
的行导致编译错误:
[DCC Error]: E2016 Array type required
我该如何解决这个问题?
最佳答案
您可以利用以下事实:您正在按顺序写入数组 functions
并递增指针,而不是使用数组索引。
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)
将指针前进到下一项,为下一次迭代做好准备。
我还更正了您的 for
循环。在您的 Delphi 代码中,您执行的一次迭代过多。
关于c++ - 将 VirtualProtect EAT Hook 例程从 C 转换为 Delphi 的 Delphi 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9484319/
我最近购买了《C 编程语言》并尝试了 Ex 1-8这是代码 #include #include #include /* * */ int main() { int nl,nt,nb;
早上好!我有一个变量“var”,可能为 0。我检查该变量是否为空,如果不是,我将该变量保存在 php session 中,然后调用另一个页面。在这个新页面中,我检查我创建的 session 是否为空,
我正在努力完成 Learn Python the Hard Way ex.25,但我无法理解某些事情。这是脚本: def break_words(stuff): """this functio
我是一名优秀的程序员,十分优秀!