1.Mach-O文件种类
Mach-O文件大致可分为如下这么多,分别在文件fat.h
和 load.h
中有说明我已上传github,有兴趣的可以下载来看,对一些字段也有相应的注释,文件出自xnu开源代码
可以在终端通过file + Mach-O文件名查看其架构,
早期有ARMV7,ARMV7s,等架构,现在主流的几乎都是ARM64的.
yangpei1@localhost Desktop % file WeChat
WeChat: Mach-O 64-bit executable arm64
yangpei1@localhost Desktop %
2.Mach-O文件字段介绍
1.关于CPU的常用类型包括
CPU_TYPE_X86, CPU_TYPE_I386, CPU_TYPE_X86_64, CPU_TYPE_ARM, CPU_TYPE_ARM64
等...
2.CPU的子类型CPU_SUBTYPE_X86_ALL, CPU_SUBTYPE_X86_64_ALL, CPU_SUBTYPE_X86_ARCH1, CPU_SUBTYPE_X86_64_H
//In fat.h file
struct fat_header {
uint32_t magic; 魔数(特征字段),标识当前设备是大端序还是小端序,iOS是小端序
uint32_t nfat_arch; 包含几种架构类型
};
struct fat_arch {
cpu_type_t cputype; CPU类型
cpu_subtype_t cpusubtype; 标识具体的CPU类型
uint32_t offset; 指定该CPU架构数据相对于文件开头的偏移量
uint32_t size; 指定该CPU架构数据的大小
uint32_t align; 内存对齐边界,取值必须是2的N次方
};
//In loader.h file
struct mach_header {
uint32_t magic;魔数值,每个架构下的魔数值都是固定的,mach_64是0xFEEDFACF,
cpu_type_t cputype; /* cpu specifier */
cpu_subtype_t cpusubtype;
uint32_t filetype; Mach-O的文件类型
uint32_t ncmds; Mach-O文件中,加载命令的数量
uint32_t sizeofcmds; Mach-O文件中,加载命令所占的总字节大小
uint32_t flags; 标志信息
};
3.Mach-O文件结构组成
Mach-O文件主要分为
Header
,Load Command
,Data
三部分组成,Data中每个段(Segment)的数据都保存在这里,段的概念与ELF
文件中段的概念类似,每个段中都会有数目不等的额Section,他们存放了具体的数据代码.
这里可以用MachOView
或 010Editor
查看详细结构,
4.Mach-O文件加载命令
LC_LOAD_DYLIB
:指向的是程序依赖库的加载信息,日常的分析过程中,比较熟知的/System/Library, usr/lib,还有一些@rpath,@executable_path,在未越狱平台注入动态库的原理就是向Mach-O文件中添加一条LC_LOAD_DYLIB
加载命令.
LC_CODE_SIGNATURE
:是代码签名的加载命令,一般在最后一段中
struct linkedit_data_command {
uint32_t cmd; /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
LC_FUNCTION_STARTS, LC_DATA_IN_CODE,
LC_DYLIB_CODE_SIGN_DRS,
LC_LINKER_OPTIMIZATION_HINT,
LC_DYLD_EXPORTS_TRIE, or
LC_DYLD_CHAINED_FIXUPS. */
uint32_t cmdsize; /* sizeof(struct linkedit_data_command) */
uint32_t dataoff; /* file offset of data in __LINKEDIT segment */
uint32_t datasize; /* file size of data in __LINKEDIT segment */
};
LC_SEGMENT
:表示这是一个段加载命令,需要将它加载到对应的进程空间中.
LC_MAIN
:记录可执行文件主函数main()的位置,
LC_ENCRYPTION_INFO
:存储着被加密的APP文件,也就是加壳的文件,针对这个特性,将内存中解密的数据写回原位,并将cryptid置为零,来达到解密的目的,解密工具就是我们熟知的dumpdecrypted