没有函数包含所选帧的程序计数器

12

我试图对一个易受攻击的代码进行缓冲区溢出攻击。

但似乎出了些问题,尽管我的攻击字符串没有破坏堆栈,但我的嵌入式汇编代码却无法运行。

以下是我想要攻击的程序在执行“ret”指令之前的内存值片段。

0x55683984:     0x5568398c   0x...(old r.a)      0x68e322a1      0x0000c31c
0x55683994:     0xf7fa9400      0x0804a3d7       0x556839c0      0xf7e518d0

在此时候,问题出现了,因为它无法弹出栈并使%eip指向已经弹出的值?所以我的漏洞利用汇编代码失效了。(0x68e322a1 0x0000c31c)。Gdb报告没有函数包含所选帧的程序计数器。当我尝试不进行调试而执行它时,会导致分段错误。

这个问题是否与我的汇编代码长度有关呢?(在这种情况下是6)?

Program received signal SIGSEGV, Segmentation fault.
0x5568398c in ?? ()
(gdb) x 0x5568398c
0x5568398c: 0x68e322a1

当我能够看到导致段错误的地址内部内容时,这是如何发生的?


你可以使用 disassemble 或者 x/10i $eip 来查看程序在哪个位置出现了段错误,使用 bt 命令来查看调用栈。如果您能够提供您正在执行的代码,那么我们就可以更方便地提供帮助(假如是因为 68 e3 .. 出现了错误,看起来可能存在零散的字节)。另外,如果这是作业,请标注一下。 - user786653
我使用了 layout asm 来查看发生了什么,但并没有帮助。此外,现在我的攻击代码以 c3(表示 ret 指令)结尾,一个孤立的零字节不是问题。关键是我意外地试图访问可能未定义的内存地址。 - bfaskiplar
2个回答

15

默认情况下,disassemble会打印出当前函数的代码。在您的情况下,程序计数器指向堆栈的某个位置,gdb无法理解当前函数的边界在哪里,因此会出现错误信息。

但您可以手动指定要反汇编的地址范围:

(gdb) disassemble 0x7fffffffbb00,0x7fffffffbbff

4
非常棒的技巧。或者,你可以使用 disassemble $rip, $rip+offset 命令来简化查找堆栈框架位置的过程。请注意,这并不会改变原意。 - Eric

6

好的,这里是故事。在我的汇编代码中,我忘记在movl指令前面加上“$”符号。因此,程序试图访问未定义的内存地址,导致段错误。

但是,我不喜欢GDB仅通过说“没有函数包含所选帧的程序计数器”来通知此情况的方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接