接触iOS逆向已经有一段时间了,但是一直没有好好去了解一下最基础的MachO结构,本文主要记录一下对MachO文件结构的学习和理解。
MachO文件的基本格式
Mach-O是Mach Object文件格式的缩写,iOS以及Mac上可执行的文件格式,类似Window的PE,Linux上的ELF。
由下图可知,MachO文件的结构,主要包括Header、LoadCommand、Data三部分,Data部分由Section组成。
- Header:保存了Mach-O的一些基本信息,包括了平台、文件类型、LoadCommands的个数等等。
- LoadCommands:加载Mach-O文件时会使用这里的数据来确定内存的分布。
- Data:每一个segment的具体数据都保存在这里,这里包含了具体的代码、数据等等。
这里介绍一个分析MachO文件结构的必备工具,MachOView
MachOView下载地址:http://sourceforge.net/projects/machoview/
MachOView源码地址:https://github.com/gdbinit/MachOView
效果如下图所示:
MachO头部
MachO头部结构可以从苹果开源的代码中找到,具体如下:
|
|
从上面的代码中可以看出,它由以下部分组成。
- magic:MachO文件的魔数,FAT为0xcafebabe,ARMv7位0xfeedface,ARM64为0xfeedfacf(Mac是小端模式)。
- cputype、cpusubtype:CPU架构和子版本。
- filetype:文件类型。常见的有MH_OBJECT(目标文件)、MH_EXECUTABLE(可执行二进制文件)、MH_DYLIB(动态库)。
- mcmds:加载命令的数量。
- sizeofcms:所有加载命令的大小
- flags:dyld加载需要一些标记。其中,MH_PIE表示启用地址空间布局随机化。
- reserved:64位的保留字段。
Load Command
load Command用于告诉操作系统应当如何加载文件中的数据,对系统内核加载器和动态链接器起指导作用。
load Command包含以下部分:
|
LC_SEGMENT_64定义了一个64位的段,当文件加载后映射到地址空间,64位段的定义如下:
|
|
系统将fileoff偏移处的filesize大小的内容加载到虚拟内存的vmaddr,大小为vmsize,vmsize 并不等于 filesize,对于 4KB 大小的 VP,vmsize 是 4K 的倍数;换句话说,vmsize 一般大于 segment 的实际大小。
端页面的权限由initport进行初始化。但是不能超过 maxprot 中指定的值。
文件中主要包括PAGEZERO、TEXT、DATA、LINKEDIT四种段,段里可以包括不同的节。定义如下:
结构体section_64可以看做 section header,它描述了对应 section 的具体位置,以及要被映射的目标虚拟地址。
回头再看segment_command_64的cmdsize字段,它的数值并非是segment_command_64的 size 大小,还包括了紧接在 command 后面的所有section_64结构体的大小。
如果 segment 含有 5 个 section,那么对应的 segment_command_64 的 cmdsize 值为:72(segment_command_64本身大小) + 5 * 80(section_64的大小) = 472 bytes
_TEXT段和_DATA段
_TEXT
_TEXT段包含了多个节区,各区的作用如下:
- _text节是主程序代码
- _picsymbolstub4节和__syub_helper节用于动态链接
- _cstring是代码里用到的字符串表
- _objc_classname是objc类方法名
- _objc_methname是objc的方法名称
- _objc_methtype是objc的方法类型
- _const是由const修饰的常量
_DATA
_DATA是数据段,里面主要存放数据,可读可写不可执行,部分节区作用如下:
- _got非懒加载全局指针表
- _la_symbol_ptr懒加载指针表
- _cftring使用的字符串信息
- _objc_classlist程序中类列表
- _objc_protolist程序中协议列表
- _objc_imageinfo程序中镜像信息
- _objc_const是objc常量
- _objc_superrefs是objc超类引用
- _objc_ivar是objc类的实例变量
总结
以上是针对MachO文件结构的简单总结,为了更加形象的了解MachO文件结构及其在程序运行中的运用,下一节通过fishhook、class-dump等工具的原理深入了解MachO的工作原理。