简单了解 Mach-O 文件

1,273 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。


Mach-O 文件是什么?

Mach-O(Mach Object)是 macOS iOS iPadOS 存储程序和库的文件格式。对应系统通过应用二进制接口(ABI)来运行改格式的文件。

Mach-O 文件格式保存了在编译过程和链接过程中产生的机器代码和数据,从而为静态链接和动态链接的代码提供了单一文件格式。

当我们在调试iOS 应用程序 点击 运行按钮的时候,做了什么事情? 

实际上是加载ipa(Mach-O_test.app)包  中的可执行文件Mach-O_test   (Products 下的 Mach-O_test.app 显示包内容可以看到)

image.png

image.png

Mach-O_test  可执行文件调用过程:

  1. 调用 fork 函数 创建一个进程

  2. 调用 execve 或其衍生函数,在该进程上加载,执行 Mach-O 文件

    当我们调用时execve(程序加载器),内核实际上在执行以下操作:

    1. 将文件加载到内存

    2. 开始分析 Mach-O 中的mach_header, 以确保它是有效的Mach-O 文件

在终端 用objdump指令分析 Mach-O_test

objdump --macho --private-headers Mach-O_test 

结果如下,有多个Load command:

image.png

Mach-O本质上是二进制文件,不过你可以看成Mach-O是 文件配置 + 二进制代码

main 入口Load command :

image.png

Mach-O 文件是可读可写的,只要按照一定的规则就可以读出里边的数据。

我们可以自己写程序 按照自己的方式,读取 Mach-O 文件 中想要的信息\

下面是一个 读取  Mach-O 的程序 github地址:此程序可以读取到 简洁的Load command (LC)

github.com/penglimin/m…

下载下来后,运行,找到  可执行文件:

image.png

此可执行文件可以在终端执行:

用来读取 Mach-O 文件

比如自己读自己:

./machoinfo machoinfo

image.png

  1. Mach-O  是二进制

  2. Mach-O  可以看成是 配置 + 二进制

  3. Mach-O  的排列是按照一定规则的

  4. Mach-O  是可读可写的

如果你想调试上面的程序:

image.png

我换成了

/Users/xxxxx/Desktop/2021/Mach-O_test

这个参数 会传递到 main 函数里. 你可以跟代码看一下。

到此,我们就简单了解了 Mach-O 文件。

我们编译成可执行文件(Mach-O 文件)的时候, 中间要经历一个 目标文件 也就 .o 文件。 

编译过程 就是把代码 放到 对应的 配置里边。 把源代码背后的符号进行分类,形成一个符号表。

链接过程 就是把多个目标文件(.o文件)组合成一个文件。 把多个符号表合并成一起,产生出一个可执行文件。

Symbol Table:

Symbol Table: 保存符号

String Table:保存符号的名称

indirect Symbol Table: 间接符号表。保存使用的外部符号。准确一点就是使用的外部动态库的符号。是Symbol Table的子集。

比如:NSLog 是 Foundation  库中的 函数,就会放到 indirect Symbol Table 中。

......