Fukahi Tekiō 不可避適応: Bypassing Win 10/11 FPU "Issues" via Custom CALL/POP XOR Encoder
Share
Published: 2026-01-15
Author: JAKESWIZ
Introduction
This exploit technique was developed for the vulnserver TRUN buffer overflow vulnerability, but it can be applied to other exploits, especially for those new to ARM → x86/64 emulation exploitation.
The motivation came from wanting to run Windows exploitation demos on an ARM Mac (running Windows 11 AARCH64 with the Prism emulation layer) for a talk at Wild West Hackin' Fest in Denver.
The Problem
When exploiting buffer overflows on modern Windows systems (especially under ARM emulation), msfvenom's default encoder (shikata_ga_nai) crashes during shellcode execution:
eax=00000000 ebx=00000000 ecx=00000052 edx=02ff4a30 esi=55bd55d0 edi=00401848
eip=089ff959 esp=089ff924 ebp=00000000
089ff959 317012 xor dword ptr [eax+12h],esi
Attempt to read from address 00000012
The decoder tries to dereference a register (EAX, EBP, or ESI) containing a near-null value.
Why This Happens
shikata_ga_nai uses a GetPC technique relying on FPU (Floating Point Unit) instructions:
fcmovb st, st(5) ; Any FPU instruction
fnstenv [esp-0xc] ; Save FPU state to stack
pop ebp ; Grab saved EIP from FPU state
On Windows 10/11 and under ARM emulation (Prism), the FPU instruction pointer field often returns zeros. When the decoder does pop ebp, it gets 0x00000000 and crashes.
The Solution: CALL/POP GetPC
Instead of relying on FPU quirks, use the reliable CALL/POP technique:
jmp short call_label ; Jump to the CALL
pop_label:
pop esi ; ESI now contains address of encoded shellcode
; ... decoder logic ...
call_label:
call pop_label ; Pushes address of encoded shellcode, jumps back
; encoded shellcode starts here
When the CPU executes a CALL instruction, it pushes the address of the next instruction onto the stack. We immediately POP that address into a register. This is 100% reliable because CALL always pushes the return address — no FPU state involved.
Want to read more? Read more at:
www.churchofmalware.org