我正在查看使用Apple的otool
对一些x86_64代码进行反汇编。以下是otool
输出的反汇编示例:
0000000100055de4 movq $0x00000000,%rax
只有该偏移量中的最后4个字节00055de4
表示该指令的文件地址。我可以打开一个十六进制编辑器并导航到0x55de4
,movq
指令就在那里。
然而,我注意到gdb仅在我在地址中包含所有8个字节时才有效,包括神秘的1
。 break *0x0000000100055de4
按预期工作,而break *0x00055de4
永远不会触发。
我用otool
分析的每个64位二进制文件都显示了这种模式。它显然不适用于32位地址。
因此,如果0x55de4
是实际地址,为什么otool
和gdb
使用0x0000000100055de4
?
答案 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,这解释了该模式不适用的原因。