Delphi 将 VirtualProtect EAT 钩子例程从 C 转换为 Delphi 的问题 [英] Delphi problems converting VirtualProtect EAT hook routines from C to Delphi

查看:27
本文介绍了Delphi 将 VirtualProtect EAT 钩子例程从 C 转换为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆