This program uses false conditional branches: an xor eax,
eax, followed by jz.
The program tricks the disassembler into disassembling the opcode 0xE8, the first of a 5-byte call instruction, which
immediately follows the jz instruction.
The false conditional branch technique is used five times in this program.
The command-line argument pdq will cause the program to
print “Good Job!”
First, we load the file into IDA Pro and scroll to the main
function at address 0x401000. A few lines from the start of the function, memory address 0x0040100E,
we see the first signs of anti-disassembly, as shown in Example C-120.
Example C-120. jz jumping into the middle of a call instruction
00401006 83 7D 08 02 cmp dword ptr [ebp+8], 2 0040100A 75 52 jnz short loc_40105E 0040100C 33 C0 xor eax, eax 0040100E 74 01 jz short near ptr loc_401010+1 ❶ 00401010 00401010 loc_401010: ; CODE XREF:0040100Ej 00401010 E8 8B 45 0C 8B ❷call near ptr 8B4C55A0h
As shown at ❶, the jz instruction appears to be jumping into the middle of the 5-byte call instruction at ❷. We must
determine whether this branch will be executed.
The instruction immediately preceding this branch is xor eax,
eax, which will always set the EAX register to zero, and thus always result in the zero
flag being set. The jz instruction will therefore always jump at
this point because the state of the zero flag is always known. We must alter the disassembly to show
the real target of this jump instead of the fake call instruction
that is overlapping it.
Position your cursor on line 0x00401010 and press the D key on your keyboard to turn the line
into data, as shown in Example C-121. Notice that the
CODE XREF comment is no longer red but green, and the target of
the jz instruction is no longer loc_401010+1 but unk_401011, as seen at ❶.
Example C-121. Converting the call instruction from Example C-120 to data
0040100E 74 01 jz short near ptr unk_401011 ❶ 0040100E ; -------------------------------------------------------------- 00401010 E8 db 0E8h 00401011 8B ❷ unk_401011 db 8Bh ; ï ; CODE XREF: 0040100Ej
We can now modify the real target of the jz instruction. To
do so, place your cursor at ❷ and press the C key on
your keyboard to turn this piece of data into code. The instructions immediately following the
listing may be out of alignment, so keep pressing C on each db
line that follows until each instruction is followed immediately by another instruction with no data
bytes in between.
The same false conditional technique is found again at offset 0x0040101F. Clean up the code at this location in the same manner to reveal another use of the false conditional technique at location 0x00401033. The final remaining places to fix are 0x00401047 and 0x0040105E.
Once all the code is disassembled correctly, select the code from line 0x00401000 to the
retn instruction at line 0x00401077, and press the P key on your
keyboard to force IDA Pro to turn this block of code into a function. Once it is a function, rename
the function parameters argc and argv. At this point, it should be clear at line 0x00401006 that the program checks to see
if the value of argc is 2, and prints the failure string if it is
not. If the value is 2, line 0x0040101A compares the first letter of argv[1] with p. Line 0x0040102E then compares the
third letter with q, and 0x00401042 compares the second with
d. If all three letters are equal, the string Good Job! is printed at line 0x00401051.