Reverse Engineering for Beginners

(avery) #1

CHAPTER 6.PRINTF()WITH SEVERAL ARGUMENTS CHAPTER 6.PRINTF()WITH SEVERAL ARGUMENTS


Chapter 6


printf() with several arguments


Now let’s extend theHello, world!(3 on page 6) example, replacingprintf()in themain()function body with this:


#include <stdio.h>


int main()
{
printf("a=%d; b=%d; c=%d", 1, 2, 3);
return 0;
};


6.1 x86


6.1.1 x86: 3 arguments


MSVC


When we compile it with MSVC 2010 Express we get:


$SG3830 DB 'a=%d; b=%d; c=%d', 00H


...


push 3
push 2
push 1
push OFFSET $SG3830
call _printf
add esp, 16 ; 00000010H

Almost the same, but now we can see theprintf()arguments are pushed onto the stack in reverse order. The first
argument is pushed last.


By the way, variables ofinttype in 32-bit environment have 32-bit width, that is 4 bytes.


So, we have 4 arguments here. 4 ∗4 = 16—they occupy exactly 16 bytes in the stack: a 32-bit pointer to a string and 3
numbers of typeint.


When thestack pointer(ESPregister) has changed back by theADD ESP, Xinstruction after a function call, often, the
number of function arguments could be deduced by simply dividing X by 4.


Of course, this is specific to thecdeclcalling convention, and only for 32-bit environment.


See also the calling conventions section (64 on page 648).


In certain cases where several functions return right after one another, the compiler could merge multiple “ADD ESP, X”
instructions into one, after the last call:


push a1
push a2
call ...
...
push a1

Free download pdf