【发布时间】:2013-02-10 13:51:03
【问题描述】:
我想问一个关于 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;
非常感谢您,祝您有美好的一天!
【问题讨论】:
-
完全不清楚你的程序使用什么样的运行时支持库。其中将包含终止程序的代码。它可以是一个单独的 DLL,在 C/C++ 中很常见。程序通过简单地从入口点返回或调用 TerminateProcess 来结束自己。
-
@Hans:程序几乎总是通过调用
ExitProcess来结束自己。入口点永远不会返回。 (大多数运行时支持库都允许用户提供某种main函数返回,然后运行时调用ExitProcess,但返回的用户提供的main函数不是入口点) -
如果你正在使用 crt,你仍然可以使用 atexit(),或者你可能更喜欢做 iat hooking,因为这很有趣。我有一个工作代码,但不幸的是,当 Windows 拧紧磁盘时它丢失了
标签: winapi hook portable-executable thunk api-hook