如何在没有源代码的情况下在内存中查找变量位置?

时间:2018-09-12 15:53:41

标签: memory gdb

基本上我想在gdb中找到变量的地址/位置吗?

我通常知道变量存储在rbp,但不知道如何使用gdb定位它们。

1 个答案:

答案 0 :(得分:0)

  

我想在gdb中找到变量的地址/位置吗?

这是可能的,但是方法取决于变量是全局变量还是局部变量。

  

我通常知道变量存储在rbp

局部变量存储在帧指针的某些偏移处。 %RBP通常用作未优化二进制文件中的帧指针。

要找到这样的变量,您需要知道如何阅读机器代码,然后才能找到它。 GDB不会帮助您在没有调试信息的情况下找到它(无法)。

  

没有源代码

源代码与此无关,GDB从不查看源代码,只是向您显示源代码。

具体示例。假设您有以下来源:

int foo(int *ip) { return *ip + 42; }
int main()
{
  int j = 1;
  return foo(&j);
}

在没有调试信息且没有优化的情况下进行编译会导致:

(gdb) disas main
Dump of assembler code for function main:
   0x000000000000060d <+0>:     push   %rbp
   0x000000000000060e <+1>:     mov    %rsp,%rbp
   0x0000000000000611 <+4>:     sub    $0x10,%rsp
   0x0000000000000615 <+8>:     movl   $0x1,-0x4(%rbp)
   0x000000000000061c <+15>:    lea    -0x4(%rbp),%rax
   0x0000000000000620 <+19>:    mov    %rax,%rdi
   0x0000000000000623 <+22>:    callq  0x5fa <foo>
   0x0000000000000628 <+27>:    leaveq
   0x0000000000000629 <+28>:    retq
End of assembler dump.

在这里您可以清楚地看到j4的偏移量为%rbp负偏移量。

您可以在foo上设置一个断点,并使用GDB像这样检查其值:

(gdb) b foo
Breakpoint 1 at 0x5fe
(gdb) run

Breakpoint 1, 0x00005555555545fe in foo ()
(gdb) up
#1  0x0000555555554628 in main ()
(gdb) x/x $rbp-4
0x7fffffffdbcc: 0x00000001      // indeed that is expected value of j