I will just give the code to hook NtTerminateProcess although, you need to manage the callback. As that is the "real" part of this hook.
- First we will be unprotecting the target address (Nt\ZwTerminateProcess)
- Replace first instruction - mov eax, 29h
with jmp [callback address]
- Finally re-protecting the target address with it's previous\original protection level
DWORD NtHookInstall(LPVOID lpTargetAddress,LPVOID lpCallbackAddress)
if(lpTargetAddress == 0 || lpCallbackAddress == 0) return 0; //Misc. Check
DWORD dwOldProtection = 0;
if(VirtualProtect(lpTargetAddress,7,PAGE_EXECUTE_READWRITE,&dwOldProtection) == 0) return 0;
*(BYTE*)(lpTargetAddress)= 0xE9; // Opcode for JMP
*(long*)((LPBYTE)lpTargetAddress+1) = ((DWORD)lpCallbackAddress - ((DWORD)lpTargetAddress + 5));
VirtualProtect(lpTargetAddress,7,dwOldProtection,&dwOldProtection); //reinstate original protection
return 1; // SUCCESS
***NOTE*** The above code works with all NT functions, although you need to work with the callback
NtHookInstall(GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"ZwTerminateProcess"), (LPVOID) Callback);
The code, given is ONLY
for local hooking, if you wish to make it System-Wide hook\Global hook, you can use several methods to do so these include:
- PE Injection
- Code Injection
- DLL Injection
For the PE & Code Injection, the code is more or less straight forward but for DLL Injection, you need to convert the above into a DLL. Then inject the DLL into all processes in the memory.
Lastly, I would highly recommend you learn & understand assembly (both x64 & x86), this would massively help you when doing this sort of stuff.
At the moment you are copy & pasting with minimal knowledge of working behind this.
The Callback should ideally be only assembly and set it as
mainly because, it would exist as a simple stub in the memory, therefore your callback can be easily patched back to return the real function.
Good Luck! Hope This helps.