This time OllyDbg swallows the bait and uses the invalid 0040103Das the
starting address from which to disassemble, which produces a meaningless
assembly language listing. What’s more, IDA Pro produces an equally unread-
able output—both major recursive traversers fall for this trick. Needless to say,
linear sweepers such as SoftICE react in the exact same manner.
One recursive traversal disassembler that is not falling for this trick is
PEBrowse Professional. Here is the listing produced by PEBrowse:
0x401031: B802000000 mov eax,0x2
0x401036: 83F803 cmp eax,0x3
0x401039: 7402 jz 0x40103d ; (*+0x4)
0x40103B: 7501 jnz 0x40103e ; (*+0x3)
0x40103D: 0F8B45F850E8 jpo 0xe8910888 ; <==0x00401039(*-0x4)
;***********************************************************************
0x40103E: 8B45F8 mov eax,dword ptr [ebp-0x8] ; VAR:0x8
0x401041: 50 push eax
0x401042: E8B9FFFFFF call 0x401000
;***********************************************************************
Apparently (and it’s difficult to tell whether this is caused by the presence of
special heuristics designed to withstand such code sequences or just by a
fluke) PEBrowse Professional is trying to disassemble the code from both
40103Dand from 40103E, and is showing both options. It looks like you’ll
need to improve on your technique a little bit—there must not be a direct jump
to the valid code address if you’re to fool every disassembler. The solution is to
simply perform an indirect jump using a value loaded in a register. The fol-
lowing code confuses every disassembler I’ve tested, including both linear-
sweep-based tools and recursive-traversal-based tools.
_asm
{
mov eax, 2
cmp eax, 3
je Junk
mov eax, After
jmp eax
Junk:
_emit 0xf
After:
mov eax, [SomeVariable]
push eax
call AFunction
}
The reason this trick works is quite trivial—because the disassembler has no
idea that the sequence mov eax, After, jmp eaxis equivalent to jmp
After, the disassembler is not even trying to begin disassembling from the
Afteraddress.
342 Chapter 10