2012-02-28 157 views
3

我试图把这段代码转换这些来自CHook论坛发布此代码确实EAT挂钩:德尔福问题转换VirtualProtect的EAT挂钩程序从C到德尔福

#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++到德尔福,但我m在var声明中存在问题,特别是“函数”变量。

这是我的德尔福转换残缺码:

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 

我该如何解决这个问题?

+1

你可以使用C++ builder编译C++代码并创建一个delphi接口吗? – Rudi 2012-02-28 15:07:27

+4

我在此保证downvote并投票结束所有“请转换代码”问题。 OP没有显示足够的努力。 – 2012-02-28 15:30:04

+3

@Warren我给你评论一个虚拟downvote。 paulohr对于SO来说是全新的,应该显示出一些松弛。更重要的是,paulohr对所有澄清请求做出了非常好的回应,并且付出了相当大的努力,见证了转换后的Delphi代码。我认为我们应该尽力帮助像保罗这样的人。 – 2012-02-28 15:35:07

回答

4

您可以利用这样一个事实,即您按顺序写入数组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点阵列中的第i个。当每次迭代完成时,inc(functions)使指针前进到下一个项目,为下一次迭代做好准备。

我也更正了您的for循环。在你的Delphi代码中,你执行一次迭代太多。

+0

嗨大卫,现在都是正确的吗? http://pastebin.com/WbmZ28Bv – paulohr 2012-02-28 15:30:18

+1

你很努力地回答这个问题,但我真的认为不应该鼓励OP(不要鼓励他/她之后的10K人)只问“转换我的C++ codez plz kthxbye”。 – 2012-02-28 15:30:48

+2

@WarrenP OP显然很挣扎,对C++没有深入的理解。当然,我们在这里提供帮助。至少我试图解释一下代码,你会看到在上一个问题中,我没有转换代码。至少直到OP尝试并提出一些错误的东西。 – 2012-02-28 15:32:27

0

有时候解决这个问题的最好方法是实际看看你想要在C++中做什么,并找到你需要的现有库(已经转换为Delphi)。

例如,您在此尝试执行的挂钩类型已由MadCodeHook库完成,这些库由Madshi在此处提供。他们现在只能在商业上使用,因为它们非常强大,而且他不想启用恶意软件。

+0

MadCodeHook挂钩EAT或IAT? – paulohr 2012-02-28 15:58:06

+1

去阅读文档,paulohr。 :-) – 2012-02-28 16:06:09