2011-05-11 115 views
6

我知道,你可以用gdb在正从$ EBP抵消寻找发现任何参数:如何用gdb读取局部变量?

(gdb) x/4wx $ebp 

然后,我会看在第3和第4地址使用x/s,因为他们将是第一个和第二参数。那么局部变量呢?我如何看待$ ebp的负偏移值? 另外,无论如何看看$ eax的价值吗? 每当我尝试使用x/s $eax打印$ eax的值时,地址超出限制或值为0,我相信这不是因为我只是在寄存器中放置了一个常量值。

我试过info locals但我收到消息“没有符号表信息可用”。

回答

6

首先,您需要将调试符号编译到您的二进制文件中。使用当前命令在gcc上使用-g选项来执行此操作。如果您使用的是其他编译器,则需要查阅其文档。在此之后,'info locals'和打印命令将起作用。

要查看任何局部变量,您只需使用'print'命令。例如,查看局部变量'i'就像'打印i'一样简单。

您应该能够像$ ebp一样处理$ eax。我怀疑你有问题,因为你使用的是x/s。 x/s会尝试打印出一个字符串,所以它会一直持续下去,直到遇到一个空字符。如果这种情况很长时间没有发生,那么字符串的长度将超出界限。试试'x/d $ eax'。你甚至可以'打印$ eax'。您也可以使用'信息寄存器'来获取所有的寄存器数据。

0

我知道,你可以用gdb

这只适用于一些处理器和一些调用约定在正从$ EBP抵消寻找发现任何参数,并且绝不是普遍的。

假设你只关心x86,并且你的代码是用帧指针编译的(这是默认的,但不再是选择模式下GCC 4.6的默认值),本地被分配一个固定的负偏移量从%ebp

显然,如果你可以使用调试符号重新编译你的代码(使用-g),那么GDB将能够打印它们的值,而且你不需要关心GDB如何发现它们。

如果你不能(例如因为代码来自第三方),你必须仔细研究反汇编,并猜测。如果您猜测某个值存储在%ebp-8处,则可以使用GDB检查该值,与检查正偏移量的方式完全相同:(gdb) x/wx $ebp-8

当心:编译器可以自由奠定了当地就是了任何方式,所以如果你声明

int x, y, z; 

编译器是免费的存储x%ebp-16y%ebp-20z%ebp-12