MachO文件(12)
MachO文件
Mach-O其实是Mach Object文件格式的缩写,是mac以及iOS上可执行文件的格式, 类似于windows上的PE格式 (Portable Executable ), linux上的elf格式 (Executable and Linking Format)
Mach-O为Mach object文件格式的缩写,它是一种用于可执行文件、目标代码、动态库的文件格式。作为a.out格式的替代,Mach-O提供了更强的扩展性。
MachO格式的常见文件
- 目标文件.o
- 库文件
- .a
- .dylib
- Framework
- 可执行文件
- dyld
- .dsym
//将test.c通过clang进行编译生成test.o clang -c test.c //通过 $file 文件路径 查看文件类型 file test.o //编译.o生成一个.out的可执行文件 clang test.o -> a.out //file查看.out -> executable意思是可执行 ./a.out 可直接调用 //也可通过下面代码直接生成可执行文件 clang -o test2 test.c clang -o test3 test.o //a.out test2 test3 是一样的, 通过hash值比较 -> md5 a.out
.o文件
编译流程
1. 准确两个文件 test1.c test.c 2. clang -o demo test1.c test.c -> demo可执行文件, ./demo可直接调用 1. 流程为下: 2. clang -c test1.c test.c -> .o 3. clang -o demo1 test.o test1.o -> demo1可执行文件 4. 此时进行hash比较, md5 demo 跟 md5 demo1 hash值却不一样, 因为链接顺序不一样 1. objdump --macho -d demo //查看链接顺序
.a文件 .dylib文件
1.
find /usr -name "*.a"
1.file 路径
2.
find /usr -name "*.dylib"
1.file 路径
dyld
1. cd /usr/lib/ 2. ls dyld 3. file dyld -> dynamic linker 动态链接器 Mach-O文件 1. 有两个架构i386, x86_64
dSYM
工程编译 -> .dSYM -> 显示包文件 file 里面的包内容 -> .dDYM类型, 符号文件 1.排查崩溃信息 -> 拿到堆栈信息 -> 去符号
可执行文件的架构配置
1. 工程 -> Build Seetings -> 搜mach -> 可以更改生成类型 2. 工程编译生成的可执行文件, 默认是arm64 1. 11以上的编译 -> arm64 2. 选择低版本10.3 -> armv7/arm64 3. 架构设置 -> Build Seetings -> architectures 1. 可以修改,比如添加armv7s来支持iPhone5/5c 2. Build Active Architectures only //编译当前架构 1. debug -> 当前运行手机的架构 2. release -> 根据你需要支持的设备来定的, 即选择的编译版本
通用二进制文件 (Universal binary)
苹果公司提出的一种程序代码。能同时适用多种架构的二进制文件
- 同一个程序包中同时为多种架构提供最理想的性能。
- 因为需要储存多种代码,通用二进制应用程序通常比单一平台二进制的程序要大。
- 但是 由于两种架构有共通的非执行资源(代码以外的),所以并不会达到单一版本的两倍之多。
- 而且由于执行中只调用一部分代码,运行起来也不需要额外的内存。
//查看架构 Demo是上面生成的三个架构的 lipo -info Demo //使用lifo –thin 拆分某种架构, 拆出来是某种架构 lipo Demo -thin armv7 -output machO_armv7 //使用lipo -create 合并多种架构 lipo -create machO_armv7 machO_arm64 -output machO_7_64 // 删掉i386,x86_86 lipo -remove i386 NIMSDK -o NIMSDK
MachO文件结构
[图片上传失败...(image-5b2ccc-1619252451688)]
//直接查看otool指令 otool //查看headers信息 otool -f Demo
MachOView来分析, 非常推荐
Header的数据结构
快捷搜索 -> loader.h -> mach_header [图片上传失败...(image-f18376-1619252451688)]
Load Command段
1. Load Command段 -> PAGEZERO -> VM 1. VM Addr : 虚拟内存地址 2. VM Size: 运行时刻, 在内存中的大小 -> 4G空间, 虚拟内存大小 1. 64位 -> 0xffffffff12345678 2. 32位 -> 0x12345678 3. 这样64位就可以兼容32位 3. File offset: 数据在文件中偏移量 4. File size: 数据在文件中的大小 2. LC_DYLD_INFO_ONLY 1. Rebase Info Size 重定向, 运行时, 代码段要统一加上一个偏移量, 称为重定向 3. LC_SYMTAB 符号表信息 4. LC_MAIN 主程序入口 1. 如果别人有做防护, 运行就崩, 那么main不失为一个好的切入点 5. 还有一些需要加载的动态库 [图片上传失败...(image-95a9fd-1619252451688)]
代码段__text
- 主程序代码
- 符号绑定
数据段__Data
- 符号表