2012-02-28 154 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