This is the c code:
void test_function(int a, int b, int c, int d)
{
int flag;
char buffer[10];
flag = 31337;
buffer[0] = 'A';
}
int main()
{
test_function(1, 2, 3, 4);
}
Assembly of test_function:
Dump of assembler code for function test_function:
0x08048344 <test_function+0>: push ebp
0x08048345 <test_function+1>: mov ebp,esp
0x08048347 <test_function+3>: sub esp,0x28
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
0x08048355 <test_function+17>: leave
0x08048356 <test_function+18>: ret
End of assembler dump.
(gdb) print $ebp-12
$1 = (void *) 0xbffff7dc
(gdb) print $ebp-40
$2 = (void *) 0xbffff7c0
(gdb) x/16xw $esp
0xbffff7c0: (1)0x00000000 0x08049548 0xbffff7d8 0x08048249
0xbffff7d0: 0xb7f9f729 0xb7fd6ff4 0xbffff808 0x080483b9
0xbffff7e0: 0xb7fd6ff4 (2)0xbffff89c (3)0xbffff808 (4)0x0804838b
0xbffff7f0: (5)0x00000001 0x00000002 0x00000003 0x00000004
I'm new to these topics; therefore, some questions exist in my head.
You problem
It pushes ebp, then copies esp to ebt
ebt is wrong, there is no register that called ebt. It is should be ebp.
push ebp
the command is for preserve the stack bottom before calling the test_function function.
mov ebp,esp
sub esp,0x28
the command is for increase the stack to allocate a new block of memory for storing values during the execution of test_function function. And the size of the stack increase is not fixed and will not always be 0x28. This value is calculated by the compiler, which ensures that the size is suitable.
mov DWORD PTR [ebp-12],0x7a69
corresponds to flag = 31337,flag address is equal to ebp-12's value. The address is assigned by the compiler. DWORD corresponds to int.The hexadecimal number 0x7a69 is equivalent to the decimal number 31337.
And
mov BYTE PTR [ebp-40],0x41
the same as. The hexadecimal number 0x41 is equivalent to the decimal number 65. The decimal value of the ASCII code for the letter A is the decimal number 65. BYTE corresponds to char.
Below code
(gdb) x/16xw $esp
0xbffff7c0: (1)0x00000000 0x08049548 0xbffff7d8 0x08048249
0xbffff7d0: 0xb7f9f729 0xb7fd6ff4 0xbffff808 0x080483b9
0xbffff7e0: 0xb7fd6ff4 (2)0xbffff89c (3)0xbffff808 (4)0x0804838b
0xbffff7f0: (5)0x00000001 0x00000002 0x00000003 0x00000004
Such as 0xbffff7c0: of left code is address,it' value is 0x00000000. So 0xbffff7c4(0xbffff7c4 = 0xbffff7c0 + 4) address's value is 0x08049548, because 0x00000000 occupies 4 bytes. 0xbffff7c8 address's value is 0xbffff7d8. ....
I think below assembler code
Dump of assembler code for function test_function:
0x08048344 <test_function+0>: push ebp
0x08048345 <test_function+1>: mov ebp,esp
0x08048347 <test_function+3>: sub esp,0x28
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
0x08048355 <test_function+17>: leave
0x08048356 <test_function+18>: ret
can convert below code(as @Peter Cordes point that "leave" is equal to "mov esp,ebp" + "pop ebp" see at https://www.felixcloutier.com/x86/leave)
Dump of assembler code for function test_function:
0x08048344 <test_function+0>: push ebp
0x08048345 <test_function+1>: mov ebp,esp
0x08048347 <test_function+3>: sub esp,0x28
0x0804834a <test_function+6>: mov DWORD PTR [ebp-12],0x7a69
0x08048351 <test_function+13>: mov BYTE PTR [ebp-40],0x41
mov esp,ebp // here changed
pop ebp // here changed
0x08048356 <test_function+18>: ret
Local variables are stored in the stack.
So we can get a picture see below: