2013-02-10 66 views
0

我想問一個關於IAT掛鉤我自己的過程的問題。IAT掛鉤ExitProcess自己的過程

我目前正在嘗試掛鉤ExitProcess,因此它會在任何ExitProcess調用之前運行某個函數,並且我面臨一些麻煩。

我穿越在運行時的PE,通過IMAGE_IMPORT_DESCRIPTOR去, KERNEL32.DLL發現存在(這是第一個.dll文件),我穿越它THUNK_DATA-S的名字,試圖找到ExitProcess的存在後,雖然有沒有運氣。

記錄的功能,這些都是那些被發現存在的功能 -

GetModuleHandleA 
GetProcAddress 
LoadLibraryA 
GetModuleFileNameW 
FreeLibrary 
VirtualQuery 
GetProcessHeap 
HeapFree 
HeapAlloc 
GetSystemTimeAsFileTime 
GetCurrentThreadId 
GetCurrentProcessId 
QueryPerformanceCounter 
IsProcessorFeaturePresent 
WideCharToMultiByte 
MultiByteToWideChar 
LoadLibraryW 
lstrlenA 
LoadLibraryExW 
GetLastError 
RaiseException 
IsDebuggerPresent 
DecodePointer 
EncodePointer 
GetModuleHandleW 

雖然ExitProcess的是不通內。

我已經嘗試通過函數指針而不是名稱(使用thunkdata而不是originalthunkdata)枚舉,儘管它也失敗了。

ExitProcess的GetProcAddress會在PE內返回一個指針,並且我試圖通過loadlibrary強制加載kernel32.dll(雖然它應該被自動加載),儘管結果是一樣的。

可能是什麼問題?

HMODULE hMod = GetModuleHandle(NULL); 
PIMAGE_DOS_HEADER pImgDosHeaders = (PIMAGE_DOS_HEADER)hMod; 
PIMAGE_NT_HEADERS pImgNTHeaders = (PIMAGE_NT_HEADERS)((LPBYTE)pImgDosHeaders + pImgDosHeaders->e_lfanew); 
PIMAGE_IMPORT_DESCRIPTOR pImgImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)pImgDosHeaders + pImgNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 
UINT indx = 0; 
while(strcmpi((PCHAR)((LPBYTE)pImgDosHeaders + pImgImportDesc[indx].Name), "kernel32.dll")) { ++indx; }; 
PIMAGE_THUNK_DATA pImgThunkData = (PIMAGE_THUNK_DATA)((LPBYTE)pImgDosHeaders +pImgImportDesc[indx].OriginalFirstThunk); 
PIMAGE_IMPORT_BY_NAME pImgImportByName = NULL; 
for(;pImgThunkData->u1.Function; ++pImgThunkData) 
{ 
    pImgImportByName = (PIMAGE_IMPORT_BY_NAME)((LPBYTE)pImgDosHeaders + pImgThunkData->u1.AddressOfData); 
    !strcmpi("ExitProcess",pImgImportByName->Name) ? cout << "ExitProcess Found" : false; 
} 
return true; 

非常感謝你,祝你有美好的一天!

+0

您的程序使用什麼樣的運行時支持庫完全不清楚。其中將包含代碼來終止程序。它可能是一個單獨的DLL,在C/C++中很常見。程序通過簡單地從入口點返回或者通過調用TerminateProcess來結束它們自己。 – 2013-02-10 17:15:24

+1

@Hans:程序幾乎總是通過調用ExitProcess來結束自己。入口點永遠不會返回。 (大多數運行時支持庫允許某些由用戶提供的主函數返回,然後運行時調用ExitProcess,但用戶提供的返回的main函數不是入口點) – 2013-02-10 17:40:50

+0

您仍然可以使用atexit( )如果你正在使用crt,或者你可能喜歡做iat hooking,因爲這很有趣。我有一個工作代碼,但不幸的是,當窗口擰上磁盤時,它丟失了。 – sherpya 2013-02-11 06:09:18

回答

0

如果您的應用程序不調用ExitProcess()靜態,例如,如果它是不是在所有所謂的(即使不是由你的應用程序的RTL),或者如果它通過GetProcAddress()動態加載,那麼就不會出現在你的應用程序的輸入表。 IMPORTS表只列出了您的應用程序靜態鏈接到的功能。這可能是你的代碼沒有找到它的原因。使用像PEDUMP或DependancyWalker這樣的工具來確保你的應用程序實際上靜態鏈接到ExitProcess()。例如,在我的開發環境(C++ Builder XE2)中,如果我創建了一個控制檯項目,在IMPORTS表中找不到ExitProcess(),但如果我創建了一個GUI項目,則會找到它。不同之處在於兩種類型的項目在引擎下使用不同的RTL,因此顯然當應用程序終止時,控制檯RTL不使用ExitProcess()

+0

我個人從未見過一個不會調用ExitProcess()靜態的應用程序。 – JosephH 2013-02-11 06:43:00

+0

謝謝雷米!事實確實如此,直到現在我還以爲CRT會自動調用ExitProcess,儘管我猜想在這種情況下情況並非如此,通過調用exit()的代碼來調用doexit()等等......直到它達到了一些與__CRTDoExit()類似的強調功能,該功能處理程序的轉義。 我猜這些實際上是指向ExitProcess的指針,或者它們是在運行時評估的。 – 2013-02-11 17:32:43

+0

您必須查看CRT源代碼(如果供應商提供它),或者在ExitProcess()本身內部放置一個斷點以查看它是否被調用,但聽起來確實如此。 – 2013-02-11 17:55:41