Introduction

Single-stepping is one of the most powerful features of a debugger, as it allows a reverse engineer to execute a single instruction at a time before returning control to the debugger. This feature comes in handy when one needs to analyze a binary by executing a single instruction or a section of instructions of his/her interest. 

In this article, we will explore how stepping over and stepping into features can help when analyzing a binary with a debugger. We will use OllyDbg as our choice of debugger, but the concept remains the same with any other debugger.

Stepping

During malware analysis and reverse engineering, we may need to execute instructions one after the other (one instruction at a time) to understand the behavior at a certain point. This is called single-stepping, which provides a detailed view of what is going on when the binary is run. 

Debuggers allow us to single-step the program execution. In OllyDbg, we can do single-stepping by using the F8 key or by clicking the button highlighted in the image below. 

This button is used for step-over. This means that the single-stepping happens per line of code. However,  if we press this key when the debugger is about to execute a CALL instruction, the execution of the subroutine will be completed and the single-step continues to the next instruction after the CALL instruction. When this happens, there is a chance that we may miss the analysis of important instructions inside the subroutine.

If you want to single-step through the instructions inside the subroutine, we should use step-into on CALL instruction. In OllyDbg, this can be done by using the F7 key or the button highlighted below.

Another way to use step-into and step-over in OllyDbg is by navigating to the Debug Menu item, as shown in the following figure.

Example

Let’s try to understand these concepts with an example. The following C program is used to demonstrate how step-into and step-over can be used.

#include <stdio.h>

void test_function(int arg1, int agr2); 

void main()

{

int a = 10;

printf(“Value of a is %d\n”, a);

test_function(10,20);

a = a+5;

printf(“Updated value of a is %d\n”,a);

}

void test_function(int arg1, int arg2){

int x = 50;

int y = 40;

}

The preceding code comes with a function named test_function, where two variables are initialized. The executable binary obtained from this C program is opened using OllyDbg. Following picture shows the disassembly of the main function as well as test_function.

By looking at the disassembly, it can be seen that test_function is called at the address 0x00401549 with the following instruction.

00401549  |. E8 1C000000      CALL stepping.0040156A

A breakpoint is set on this instruction and pressing F8 (step-over) will execute the function definition available at the address 0x0040156A and control will be returned to the next instruction, which is at 0x0040154E

This means we will not be able to do single-stepping inside the block highlighted below.

As mentioned earlier, the reason for this is that debugger simply executes the function and returns control. If we want to single-step through the subroutine’s instructions instead, we will need to step-over at the CALL instruction by pressing F7.

In that case, we will be able to single-step through the subroutine, as highlighted below.

As you can observe in the preceding figure, the control is now at the address 0x0040156D, which is inside the function definition of test_function.

When analyzing a large binary, it is necessary to skip the unnecessary blocks of code. When a CALL instruction is taking to a seemingly useless block of code, we can use step-over to bypass the single-stepping process in the subroutine.

It is possible that a binary can have functions which will never return to the calling function. In these cases, if step-over is used, the debugger will lose control and we will need to restart the program being analyzed and then use step-into on the CALL function instead of step-over

Conclusion

In this article, we discussed single-stepping, which is one of the most important features of a debugger. We discussed how step-over will bypass the single-stepping of the subroutine and returns to the immediate next instruction after CALL. We also discussed how step-into can be used to single-step through the instructions inside a subroutine.

 

Sources

  1. Randal Hyde, “The Art of Assembly Language,” No Starch Press, March 2010
  2. Michael Sikorski and Andrew Honig, “Practical Malware Analysis,” No Starch Press, February 2012
  3. Reverse Engineering for Beginners, Dennis Yurichev

Be Safe

Section Guide

Srinivas

View more articles from Srinivas

As you grow in your cybersecurity career, Infosec Skills is the platform to ensure your skills are scaled to outsmart the latest cyber threats.

Section Guide

Srinivas

View more articles from Srinivas