Mach-O是Mach object的缩写,是Mac\iOS上用于存储程序、库的标准格式
MH_OBJECT
目标文件(.o) 静态库文件(.a),静态库其实就是N个.o合并在一起
MH_EXECUTE:可执行文件
.app/xx
MH_DYLIB:动态库文件
.dylib .framework/xx
MH_DYLINKER:动态链接编辑器
/usr/lib/dyld
MH_DSYM:存储着二进制文件符号信息的文件
.dSYM/Contents/Resources/DWARF/xx(常用于分析APP的崩溃信息)
在Xcode中查看target的Mach-O类型
Mach-O的基本结构
一个Mach-O文件包含3个主要区域
1.Header
文件类型、目标架构类型等
header 文件类型(可执行文件,目标文件,动态库,静态库) .目标架构(armv7. arm64 armv7s)
2.Load commands
描述文件在虚拟内存中的逻辑结构、布局
3.Raw segment data
在Load commands中定义的Segment的原始数据
load commands 相当于指针,Raw seggemnt data才是真正的data
窥探Mach-O的结构
命令行工具
file:查看Mach-O的文件类型
file 文件路径
otool:查看Mach-O特定部分和段的内容
lipo:常用于多架构Mach-O文件的处理
- 查看架构信息:lipo -info 文件路径
- 导出某种特定架构:lipo 文件路径 -thin 架构类型 -output 输出文件路径
- 合并多种架构:lipo 文件路径1 文件路径2 -output 输出文件路径
GUI工具
MachOView(https://github.com/gdbinit/MachOView)
Universal Binary(通用二进制文件)(Fat Binary)
- 通用二进制文件
- 同时适用于多种架构的二进制文件
- 包含了多种不同架构的独立的二进制文件
因为需要储存多种架构的代码,通用二进制文件通常比单一平台二进制的程序要大
-
由于两种架构有共同的一些资源,所以并不会达到单一版本的两倍之多
-
由于执行过程中,只调用一部分代码,运行起来也不需要额外的内存
-
因为文件比原来的要大,也被称为胖二进制文件(Fat Binary)
dyld和Mach-O
dyld用于加载以下类型的Mach-O文件
-
MH_EXECUTE
-
MH_DYLIB
-
MH_BUNDLE
APP的可执行文件、动态库都是由dyld负责加载的
在mac/iOS中,使用了/usr/lib/dyld程序来加载动态库 dynamic link editor 动态链接编辑器 dynamic loader ,动态加载器 dyld 动态连接器 可以把我们app的Mach-O载进内存
通过IPA包如何获取某个app的Mach-O文件??
IPA包->修改后缀.ipa为.zip然后解压->Payload文件夹->某某.app->右键显示包内容-> 里面找到无后缀名字的文件,确定是Mach-o文件
检查是否是Mach-0文件?
终端 cd文件目录,输入指令 file 文件名 示例:
Mach-O universal binary with 5 architectures: [arm_v7:current ar archive] [arm64]