assemblyx86x86-64memory-segmentation

x86 - Switching from 32-bit to 64-bit via RETF


I was looking at some anti-disassembler techniques and came across the following snippet:

push 0x33
call $+5
add  [esp+0x10+var_10], 5
retf
; next instruction here

So in a nutshell, this would immediately jump to the instruction right after RETF, but would mess up 32-bit disassemblers. Still not clear to me why that is though.

Now, I've been told that RETF returns to a 64-bit segment, and hence debugging this on a 32-bit debugger produces the wrong disassembly. When running this snippet on a 64-bit debugger (in my case windbg) it produces the correct result.

My question here is: Is there anything special about the push 0x33? Is 0x33 some kind of special value?


Solution

  • retf itself doesn't mean "return to a 64-bit segment". It means "return to the specified segment and address", as opposed to near ret meaning "return to the specified address without changing segments". The 0x33 is the segment to return to, which happens to be the segment that's used for 64-bit code. (0x23 is the 32-bit segment.)