无法访问x86-32上的返回地址

时间:2014-02-19 18:09:43

标签: assembly x86 gdb buffer-overflow shellcode

我正在尝试缓冲区溢出,但是,我陷入了困境。我覆盖了返回地址,因此EIP将指向我的shellcode的nop雪橇的地址。但是,运行ret时,我收到错误:Cannot access memory at address 0x90909094。任何人都可以看到有什么问题吗?

内存转储:

(gdb) x/8wx $esp
0xbffff18c: 0xbffff470  0xbffff400  0x00000000  0x08048559
0xbffff19c: 0xb7fc6ff4  0x08048550  0x00000000  0x00000000
(gdb) x/8wx 0xbffff470
0xbffff470: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff480: 0x90909090  0x90909090  0x90909090  0x90909090
(gdb) nexti
Cannot access memory at address 0x90909094
(gdb) i r eip
 eip            0xbffff470  0xbffff470

如您所见,返回地址为0xbffff470,在该位置放置了我的nop雪橇。但是,只要我运行下一条指令(ret),就会出错。这有什么不对? 编辑:我正在使用x86-32

编辑:我在另一篇文章中找到了答案:GDB ret "cannot access memory at address"  基本上,问题是在地址esp设置为等于ebp之前,在我的情况下将是0x90909090。因此,快速解决的是不使用'A作为填充,而是仅使用每个单词中的地址。

1 个答案:

答案 0 :(得分:0)

OP回答他自己的问题(或多或少):

  

编辑:我在另一篇文章中找到了答案:GDB ret "cannot access memory at address"基本上,问题是在地址esp设置为等于ebp之前,在我的情况下将是0x90909090。因此,快速解决是不要使用'A'作为填充,而只是使用每个单词中的地址。

换句话说,问题是他已经覆盖了当前函数堆栈帧的某些,但没有覆盖存储返回地址的堆栈上的实际点。

// let's say his function ended with a "return 0"...
xorl %eax, %eax
// now here is where he did the "x/8wx" debugger command...
// but then the function epilogue goes and does the usual thing:
movl  %esp, %ebp
popl  %ebp
// and so here, at the actual return, %esp no longer points
// to the same bytes he saw with "x/8wx"
ret

The linked answer表明他的调试器可能会遇到leave指令(相当于上面描述的movl / popl)的某些故障,这样调试器告诉 OP他在ret指令处被停止但是处理器还没有执行leave

等效地,调试器可能会对函数序言或结尾中间的断点进行厌恶,这样如果您尝试在结尾的中间设置断点,则会秘密调整到结尾的开头。< / p>