0

我想问一个关于 IAT 挂钩我自己的进程的问题。

我目前正在尝试挂钩 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;

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

4

1 回答 1

0

如果您的应用程序没有ExitProcess()静态调用,例如根本没有调用它(甚至没有被您的应用程序的 RTL 调用),或者如果它是通过 动态加载的GetProcAddress(),那么它就不会出现在您的应用程序的 IMPORTS 表中。IMPORTS 表仅列出您的应用静态链接到的函数。这可能是您的代码找不到它的原因。使用 PEDUMP 或 DependancyWalker 之类的实用程序来确保您的应用实际上是静态链接到ExitProcess(). 例如,在我的开发环境(C++Builder XE2)中,如果我创建了一个控制台项目,ExitProcess()则在 IMPORTS 表中找不到,但如果我创建了一个 GUI 项目,则可以找到它。ExitProcess()不同之处在于这两种类型的项目在底层使用了不同的 RTL,因此显然控制台 RTL在应用程序终止时不使用。

于 2013-02-11T06:40:13.537 回答