Programmers use if
statements to alter program execution
based on certain conditions. if
statements are common in C code
and disassembly. We’ll examine basic and nested if
statements in this section. Your goal should be to learn how to recognize different types of
if
statements.
Example 6-8 displays a simple if
statement in C with the assembly for this code shown in Example 6-9. Notice the conditional jump jnz
at ❷. There must be a
conditional jump for an if
statement, but not all conditional
jumps correspond to if
statements.
Example 6-8. C code if
statement example
int x = 1;
int y = 2;
if(x == y){
printf("x equals y.
");
}else{
printf("x is not equal to y.
");
}
Example 6-9. Assembly code for the if
statement example in Example 6-8
00401006 mov [ebp+var_8], 1
0040100D mov [ebp+var_4], 2
00401014 mov eax, [ebp+var_8]
00401017 cmp eax, [ebp+var_4] ❶
0040101A jnz short loc_40102B
❷
0040101C push offset aXEqualsY_ ; "x equals y.
"
00401021 call printf
00401026 add esp, 4
00401029 jmp short loc_401038 ❸
0040102B loc_40102B:
0040102B push offset aXIsNotEqualToY ; "x is not equal to y.
"
00401030 call printf
As you can see in Example 6-9, a decision
must be made before the code inside the if
statement in Example 6-8 will execute. This decision corresponds to the conditional
jump (jnz
) shown at ❷. The decision to jump is made based on the comparison (cmp
), which checks to see if var_4
equals var_8
(var_4
and var_8
correspond to x
and y
in our source code) at ❶. If
the values are not equal, the jump occurs, and the code prints "x is not
equal to y."
; otherwise, the code continues the path of execution and prints "x equals y."
Notice also the jump (jmp
) that jumps over the else section
of the code at ❸. It is important that you recognize
that only one of these two code paths can be taken.
IDA Pro has a graphing tool that is useful in recognizing constructs, as shown in Figure 6-1. This feature is the default view for analyzing functions.
Figure 6-1 shows a graph of the assembly code
example in Example 6-9. As you can see, two different
paths (❶ and ❷) of code execution lead to the end of the function, and each path prints a different
string. Code path ❶ will print "x equals y."
, and ❷ will print "x is not equal to y."
IDA Pro adds false
❶ and true
❷ labels at the decision points at the bottom of the
upper code box. As you can imagine, graphing a function can greatly speed up the reverse-engineering
process.
Example 6-10 shows C code for a nested if
statement that is similar to Example 6-8, except that two additional if
statements have been added within the original if
statement. These additional statements test to determine whether z
is equal to 0.
Example 6-10. C code for a nested if
statement
int x = 0; int y = 1; int z = 2; if(x == y){if(z==0){
printf("z is zero and x = y. "); }else{ printf("z is non-zero and x = y. "); } }else{if(z==0){
printf("z zero and x != y. "); }else{ printf("z non-zero and x != y. "); } }
Despite this minor change to the C code, the assembly code is more complicated, as shown in Example 6-11.
Example 6-11. Assembly code for the nested if
statement example shown in
Example 6-10
00401006 mov [ebp+var_8], 0 0040100D mov [ebp+var_4], 1 00401014 mov [ebp+var_C], 2 0040101B mov eax, [ebp+var_8] 0040101E cmp eax, [ebp+var_4] 00401021 jnz short loc_401047 ❶ 00401023 cmp [ebp+var_C], 0 00401027 jnz short loc_401038 ❷ 00401029 push offset aZIsZeroAndXY_ ; "z is zero and x = y. " 0040102E call printf 00401033 add esp, 4 00401036 jmp short loc_401045 00401038 loc_401038: 00401038 push offset aZIsNonZeroAndX ; "z is non-zero and x = y. " 0040103D call printf 00401042 add esp, 4 00401045 loc_401045: 00401045 jmp short loc_401069 00401047 loc_401047: 00401047 cmp [ebp+var_C], 0 0040104B jnz short loc_40105C ❸ 0040104D push offset aZZeroAndXY_ ; "z zero and x != y. " 00401052 call printf 00401057 add esp, 4 0040105A jmp short loc_401069 0040105C loc_40105C: 0040105C push offset aZNonZeroAndXY_ ; "z non-zero and x != y. " 00401061 call printf00401061
As you can see, three different conditional jumps occur. The first occurs if var_4
does not equal var_8
at ❶. The other two occur if var_C
is not equal to zero at ❷ and ❸.
18.219.198.159