小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
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 显示包内容可以看到)
Mach-O_test 可执行文件调用过程:
-
调用 fork 函数 创建一个进程
-
调用 execve 或其衍生函数,在该进程上加载,执行 Mach-O 文件
当我们调用时execve(程序加载器),内核实际上在执行以下操作:
-
将文件加载到内存
-
开始分析 Mach-O 中的mach_header, 以确保它是有效的Mach-O 文件
-
在终端 用objdump指令分析 Mach-O_test
objdump --macho --private-headers Mach-O_test
结果如下,有多个Load command:
Mach-O本质上是二进制文件,不过你可以看成Mach-O是 文件配置 + 二进制代码
main 入口Load command :
Mach-O 文件是可读可写的,只要按照一定的规则就可以读出里边的数据。
我们可以自己写程序 按照自己的方式,读取 Mach-O 文件 中想要的信息\
下面是一个 读取 Mach-O 的程序 github地址:此程序可以读取到 简洁的Load command (LC)
下载下来后,运行,找到 可执行文件:
此可执行文件可以在终端执行:
用来读取 Mach-O 文件
比如自己读自己:
./machoinfo machoinfo
-
Mach-O 是二进制
-
Mach-O 可以看成是 配置 + 二进制
-
Mach-O 的排列是按照一定规则的
-
Mach-O 是可读可写的
如果你想调试上面的程序:
我换成了
/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 中。
......