1

Here is a sample function reverse engineered from an easy program:

main            proc near
var_70          = dword ptr -70h
var_6C          = dword ptr -6Ch
var_68          = dword ptr -68h
i_2             = dword ptr -54h
i               = dword ptr -4
push    ebp
mov     ebp, esp
and     esp, 0FFFFFFF0h
sub     esp, 70h
mov     [esp+70h+i], 0
jmp     short loc_804840A
loc_80483F7:
mov     eax, [esp+70h+i]
mov     edx, [esp+70h+i]
add     edx, edx
mov     [esp+eax*4+70h+i_2], edx
add     [esp+70h+i], 1
loc_804840A:
cmp     [esp+70h+i], 13h
jle     short loc_80483F7
mov     [esp+70h+i], 0
jmp     short loc_8048441
loc_804841B:
mov    eax, [esp+70h+i]
mov    edx, [esp+eax*4+70h+i_2]
mov    eax, offset aADD ; "a[%d]=%d\n"
mov    [esp+70h+var_68], edx
mov    edx, [esp+70h+i]
mov    [esp+70h+var_6C], edx
mov    [esp+70h+var_70], eax
call   _printf
add    [esp+70h+i], 1
loc_8048441:
cmp    [esp+70h+i], 13h
jle     short loc_804841B
mov    eax, 0
leave 
retn
main   endp

C code

#include <stdio.h>
int main() {
    int a[20];
    int i;
    for (i=0; i<20; i++)
        a[i]=i*2;
    for (i=0; i<20; i++)
        printf ("a[%d]=%d\n", i, a[i]);
    return 0;
}

My questions are:

  1. Why is memory not allocated consecutively and why are some parts of the memory in between esp + 70h -54h and esp + 70h -68h not used?

  2. In sub esp, 70h, the number 70h seems to be a random number in a different program, and it is often larger than we need. Why don't the compiler just allocate what we need?

2

In your case because int is 4 bytes and you want 20 element

int a[20] // --> 20 * 4 = 0x50

so it is very normal for i and i_2

The other thing is that your compiler didn't push printf arguments into stack. It pre-allocated the stack location in

var_70 = dword ptr -70h
var_6C = dword ptr -6Ch
var_68 = dword ptr -68h

and called the function like this

mov    edx, [esp+eax*4+70h+i_2]
mov    eax, offset aADD ; "a[%d]=%d\n"
mov    [esp+70h+var_68], edx
mov    edx, [esp+70h+i]
mov    [esp+70h+var_6C], edx
mov    [esp+70h+var_70], eax
call   _printf

But there is 2 reason for such a thing (not your case)...

  1. The Compiler align the buffer for performance reasons and ease of cache. in addition unaligned buffers cause failure in some cases like Windows API calls and make debugging hard, so the compilers align every buffer to avoid this kind of failure.

  2. Some safe compilation allocate random number after buffers to prevent successful exploitation of buffer overruns. for example:

    and esp, 0FFFFFFF0h


yeap! as @DCoder commented, you asked it Here before.

  • 1
    In that question, the answers says the temporary variables, like var_70 ,generated due to copy params are not local variables. But I think that's not correct. – upton May 21 '14 at 3:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.