2017-01-19 62 views
0

返回地址我用C写的程序(只用于调试):找不到在gdb

void return_input(void) 
{ 
    char array[10]; 

    gets(array); 
    printf("%s\n", array); 
} 

main() 
{ 
    return_input(); 

    return 0; 

}

我一直在尝试堆栈溢出,因为我有工作64位机我

gcc -m32 -mpreferred-stack-boundary=2 -ggdb overflow.c -o overflow 

然后我gdb调试使用程序编译它,拆开return_input功能,我得到:

0x0804841b <+0>: push %ebp 
    0x0804841c <+1>: mov %esp,%ebp 
    0x0804841e <+3>: sub $0xc,%esp 
    0x08048421 <+6>: lea -0xa(%ebp),%eax 
    0x08048424 <+9>: push %eax 
    0x08048425 <+10>: call 0x80482e0 <[email protected]> 
    0x0804842a <+15>: add $0x4,%esp 
    0x0804842d <+18>: lea -0xa(%ebp),%eax 
    0x08048430 <+21>: push %eax 
    0x08048431 <+22>: call 0x80482f0 <[email protected]> 
    0x08048436 <+27>: add $0x4,%esp 
    0x08048439 <+30>: nop 
    0x0804843a <+31>: leave 
    0x0804843b <+32>: ret 

这标志着返回地址应0x0804843b(或不是吗?)但是,检查ESP时(记住这是一个64位机器上编译程序的32位)与x/20x $esp(在设置断点后获取函数和ret),我无法找到返回地址:

0xffffd400: 0xffffd406 0x080481ec 0x08048459 0x00000000 
    0xffffd410: 0xffffd418 0x08048444 0x00000000 0xf7e195f7 
    0xffffd420: 0x00000001 0xffffd4b4 0xffffd4bc 0x00000000 
    0xffffd430: 0x00000000 0x00000000 0xf7fb0000 0xf7ffdc04 
    0xffffd440: 0xf7ffd000 0x00000000 0xf7fb0000 0xf7fb0000 

为什么我看不到返回地址?对于长期的问题抱歉。在此先感谢

+0

你有多少''获取'字符串?覆盖返回地址正是如何使用缓冲区溢出来运行恶意代码... – StoryTeller

+0

@StoryTeller,因为我已经在问题中提到过。我在gets处设置了一个中断,因此并没有输入任何内容。问题是我没有看到返回地址 –

+0

@StoryTeller我从来没有听说过堆栈正在向下发展。你能详细说明这一点吗? –

回答

2

0x0804843b是'ret'。看起来你用'返回地址'来弄糊涂了。返回地址是在调用函数中执行的下一条指令的地址。特别对于此代码:

0x08048425 <+10>: call 0x80482e0 <[email protected]> 
    0x0804842a <+15>: add $0x4,%esp 

返回地址是0x0804842a。

现在,你不知道你到底做了什么。按照你的指定编译,'break gets'+'run'对我来说工作得很好。你确定你是从“内部”获取regs吗?

(gdb) disassemble return_input 
Dump of assembler code for function return_input: 
    0x0804843b <+0>: push %ebp 
    0x0804843c <+1>: mov %esp,%ebp 
    0x0804843e <+3>: sub $0xc,%esp 
    0x08048441 <+6>: lea -0xa(%ebp),%eax 
    0x08048444 <+9>: push %eax 
    0x08048445 <+10>: call 0x8048300 <[email protected]> 
    0x0804844a <+15>: add $0x4,%esp 

这就是应该返回的指令。

0x0804844d <+18>: lea -0xa(%ebp),%eax 
    0x08048450 <+21>: push %eax 
    0x08048451 <+22>: call 0x8048310 <[email protected]> 
    0x08048456 <+27>: add $0x4,%esp 
    0x08048459 <+30>: nop 
    0x0804845a <+31>: leave 
    0x0804845b <+32>: ret  
End of assembler dump. 

(gdb) break gets 
Breakpoint 1 at 0x8048300 
(gdb) run 
[..] 
Breakpoint 1, 0xf7e3a005 in gets() from /lib/libc.so.6 
(gdb) x/20x $esp 
0xffffd160: 0x00000001 0xf7fa3000 0xffffd180 0x0804844a 

而这里是第四位。

0xffffd170: 0xffffd176 0x0804820c 0x08048479 0x00000000 
0xffffd180: 0xffffd188 0x08048464 0x00000000 0xf7df15a6 
0xffffd190: 0x00000001 0xffffd224 0xffffd22c 0x00000000 
0xffffd1a0: 0x00000000 0x00000000 0xf7fa3000 0xf7ffdbe4 
(gdb) 
+0

这里有三个问题:1)如果返回地址不是从函数返回后要执行的下一条指令的地址,那么它是什么?2)我应该溢出哪个地址才能得到分段错误? 3)为什么我无法在'x/20x $ esp'命令中找到'ret'地址? –

+0

1.您首先倾向于什么堆栈状态? 2.你需要覆盖保存返回地址的位置,还有什么。 3.你为什么在寻找'ret'的地址以及你在哪里bt。一般来说,我只能推荐你阅读关于这个主题的经典:http://phrack.org/issues/49/14.html –