0

I`d like to ask a question regarding IAT hooking on my own process .

I am currently trying to hook ExitProcess so it would run a certain function before any ExitProcess call, and I am facing some troubles .

I am traversing the PE at runtime, going through the IMAGE_IMPORT_DESCRIPTOR , after finding kernel32.dll there (which is the first .dll) I am traversing it THUNK_DATA-s by name, trying to find ExitProcess there, though with no luck.

Logging the functions, those are the functions which are found there -

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

Though ExitProcess is nowhere within .

I have tried enumerating by function pointers instead of the names (using thunkdata instead of originalthunkdata) though it has failed as well.

GetProcAddress for ExitProcess does return a pointer within the PE, and I have tried to load kernel32.dll forcefully (though it should be loaded automatically) by loadlibrary, though the result is the same.

What could be the problem ?

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;

Thank you so very much and have a great day !

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Danny Shemesh
  • 67
  • 1
  • 9
  • It is completely unclear what kind of runtime support library your program uses. Which would contain the code to get the program terminated. It could be a separate DLL, common in C/C++. And programs end themselves by simply returning from the entrypoint or by calling TerminateProcess. – Hans Passant Feb 10 '13 at 17:15
  • 1
    @Hans: Programs almost always end themselves by calling `ExitProcess`. The entrypoint never returns. (Most runtime support libraries allow some sort of main function provided by the user to return, and then the runtime calls `ExitProcess`, but the user-provided `main` function which returns is not the entrypoint) – Ben Voigt Feb 10 '13 at 17:40
  • you can still use atexit() if you are using the crt, or you maye like instead to do iat hooking because is interesting. I had a working code but unfortunately it went lost when windows screwed the disk – sherpya Feb 11 '13 at 06:09

1 Answers1

0

If your app does not call ExitProcess() statically, such as if it is not called at all (not even by your app's RTL) or if it is loaded dynamically via GetProcAddress(), then it will not be present in your app's IMPORTS table. The IMPORTS table only lists functions that your app statically links to. That is likely why your code does not find it. Use a utility like PEDUMP or DependancyWalker to make sure your app is actually statically linking to ExitProcess(). For example, in my dev environment (C++Builder XE2), if I create a console project, ExitProcess() is not found in the IMPORTS table, but if I create a GUI project instead then it is found. The difference is that the two types of project use different RTLs under the hood, so apparently the console RTL does not use ExitProcess() when the app terminates.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I've personally never seen an application that does not call `ExitProcess()` statically. – JosephH Feb 11 '13 at 06:43
  • Thank you Remy ! That was indeed the case , till now I have thought that the CRT will automatically call ExitProcess though I guess that is not the case in this scenario , following through the code it calls exit() which calls doexit() etc... till it reaches some underscored function similar to __CRTDoExit() which handles the escape of the program . I guess non of those are actually pointers to ExitProcess or they are evaluated in runtime . – Danny Shemesh Feb 11 '13 at 17:32
  • You would have to look at the CRT source code (if the vendor supplies it), or put a breakpoint inside of `ExitProcess()` itself to see if it is being called, but it does sound like it is not. – Remy Lebeau Feb 11 '13 at 17:55