Rewriting ret address when leaving a function

0

I'm trying to rewrite ret adress from function foo() to skip first instruction after leaving function foo(). I'm following Smash stack for fun or profit and Hacking by Jon Erickson. Here is simple code where I want to skip "b = 2;" instruction, so in b should be stored value 1.

Compiled in gcc, settings: -fno-stack-protector -z execstack -g
Also I have turned off ASLR.

#include <stdio.h>
int foo() {
    int c = 0;
    int *ptr;
    ptr = (int*) 0x00007fffffffdf38;
    // Second instruction after leaving from foo(). I also tried to skip all instructions before call printf function.
    *ptr = 0x0000000000400577; 
    return 0;
}

int main()
{
    int b = 1;
    foo();
    b = 2;
    printf("b = %d\n", b);      
    return 0;
}

Output of this program is: "b = 2".

How I assumed where is stored RET instruction:

(gdb) disass main
...
0x000000000040056b <+20>:   call   0x40052d <foo>
0x0000000000400570 <+25>:   mov    DWORD PTR [rbp-0x4],0x2
0x0000000000400577 <+32>:   mov    eax,DWORD PTR [rbp-0x4]
0x000000000040057a <+35>:   mov    esi,eax
...
(gdb) break 4       // set breakpoint 1 in function foo before int *ptr;
(gdb) break 7       // set breakpoint 2 in function foo after rewriting RET for checking
(gdb) run
(gdb) x/8x &c       // "x/8x $esp" doesn't work, it says: "Cannot access memory at address 0xffffffffffffdf30", so I'm looking into memory from &c
0x7fffffffdf2c: 0x00000000  0xffffdf50  0x00007fff  0x00400570
0x7fffffffdf3c: 0x00000000  0xffffe030  0x00007fff  0x00000000
// simple math tell me, it should be:
(gdb) x/8xb 0x7fffffffdf38
0x7fffffffdf38: 0x70    0x05    0x40    0x00    0x00    0x00    0x00    0x00

This is how I have found the RET address, it is at 0x7fffffffdf38. To this place I'm putting address of next instruction - 0x0000000000400577. However, computer still didn't skip instruction b = 2, even when RET is successfully rewrited. I checked it for confirmation if it really replaced the RET address:

(gdb) c
(gdb) x/8xb 0x7fffffffdf38
0x7fffffffdf38: 0x77    0x05    0x40    0x00    0x00    0x00    0x00    0x00

So RET address is really rewrited but when program leaves from function foo() it jumps to original address 0x0000000000400570 wich I want to skip...

It should be simple, find where is stored ret adress and then put to this place other adress. What am I doing wrong? Thanks for every answer.

For specifying the questing I'm adding dissasembled functions:

Dump of assembler code for function foo:
0x000000000040052d <+0>:    push   rbp
0x000000000040052e <+1>:    mov    rbp,rsp
0x0000000000400531 <+4>:    mov    DWORD PTR [rbp-0x4],0x0
0x0000000000400538 <+11>:   movabs rax,0x7fffffffdf38
0x0000000000400542 <+21>:   mov    QWORD PTR [rbp-0x10],rax
0x0000000000400546 <+25>:   mov    rax,QWORD PTR [rbp-0x10]
0x000000000040054a <+29>:   mov    DWORD PTR [rax],0x400577
0x0000000000400550 <+35>:   mov    eax,0x0
0x0000000000400555 <+40>:   pop    rbp
0x0000000000400556 <+41>:   ret    
End of assembler dump.
(gdb) disass main
Dump of assembler code for function main:
0x0000000000400557 <+0>:    push   rbp
0x0000000000400558 <+1>:    mov    rbp,rsp
0x000000000040055b <+4>:    sub    rsp,0x10
0x000000000040055f <+8>:    mov    DWORD PTR [rbp-0x4],0x1
0x0000000000400566 <+15>:   mov    eax,0x0
0x000000000040056b <+20>:   call   0x40052d <foo>
0x0000000000400570 <+25>:   mov    DWORD PTR [rbp-0x4],0x2
0x0000000000400577 <+32>:   mov    eax,DWORD PTR [rbp-0x4]
0x000000000040057a <+35>:   mov    esi,eax
0x000000000040057c <+37>:   mov    edi,0x400624
0x0000000000400581 <+42>:   mov    eax,0x0
0x0000000000400586 <+47>:   call   0x400410 <printf@plt>
0x000000000040058b <+52>:   mov    eax,0x0
0x0000000000400590 <+57>:   leave  
0x0000000000400591 <+58>:   ret    
c
buffer-overflow
asked on Stack Overflow Nov 30, 2014 by Filco • edited Dec 2, 2018 by Alex Bravo

1 Answer

-3

When I run this in gdb debugger it works. So the code is written good, question solved. The problem is somewhere else...

answered on Stack Overflow Nov 30, 2014 by Filco • edited May 19, 2015 by Filco

User contributions licensed under CC BY-SA 3.0