Heaven's Gate — Calling 64-bit Code from a 32-bit Process

Introduction to WOW64

Windows runs 32-bit applications on 64-bit systems through the WOW64 subsystem (Windows 32-bit on Windows 64-bit). This subsystem emulates the 32-bit environment, allowing x86 binaries to execute on AMD64 systems without modification.

When a 32-bit process runs under WOW64, it operates in a hybrid state:

  • The virtual address space is 32-bit (up to 4 GB, typically 2 GB user-accessible)

  • The kernel remains in pure 64-bit mode

  • WOW64 intercepts kernel calls and translates them from 32-bit to 64-bit

┌──────────────────────────────────────────────────────────────────────┐
│               WOW64 Architecture — Internal View                     │
│                                                                      │
│  32-bit process:                                                     │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │  x86 code (32-bit)                                          │    │
│  │  ntdll32.dll (32-bit) — 32-bit native API                  │    │
│  │  wow64.dll — call thunking and translation                  │    │
│  │  wow64win.dll — GUI call thunking                           │    │
│  │  wow64cpu.dll — transition to 64-bit mode                   │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                            │                                         │
│                     wow64cpu!BTCpuSimulate                           │
│                            │                                         │
│           ┌────────────────▼───────────────────┐                    │
│           │   Far jump to CS:0x33               │                    │
│           │   (switches CPU to 64-bit Long Mode)│                    │
│           └────────────────────────────────────┘                    │
│                            │                                         │
│  ┌─────────────────────────▼───────────────────────────────────┐    │
│  │  64-bit kernel (NT Executive)                               │    │
│  │  ntoskrnl.exe executes the syscall in native 64-bit mode    │    │
│  └─────────────────────────────────────────────────────────────┘    │
└──────────────────────────────────────────────────────────────────────┘

Heaven's Gate is the technique of exploiting this 32-to-64-bit mode transition inside a WOW64 process to execute 64-bit code directly — bypassing the WOW64 thunking layer entirely.


Why This Is Useful for Evasion

EDRs that hook APIs typically install two sets of hooks:

  • One for 64-bit processes (in the 64-bit ntdll.dll)

  • One for 32-bit processes (in the 32-bit ntdll.dll, via WOW64)

When a 32-bit process uses Heaven's Gate to call 64-bit syscalls directly, it completely bypasses the 32-bit EDR hook layer. The syscalls reach the kernel directly in 64-bit mode, as if they originated from a native 64-bit process.


The Mechanism: Far Jump with CS:0x33

In x86-64, the code segment selector controls the CPU's operating mode:

  • CS = 0x23: 32-bit mode (compatibility mode)

  • CS = 0x33: 64-bit mode (long mode)

A far jump targeting a different selector (jmp far 0x33:address) causes the CPU to transition to the corresponding mode. WOW64 uses exactly this mechanism internally when moving between modes.

x86 Assembly Implementation (32-bit)

C Implementation with Inline Assembly (MSVC)

For use in C with a 32-bit MSVC compiler:

Runtime-Generated Stub Approach

The most practical approach generates the Heaven's Gate stub at runtime as a raw byte buffer:


Practical Use Cases

Heaven's Gate appears in:

  1. 32-bit loaders for 64-bit payloads: A 32-bit dropper (easier to obfuscate) injects a 64-bit payload using native syscalls.

  2. Bypassing hooks in legacy EDRs: EDRs that only install 32-bit hooks are completely blind to this path.

  3. Anti-analysis: Sandboxes that only emulate 32-bit code cannot follow execution into 64-bit code triggered via Heaven's Gate.


Limitations

  • Requires the process to run under WOW64 (32-bit on a 64-bit OS)

  • Does not work on natively 32-bit systems (e.g., Windows XP x86)

  • Modern EDRs install hooks in both 32-bit and 64-bit ntdll — Heaven's Gate only bypasses the 32-bit set

  • Correctly managing the stack across mode transitions requires extreme care to avoid corruption


Detection

  • Code segment analysis: EDRs with kernel drivers can detect unexpected CS transitions via thread context inspection

  • Far jump opcode scanning: Hunting for 0xEA (far jmp) or RETF in userland code

  • Call correlation: A 64-bit syscall with a 32-bit call stack is a detectable anomaly


References

  • Roy G. Biv (Barnaby Jack), "Heaven's Gate" — 2011 (original concept)

  • ReWolf, "x86/x64 Hybrid Shellcode" — rewolf.pl (2012)

  • Alex Ionescu, "Windows WOW64 Internals" — RECON 2015

  • Hexacorn, "Heaven's Gate for Malware Developers" — hexacorn.com

  • ired.team, "Heaven's Gate — Calling x64 Code from x86 Process" — ired.team

  • NETSPI, "Heaven's Gate: 32-bit Process to 64-bit Syscalls" — netspi.com (2021)

  • Windows Internals 7th Edition, "WOW64 Architecture"

Last updated