2013-02-10 69 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