Created
May 14, 2019 20:47
-
-
Save hoangprod/4f5e821525cd199c3ca3134a0596e263 to your computer and use it in GitHub Desktop.
Wow64Hook example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include <iostream> | |
LPVOID lpJmpRealloc = nullptr; | |
DWORD Backup_Eax, Handle, Address_1, New, Old, *DwSizee; | |
const DWORD_PTR __declspec(naked) GetGateAddress() | |
{ | |
__asm | |
{ | |
mov eax, dword ptr fs : [0xC0] | |
ret | |
} | |
} | |
void __declspec(naked) hk_NtProtectVirtualMemory() | |
{ | |
__asm { | |
mov Backup_Eax, eax | |
mov eax, [esp + 0x8] | |
mov Handle, eax | |
mov eax, [esp + 0xC] | |
mov Address_1, eax | |
mov eax, [esp + 0x10] | |
mov DwSizee, eax | |
mov eax, [esp + 0x14] | |
mov New, eax | |
mov eax, [esp + 0x18] | |
mov Old, eax | |
mov eax, Backup_Eax | |
pushad | |
} | |
printf("NtPVM Handle: [%x] Address: [0x%x] Size: [%d] NewProtect: [0x%x]\n", Handle, Address_1, *DwSizee, New); | |
__asm popad | |
__asm jmp lpJmpRealloc | |
} | |
void __declspec(naked) hk_NtReadVirtualMemory() | |
{ | |
__asm pushad | |
printf("Calling NtReadVirtualMemory.\n"); | |
__asm popad | |
__asm jmp lpJmpRealloc | |
} | |
void __declspec(naked) hk_Wow64Trampoline() | |
{ | |
__asm | |
{ | |
cmp eax, 0x3f //64bit Syscall id of NtRVM | |
je hk_NtReadVirtualMemory | |
cmp eax, 0x50 //64bit Syscall id of NtPVM | |
je hk_NtProtectVirtualMemory | |
jmp lpJmpRealloc | |
} | |
} | |
const LPVOID CreateNewJump() | |
{ | |
DWORD_PTR Gate = GetGateAddress(); | |
lpJmpRealloc = VirtualAlloc(nullptr, 0x1000, MEM_RESERVE | MEM_COMMIT, | |
PAGE_EXECUTE_READWRITE); | |
memcpy(lpJmpRealloc, (void *)Gate, 9); | |
return lpJmpRealloc; | |
} | |
const void WriteJump(const DWORD_PTR dwWow64Address, const void *pBuffer, size_t ulSize) | |
{ | |
DWORD dwOldProtect = 0; | |
VirtualProtect((LPVOID)dwWow64Address, 0x1000, PAGE_EXECUTE_READWRITE, &dwOldProtect); | |
(void)memcpy((void *)dwWow64Address, pBuffer, ulSize); | |
VirtualProtect((LPVOID)dwWow64Address, 0x1000, dwOldProtect, &dwOldProtect); | |
} | |
const void EnableWow64Redirect() | |
{ | |
LPVOID Hook_Gate = &hk_Wow64Trampoline; | |
char trampolineBytes[] = | |
{ | |
0x68, 0xDD, 0xCC, 0xBB, 0xAA, /*push 0xAABBCCDD*/ | |
0xC3, /*ret*/ | |
0xCC, 0xCC, 0xCC /*padding*/ | |
}; | |
memcpy(&trampolineBytes[1], &Hook_Gate, 4); | |
WriteJump(GetGateAddress(), trampolineBytes, sizeof(trampolineBytes)); | |
} | |
BOOL APIENTRY DllMain(HMODULE hModule, | |
DWORD ul_reason_for_call, | |
LPVOID lpReserved | |
) | |
{ | |
switch (ul_reason_for_call) | |
{ | |
case DLL_PROCESS_ATTACH: | |
AllocConsole(); | |
FILE* fp; | |
freopen_s(&fp, "CONOUT$", "w", stdout); | |
printf("Gate: %p\n", GetGateAddress()); | |
printf("Trampoline Gate: %p\n", CreateNewJump()); | |
printf("Hook Gate: %p\n", hk_Wow64Trampoline); | |
EnableWow64Redirect(); | |
case DLL_THREAD_ATTACH: | |
case DLL_THREAD_DETACH: | |
case DLL_PROCESS_DETACH: | |
break; | |
} | |
return TRUE; | |
} |
const LPVOID CreateNewJump()
{
DWORD_PTR Gate = GetGateAddress();
lpJmpRealloc = VirtualAlloc(nullptr, 0x1000, MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
memcpy(lpJmpRealloc, (void *)Gate, 9);
return lpJmpRealloc;
}
Why do we copy 9 bytes? I noticed Heaven's gate only has 7 useful bytes.
Thank you.
const LPVOID CreateNewJump() { DWORD_PTR Gate = GetGateAddress(); lpJmpRealloc = VirtualAlloc(nullptr, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); memcpy(lpJmpRealloc, (void *)Gate, 9); return lpJmpRealloc; }
Why do we copy 9 bytes? I noticed Heaven's gate only has 7 useful bytes.
Thank you.
I have not work with Wow64 in some time and by looking through the code, I don't see a good reason either. At the transition gate, it looks like there are 7 useful bytes and then 2x 00 bytes but those 2x 00 bytes should never be executed due to it being after an unconditional jump. Therefore, I think using just 7 bytes should be sufficed.
Thank you so much. @hoangprod
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
void __declspec(naked) hk_NtProtectVirtualMemory()
{
__asm {
mov Backup_Eax, eax
mov eax, [esp + 0x8]
mov Handle, eax
mov eax, [esp + 0xC]
mov Address_1, eax
mov eax, [esp + 0x10]
mov DwSizee, eax
mov eax, [esp + 0x14]
mov New, eax
mov eax, [esp + 0x18]
mov Old, eax
mov eax, Backup_Eax
pushad
}
How can I arguments of find that function?
i will want to find NtOpenProcess function stack [esp+0x00]
thank you