Unfortunately, different disassemblers produce different output for these
sequences. Consider the following sequence for example:
_asm
{
mov eax, 2
cmp eax, 2
je After
_emit 0xf
After:
mov eax, [SomeVariable]
push eax
call AFunction
}
This is similar to the method used earlier for linear sweep disassemblers,
except that you’re now using a simple opaque predicate instead of an uncon-
ditional jump. The opaque predicate simply compares 2 with 2 and performs a
jump if they’re equal. The following listing was produced by IDA Pro:
.text:00401031 mov eax, 2
.text:00401036 cmp eax, 2
.text:00401039 jz short near ptr loc_40103B+1
.text:0040103B
.text:0040103B loc_40103B: ; CODE XREF: .text:00401039 _j
.text:0040103B jnp near ptr 0E8910886h
.text:00401041 mov ebx, 68FFFFFFh
.text:00401046 fsub qword ptr [eax+40h]
.text:00401049 add al, ch
.text:0040104B add eax, [eax]
As you can see, IDA bought into it and produced incorrect code. Does this
mean that IDA Pro, which has a reputation for being one of the most powerful
disassemblers around, is flawed in some way? Absolutely not. When you
think about it, properly disassembling these kinds of code sequences is not a
problem that can be solved in a generic method—the disassembler must con-
tain specific heuristics that deal with these kinds of situations. Instead disas-
semblers such as IDA (and also OllyDbg) contain specific commands that
inform the disassembler whether a certain byte is code or data. To properly
disassemble such code in these products, one would have to inform the disas-
sembler that our junk byte is really data and not code. This would solve the
problem and the disassembler would produce a correct disassembly.
Let’s go back to our sample from earlier and see how OllyDbg reacts to it.
00401031. B8 02000000 MOV EAX,2
00401036. 83F8 02 CMP EAX,2
00401039. 74 01 JE SHORT compiler.0040103C
0040103B 0F DB 0F
0040103C > 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
340 Chapter 10