我正在尝试缓冲区溢出,但是,我陷入了困境。我覆盖了返回地址,因此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作为填充,而是仅使用每个单词中的地址。
答案 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>