6

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

4

1 回答 1

4

假设我理解这个问题,也许这会让你开始。相对跳跃是基于 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
于 2010-11-30T04:47:25.967 回答