Macos 为什么otool会截断我的反汇编输出?

Macos 为什么otool会截断我的反汇编输出?,macos,lldb,disassembly,mach-o,otool,Macos,Lldb,Disassembly,Mach O,Otool,当我运行这个命令时 otool -t binary otool将正确转储二进制文件的文本部分。例如 0000000100002100 55 48 89 e5 41 56 53 48 8b 35 32 24 54 00 4c 8b : 但当我运行此命令时: otool -tvV binary otool跳过了文本部分的大部分内容: 00000001003a32ce pushq %rbp : 前3805646字节被简单地跳过,而不是反汇编。如果我在lldb中打开二进制文件,我可以在跳过

当我运行这个命令时

otool -t binary
otool
将正确转储
二进制文件的文本部分。例如

0000000100002100   55 48 89 e5 41 56 53 48 8b 35 32 24 54 00 4c 8b 
:
但当我运行此命令时:

otool -tvV binary
otool
跳过了文本部分的大部分内容:

00000001003a32ce pushq %rbp
:
前3805646字节被简单地跳过,而不是反汇编。如果我在
lldb
中打开二进制文件,我可以在跳过的地址处很好地反汇编代码

有没有人有过类似的经历?
otool
是否有内部大小限制并截断超出该限制的部分?是否有人发现了一种变通方法,或者知道一种可免费使用的类似工具

我试图用
lldb
反汇编整个二进制文件:

lldb binary
(lldb) dis -s 0x100002100 -e ...

-e
设置为文本部分中最后一个字节的地址,但这也不起作用。实际上,
lldb
在分解大约5000字节的文本部分后停止输出。

我以前见过这种情况,我相信
otool
正在(令人烦恼地)跳转到第一个符号。如果执行
nm-n二进制
,则在
0000000 1003A32CE
处定义的第一个符号是否为

Xcode附带了另一个工具,叫做
otool classic
,它似乎可以分解整个文本段。据推测,这是重写或类似操作之前的较旧版本的
otool
。虽然它获得了整个文本段,但在其他方面(如对选择器或字符串的引用进行解码)它可能没有那么出色。要调用它,可以使用
xrun-otool-classic


在我的测试中,您还可以使用Xcode早期版本附带的
otool
。Xcode 7.3.1和Xcode 6.4中的代码没有这个问题。(这些是我碰巧可以测试的,其他的可能也可以。)

基于Ken Thomases的回复和评论,我用旧Xcode版本的
otool
进行了一些测试,发现Xcode 7.3.1中的
otool
工作得更好,但也不会分解整个文本部分。我向苹果提交了一份缺陷报告,结果如下:

工程部已确定该问题的行为符合预期 关于下列信息:

otool(1)的实现在Xcode 8中更改为基于 llvm objdump(1)来自旧的otool经典(1),目前仍在使用中 系统

对于llvm社区,启动反汇编的当前行为 从第一个已知的符号开始,就是llvm社区的行为 欲望


事实上,
otool-classic
可以正常工作(
xcrun-otool-classic
可以正常工作),就像Ken在他的评论中指出的那样,但我对这个回复不满意,因此我现在将在LLVM项目中提交一个bug。

您可能就在这里。带有地址的第一个符号位于
0x100000000
,但这只是
mh_execute_头
,它不是真正的符号,而是用作基偏移量。第二个位于
0x1003a32ce
,这是第一个“实”符号。反汇编似乎从这里开始,跳过之前的任何内容。哇,太疯狂了。我会试试旧的耳石,看看会发生什么。是的,你完全正确。我在Xcode 7.3.1中尝试了
otool
,它的工作原理与预期一致,因此这显然是一个bug。你已经向苹果公司报告了吗?我想我现在会这么做,即使它被当作傻瓜关上了。非常感谢!好的,看来7.3.1的
otool
也不能正常工作。它在第一个符号之前掩饰一切,而在它之后却什么也没有。只需将这两个函数的输出进行组合,即可生成整个binary.Hmm的汇编代码。在我的测试用例中,7.3.1中的一个分解了整个文本段,而不仅仅是第一个符号。我还注意到在Xcode 7.x和Xcode 8.x中都有一个
otool classic
命令。它似乎也起作用了。您可以使用
xcrun-otool-classic
调用它
otool-classic
确实可以正常工作,它确实可以反汇编所有代码!我不知道为什么7.3.1不适合我。。。可能是因为我没有将命令行完全更改为7.3.1(仍然设置为8.2.1),只是在7.3.1包中直接调用了otool?但有了otool classic,我们就有了一个完美的解决方案。你可能想在答案中加上这个,因为我认为这是大多数有类似问题的人的完美答案。