I can hook any other function, but not ExitProcess.
Here is the code to demonstrate this:
#include <iostream>
#include <cstdlib>
#include <Windows.h>
#include <Psapi.h>
void __stdcall NewSleep(DWORD milliseconds)
{
std::cout << "Sleep." << std::endl;
std::cin.get();
}
void __stdcall NewExitProcess(UINT exitCode)
{
std::cout << "ExitProcess." << std::endl;
std::cin.get();
}
FARPROC f1 = NULL;
FARPROC f2 = NULL;
int main()
{
HMODULE kernel32Module = GetModuleHandle("KERNEL32.dll");
f1 = GetProcAddress(kernel32Module, "Sleep");
f2 = GetProcAddress(kernel32Module, "ExitProcess");
std::cout << f1 << std::endl;
unsigned char* baseAddress = (unsigned char*)GetModuleHandle(NULL);
IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)baseAddress;
IMAGE_NT_HEADERS* inh = (IMAGE_NT_HEADERS*)(baseAddress + idh->e_lfanew);
IMAGE_IMPORT_DESCRIPTOR* iid = (IMAGE_IMPORT_DESCRIPTOR*)(baseAddress + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
for (IMAGE_IMPORT_DESCRIPTOR* i = iid; i->Name != 0; ++i)
{
std::string moduleName = (char*)(baseAddress + i->Name);
if (moduleName == "KERNEL32.dll")
{
IMAGE_THUNK_DATA* itd = (IMAGE_THUNK_DATA*)(baseAddress + i->FirstThunk);
for (IMAGE_THUNK_DATA* j = itd; j->u1.Function != 0; ++j)
{
if ((FARPROC)j->u1.Function == f1)
{
DWORD oldProtect = 0;
VirtualProtect(&j->u1.Function, sizeof(DWORD), PAGE_READWRITE, &oldProtect);
j->u1.Function = (DWORD)&NewSleep;
VirtualProtect(&j->u1.Function, sizeof(DWORD), oldProtect, &oldProtect);
}
if ((FARPROC)j->u1.Function == f2)
{
DWORD oldProtect = 0;
VirtualProtect(&j->u1.Function, sizeof(DWORD), PAGE_READWRITE, &oldProtect);
j->u1.Function = (DWORD)&NewExitProcess;
VirtualProtect(&j->u1.Function, sizeof(DWORD), oldProtect, &oldProtect);
}
}
break;
}
}
Sleep(0);
Sleep(0);
ExitProcess(0);
//Crash.
std::cin.sync();
std::cin.get();
return EXIT_SUCCESS;
}
It calls the hooked function, but when NewExitProcess returns I get an access violation. The calls to Sleep are fine, just like any hooked function other than ExitProcess.
EDIT: I get the same issue when hooking ExitThread though.