繁体   English   中英

如何从`push%ebp`获取汇编指令的相对偏移量

[英]How to get relative offset of assembly instruction from `push %ebp`

当我在gdb使用disas时。 我可能会得到这样的东西。

(gdb) disas bar
Dump of assembler code for function bar:
   0x08048e84 <+0>: push   %ebp
   0x08048e85 <+1>: mov    %esp,%ebp
   0x08048e87 <+3>: sub    $0x8,%esp
   0x08048e8a <+6>: mov    0xc(%ebp),%eax
   0x08048e8d <+9>: mov    0x8(%ebp),%edx
   0x08048e90 <+12>:    add    %edx,%eax
   0x08048e92 <+14>:    mov    %eax,-0x4(%ebp)
   0x08048e95 <+17>:    mov    0x81f4074,%eax
   0x08048e9a <+22>:    mov    %eax,(%esp)
   0x08048e9d <+25>:    call   0x8048ed8 <traceback>
   0x08048ea2 <+30>:    mov    -0x4(%ebp),%eax
   0x08048ea5 <+33>:    mov    %eax,0x8(%ebp)
   0x08048ea8 <+36>:    leave  
   0x08048ea9 <+37>:    ret    
End of assembler dump.

假设我的C程序中有0x08048ea2 我如何获得偏移量<+30>并获得0x08048e84

很难说出到底要做什么,但是回溯功能通常会查看“堆栈帧”并从那里找到返回地址。 然后,他们解析函数列表,以查找每个返回地址的前一个函数。 如果您在调试器中,那么大概也可以说出返回地址代表的代码行。

从这里,我不确定问题是“如何评估堆栈框架”还是“如何找到'紧邻的函数'”。

堆栈帧的生成是特定于平台的,但通常使用特定的寄存器来保存一个地址,该地址是在函数输入时建立的堆栈上的固定位置。 堆栈框架通常指向堆栈中先前堆栈框架指针处(或旁边)的位置。 这允许使用帧指针遍历堆栈并评估返回地址(返回地址通常位于相对于堆栈帧信息的固定位置。

请注意,编译器可以进行多种优化,这些优化会影响堆栈帧(具体来说有两个:禁用堆栈帧生成和返回值优化)。

确定功能的地址也取决于平台。 如果需要,编译器和链接器将创建和管理调试符号。 这实际上嵌入了一个函数名和起始地址的查找表,该表已加载到内存中供调试器访问。 更好的系统还将提供在发行版本中查找符号名称的功能。 他们通常通过让IDE提供功能基地址(一个映射文件),然后找出代码段被加载到内存中的位置来实现此目的。 我怀疑此信息是由OS调用提供的,但也许还有其他机制。

我有一个愚蠢的方法。 添加这样的标签:

    /* ommit some code */
    label:
    mov    -0x4(%ebp),%eax
    mov    %eax,0x8(%ebp)
    leave  
    ret

然后:

    lea eax, label /* eax will be 0x08048ea2 */
    lea ebx, bar  /* ebx will be 0x08048e84 */
    sub eax, ebx /* get the offset */

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM