为什么64位地址的前4个字节打印为0x00000001?

时间:2013-05-08 16:09:01

标签: macos 64-bit offset memory-address otool

我正在查看使用Apple的otool对一些x86_64代码进行反汇编。以下是otool输出的反汇编示例:

0000000100055de4    movq    $0x00000000,%rax

只有该偏移量中的最后4个字节00055de4表示该指令的文件地址。我可以打开一个十六进制编辑器并导航到0x55de4movq指令就在那里。

然而,我注意到gdb仅在我在地址中包含所有8个字节时才有效,包括神秘的1break *0x0000000100055de4按预期工作,而break *0x00055de4永远不会触发。

我用otool分析的每个64位二进制文​​件都显示了这种模式。它显然不适用于32位地址。

因此,如果0x55de4是实际地址,为什么otoolgdb使用0x0000000100055de4

1 个答案:

答案 0 :(得分:1)

__ PAGEZERO是64位Mach-O二进制文件中的第一个加载命令,它指定虚拟内存中的段大小为0x100000000。

$ otool -lV 二进制

command 0
      cmd LC_SEGMENT_64
  cmdsize 72
  segname __PAGEZERO
   vmaddr 0x0000000000000000
   vmsize 0x0000000100000000

当你执行break *0x00055de4时,你的断点最终会出现在这段零中,这就解释了为什么它永远不会被击中。 0x0000000100055de4是加载到虚拟内存中时指令的地址(在二进制文件中的0x55de4处找到)。

对于32位二进制文​​件,__PAGEZERO大小为0x1000,这解释了该模式不适用的原因。