2

我对汇编语言真的很陌生,我正在尝试解码从二进制文件(使用 gdb)生成的汇编文件。我无法理解以下代码(这是新功能的开始)。我在 x64 机器上,%rdi拥有 6 位数字(我的输入)。所以让我们说那是0 1 2 3 4 5

   400e79:       55                      push   %rbp
   400e7a:       48 89 e5                mov    %rsp,%rbp
   400e7d:       48 83 ec 30             sub    $0x30,%rsp
   400e81:       48 89 7d d8             mov    %rdi,-0x28(%rbp)
   400e85:       48 8d 75 e0             lea    -0x20(%rbp),%rsi
   400e89:       48 8b 7d d8             mov    -0x28(%rbp),%rdi

如果可以的话,我想向您展示我的想法:

400e79:所以当我们启动一个函数时,我们将旧的基指针压入堆栈。所以堆栈看起来像:

 RETURN ADDRESS
 old %rbp value  <--- %rsp

400e7a:堆栈看起来像:

 RETURN ADDRESS
 old %rbp value <---- %rsp, %rbp

400e7d:堆栈看起来像:

 RETURN ADDRESS
 old %rbp value  <----%rbp
 ----empty----
 ----empty----
 ----empty----
 ----empty----
 ----empty----
 ----empty----  <---%rsp

400e81: 这里的东西让我很困惑。我们正在将%rdi( 0 1 2 3 4 5) 中的内容移动到-0x28(%rbp). 所以堆栈看起来像:

 RETURN ADDRESS
 old %rbp value  <----%rbp
 ----empty----
 ----empty----
 ----empty----
 ----empty----
 0 1 2 3 4 5
 ----empty----  <---%rsp

但是,当我尝试通过在 gdb-0x28(%rbp)上运行来查看内容时x/s $rbp-0x28,我没有得到0 1 2 3 4 5预期的结果,但我得到了"\020C". 我运行正确吗?

400e85:堆:

 RETURN ADDRESS
 old %rbp value  <----%rbp
 ----empty----
 ----empty----
 ----empty----
 ----empty---- <--- %rsi
 0 1 2 3 4 5
 ----empty----  <---%rsp

400e89:我完全不明白这一点。刚才我们做mov %rdi,-0x28(%rbp)了,为什么现在做mov -0x28(%rbp),%rdi?这不是重复吗?

非常感谢!我知道这真的很长,感谢您抽出时间帮助我!

4

1 回答 1

2

你的分析是正确的。

运行时得到奇怪结果的原因x/s $rbp-0x28是您不能将字符串放入寄存器中。寄存器包含的值很可能是指向该字符串的指针,这意味着您需要另一个级别的间接来读取它。我相信这会奏效:

p/x *(char**)($rbp-0x28)
x/s $

至于无用的负载,这对于未经优化编译的代码很常见。编译器盲目地将每一行转换为汇编,而不考虑当前寄存器值。我已经看到代码通过几个寄存器将单个值传递回它最初所在的寄存器。

于 2012-10-26T05:10:42.510 回答