-
-
Save hoangprod/4f5e821525cd199c3ca3134a0596e263 to your computer and use it in GitHub Desktop.
| #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; | |
| } |
is this a 32 or 64 bit DLL may i ask?
Since this is a Wow64 hook, this should be compiled as a 32bit DLL injected into a 32bit process on a 64bit OS.
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
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
is this a 32 or 64 bit DLL may i ask?