【问题标题】:What's the difference between binary and executable files mentioned in ndisasm's manual?ndisasm 手册中提到的二进制文件和可执行文件有什么区别?
【发布时间】:2015-06-29 21:43:57
【问题描述】:

我想用clang 编译我的C 文件,然后用ndisasm 反编译它(用于教育目的)。但是,ndisasm 在它的手册中说它只适用于 binary 而不是 executable 文件:

   ndisasm only disassembles binary files: it  has
   no  understanding  of  the  header  information
   present in object or executable files.  If  you
   want  to disassemble an object file, you should
   probably be using objdump(1).

到底有什么区别?当我使用简单的 C 文件、可执行文件或二进制文件运行 clang 时,它会输出什么?

【问题讨论】:

  • 你不需要反汇编,使用-s swtich 应该会生成程序集。
  • 我不需要做任何事情,我是出于好奇而做的。而且我很好奇人们是如何反汇编二进制文件的,所以我用自己的代码来学习。

标签: c clang disassembly


【解决方案1】:

一个目标文件包含机器语言代码,各种其他信息。听起来ndisasm 只想要机器代码,而不是其他东西。因此,消息告诉您使用objdump 实用程序从目标文件中仅提取机器代码段。然后你大概可以在上面运行ndisasm

【讨论】:

  • 特别是,可执行文件以标头开头,告诉操作系统要加载什么、重定位到哪里、整个文件的哪些部分可执行的等等。 ndisasm 在被问到时会兴高采烈地“分解”该元信息,但这样做毫无意义。这就是引文所说的。
  • 您的下一个问题可能是“好的,以二进制形式仅提取代码段的正确objdump 选项是什么?”我自己浏览了objdump 手册页,然后我也看不出来希望其他人能够在这方面提供帮助。
  • 看来objdump 自带反汇编器。没有从目标文件中提取代码的工具吗? ndisasm 故意保持简单——如果你想让它跳过一个标题,你需要用其他方法找出它的大小,然后把那个数字输入进去。
【解决方案2】:

当我使用简单的 C 文件、可执行文件或二进制文件运行它时,clang 会输出什么?

C 编译器通常能够创建一个“原始”二进制文件,即 Just The Code,保留番茄,因为对于某些(罕见的!)目的可能有用。例如,想想引导扇区(不能以常规方式“加载”可执行文件,因为加载它们的操作系统尚未启动)和可编程 RAM 芯片。操作系统本身通常不喜欢执行“原始二进制代码”——几乎出于相同的原因。一个例外是 MS Windows,它仍然可以运行旧格式的 .com 二进制文件。

默认情况下,clang 会创建一个可执行文件。中间文件,称为目标文件,通常在可执行文件被链接(与库函数和适当的可执行文件头粘合在一起)后被删除。要仅获取 .o 目标文件,请使用 -c 开关。

请注意,对象文件也包含一个标题。毕竟,链接器需要知道文件包含什么才能将其链接到其他部分。

出于教育目的,您可能需要检查目标文件格式。有了这些知识,应该可以编写一个程序,告诉你实际代码在文件中的哪个偏移处开始。然后您可以将该信息输入ndisasm

除了标题之外,文件可能在指令之后包含更多数据。同样,ndisasm 不知道也不关心。如果您的测试程序在末尾的某处包含一个字符串Hello world!,它也会很乐意尝试反汇编它。由你自己来识别这些垃圾,并忽略ndisasm 对它所做的事情。

【讨论】:

    猜你喜欢
    • 2010-11-05
    • 2010-12-28
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    相关资源
    最近更新 更多