CHAPTER 6.PRINTF()WITH SEVERAL ARGUMENTS CHAPTER 6.PRINTF()WITH SEVERAL ARGUMENTS
Press F8 again to executeADD ESP, 10instruction:
Figure 6.6:OllyDbg: afterADD ESP, 10instruction execution
ESPhas changed, but the values are still in the stack! Yes, of course; no one needs to set these values to zeroes or something
like that. Everything above the stack pointer (SP) isnoiseorgarbageand has no meaning at all. It would be time consuming
to clear the unused stack entries anyway, and no one really needs to.
GCC
Now let’s compile the same program in Linux using GCC 4.4.1 and take a look at what we have got inIDA:
main proc near
var_10 = dword ptr -10h
var_C = dword ptr -0Ch
var_8 = dword ptr -8
var_4 = dword ptr -4
push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 10h
mov eax, offset aADBDCD ; "a=%d; b=%d; c=%d"
mov [esp+10h+var_4], 3
mov [esp+10h+var_8], 2
mov [esp+10h+var_C], 1
mov [esp+10h+var_10], eax
call _printf
mov eax, 0
leave
retn
main endp
Its noticeable that the difference between the MSVC code and the GCC code is only in the way the arguments are stored on
the stack. Here the GCC is working directly with the stack without the use ofPUSH/POP.
GCC and GDB
Let’s try this example also inGDB^1 in Linux.
-goption instructs the compiler to include debug information in the executable file.
$ gcc 1.c -g -o 1
(^1) GNU debugger