Loops and repetitive tasks are very common in all software, and it is important that you are able to recognize them.
The for loop is a basic looping mechanism used in C
programming. for loops always have four components:
initialization, comparison, execution instructions, and the increment or decrement.
Example 6-12 shows an example of a for loop.
In this example, the initialization sets i to 0 (zero), and
the comparison checks to see if i is less than 100. If i is less than 100, the printf
instruction will execute, the increment will add 1 to i, and the
process will check to see if i is less than 100. These steps will
repeat until i is greater than or equal to 100.
In assembly, the for loop can be recognized by locating the
four components—initialization, comparison, execution instructions, and increment/decrement.
For example, in Example 6-13, ❶ corresponds to the initialization step. The code between
❸ and ❹
corresponds to the increment that is initially jumped over at ❷ with a jump instruction. The comparison occurs at ❺, and at ❻, the decision is made by the
conditional jump. If the jump is not taken, the printf instruction will execute, and an
unconditional jump occurs at ❼, which causes the
increment to occur.
Example 6-13. Assembly code for the for loop example in Example 6-12
00401004 mov [ebp+var_4], 0 ❶ 0040100B jmp short loc_401016 ❷ 0040100D loc_40100D: 0040100D mov eax, [ebp+var_4] ❸ 00401010 add eax, 1 00401013 mov [ebp+var_4], eax ❹ 00401016 loc_401016: 00401016 cmp [ebp+var_4], 64h ❺ 0040101A jge short loc_40102F ❻ 0040101C mov ecx, [ebp+var_4] 0040101F push ecx 00401020 push offset aID ; "i equals %d\n" 00401025 call printf 0040102A add esp, 8 0040102D jmp short loc_40100D ❼
A for loop can be recognized using IDA Pro’s graphing
mode, as shown in Figure 6-2.
In the figure, the upward pointing arrow after the increment code indicates a loop.
These arrows make loops easier to recognize in the graph view than in the standard disassembly view.
The graph displays five boxes: The top four are the components of the for loop (initialization, comparison, execution, and increment, in that order). The box
on the bottom right is the function epilogue, which we described in Chapter 4 as the portion of a function responsible for cleaning up
the stack and returning.
The while loop is frequently used by malware authors to
loop until a condition is met, such as receiving a packet or command. while loops look similar to for loops in assembly, but they are easier to understand. The
while loop in Example 6-14 will
continue to loop until the status returned from checkResult is
0.
Example 6-14. C code for a while loop
int status=0;
int result = 0;
while(status == 0){
result = performAction();
status = checkResult(result);
}The assembly code in Example 6-15 looks similar
to the for loop, except that it lacks an increment section. A
conditional jump occurs at ❶ and an unconditional jump
at ❷, but the only way for this code to stop executing
repeatedly is for that conditional jump to occur.
Example 6-15. Assembly code for the while loop example in Example 6-14
00401036 mov [ebp+var_4], 0 0040103D mov [ebp+var_8], 0 00401044 loc_401044: 00401044 cmp [ebp+var_4], 0 00401048 jnz short loc_401063 ❶ 0040104A call performAction 0040104F mov [ebp+var_8], eax 00401052 mov eax, [ebp+var_8] 00401055 push eax 00401056 call checkResult 0040105B add esp, 4 0040105E mov [ebp+var_4], eax 00401061 jmp short loc_401044 ❷