LPVOID __stdcall
HookedVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocatoinType, DWORD flProtect)
{
printf("Pivoting to direct systemcall\n");
NtAllocateVirtualMemory10(GetCurrentProcess(), &lpAddress, 0, &dwSize, flAllocationType, flProtect);
return lpAddress;
}
int
PatchVirtualAlloc(void)
{
void (*hookedFunc)(void) = &HookedVirtualAlloc;
BYTE patch[] = {0x68, 0x00, 0x00, 0x00, 0x00, 0xC3}; //PUSH ; ret;
memcpy(patch+2, &hookedFunc, 4);
LPVOID lpProcAddress = GetProcAddress(LoadLibrary("kernel32.dll"), "VirtualAlloc");
LPVOID lpBaseAddress = lpProcAddress;
ULONG OldProtection, NewProtection;
SIZE_T uSize = sizeof patch;
NTSTATUS status = ZwProtectVirtualMemory10(GetCurrentProcess(), &lpBaseAddress, &uSize, PAGE_EXECUTE_READWRITE, &OldProtection);
if (status != STATUS_SUCCESS) {
return 1;
}
status = ZwWriteVirtualMemory10(GetCurrentProcess(), lpProcAddress, (PVOID)patch, sizeof(patch), NULL);
if (status != STATUS_SUCCESS) {
return 2;
}
status = ZwProtectVirtualMemory10(GetCurrentProcess(), &lpBaseAddress, &uSize, OldProtection, &NewProtection);
if (status != STATUS_SUCCESS) {
return 3;
}
return 0;
}
This is an example of how to grab a function address from an already loaded DLL file and overwrite it to instead pivot to a function that the programmer controls. In this example, we overwrite the VirtualAlloc function to instead point to our own function that will make a direct system call instead of relying on ntdll.dll to make it for us. This can be required in events that library code makes use of a specific dll function that the user would like to intercept. Of note here is that the replacement function must match the calling convention of the funcion it is replacing as we are simply long JMP'ing to the new function without regards to properly dealing with the stack or registers.
References:
https://www.ired.team/offensive-security/code-injection-process-injection/how-to-hook-windows-api-using-c++
https://github.com/outflanknl/Dumpert/blob/master/Dumpert/Outflank-Dumpert/Dumpert.c#L14-L69