【问题标题】:Determining register values when using objdump使用 objdump 时确定寄存器值
【发布时间】:2010-11-30 03:32:52
【问题描述】:

所以我尝试使用 objdump 实用程序从程序集构建控制流图,但遇到了问题。基本上,每当发生分支并且目标地址是相对的时,我不确定如何知道下一个基本块从哪里开始。我不确定我是否清楚,所以我将添加一个示例。假设我的程序正在通过 objdump 输出,并记录了第一个基本块的起始地址。然后它会执行一个跳转命令,该命令使用相对寻址来指向要跳转到的正确地址。我知道我的第一个基本块的结尾就在那儿,但是我如何为下一个基本块的开头获取正确的地址?任何人都可以提供任何指导将不胜感激,我充其量只是一个 x86 新手,过去一周我一直在努力解决这个问题。

【问题讨论】:

    标签: assembly x86 x86-64 control-flow objdump


    【解决方案1】:

    假设我理解了这个问题,也许这会让你开始。相对跳跃是基于 pc 的。

    d: eb 04 jmp 13

    0xEB 是基于 8 位立即数的相对跳转的操作码。指令的地址在 objdump 输出中,在本例中为 d 或 0xD。它是一个两字节指令(x86 是可变长度)。它会在输出中告诉您目标地址是什么,在本例中为 jmp 13。因此,在 objdump 输出中查找以 13 开头的行,冒号是下一段代码的开头。

    了解该地址是如何计算的。 pc 开始取指令时位于 0xD,需要两个字节,因此 pc 在准备执行该指令时位于 0xD+2 = 0xF。偏移量为 0x4,因此 0xF+0x4 = 0x13 目标地址。

    20:75 ed jne f

    向后也是一样。 pc 加上字节数 = 0x20+2 = 0x22。 0xED 是带符号的数字并且是负数,因此符号将 0xED 扩展到 0xFFFFFFF...FFFFED,无论您的地址寄存器有多大。添加 0x22+0xFFFFFF...FFFED 得到 0x0F 目标地址。您也可以取 0xED,反转并加 1 来否定它。 ~0xED = 0x12,0x12+1 = 0x13。所以 0xED 表示减去 0x13。 0x22-0x13=0x0F。

    这里还有一些,在每种情况下,它都会为您提供可以在 objdump 输出中查找的目标地址。

    了解它如何计算该值。同样的故事,从 0x400A81 处的操作码开始,在这种情况下,可变长度指令需要 6 个字节。因此,当您准备好执行 pc 时,地址为 0x400A81+6 = 0x400A87。偏移量为 0x107,因此如果满足条件,则目标地址为 0x400A87 + 0x107 = 0x400B8E。

    请注意,这些是从更大的程序中提取的,而不是顺序代码,只是孤立示例的集合。

    400a81:0f 8f 07 01 00 00 jg 400b8e 400a8f:0f 8f e6 00 00 00 jg 400b7b 400a9d:0f 8f c5 00 00 00 jg 400b68 400aab:0f 8f a4 00 00 00 jg 400b55 400ab9:0f 8f 83 00 00 00 jg 400b42 401d76:0f 8f 31 01 00 00 jg 401ead

    【讨论】:

    • 非常感谢,这解决了我的很多问题。基本上看起来我只是不完全理解我正在使用的 objdump 输出。有谁知道了解更多关于 objdump 输出的好资源吗?
    • 我正在阅读一些输出,这肯定会澄清很多。我仍然不确定这样的一行: 4020a6: ff 25 4c 8f 21 00 jmpq *0x218f4c(%rip) # 61aff8 <_fini> 基本上看起来我只是不完全理解我的 objdump 输出我一起工作。有谁知道了解更多关于 objdump 输出的好资源吗?
    • 我想说你正在寻找的是理解 x86 汇编器不一定是 objdump。该特定指令的操作码不会向我跳出(不是双关语),但语法对我来说暗示它是基于寄存器的东西,这意味着目标地址与运行时 %rip 的内容有关,跳转表基本。而且由于您没有执行此代码而只是检查它,因此可能不清楚 %rip 的内容是什么,因此您可能无法弄清楚目标地址是什么。
    • 或者可能在 0x218f4c 有一个表,其中包含可能的地址列表。尽管表有多深与程序有关,如果不分析整个代码(与一次一条指令相比),不一定很明显。
    • x86 绝对不是第一次学习的入门汇编语言。可能会使用模拟器退回到 msp430。我也会说 arm 或 thumb ,但它们的操作码编码比 x86 更难理解。其他人的指令要少得多,并且没有这个 8 位处理器,然后是 16 位,然后是 32 位,然后是 64 位补丁,随着时间的推移,可以形成一个很长的操作码列表,可以用不同的方式解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 2015-06-17
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多