Mach-O文件格式

1.Mach-O文件种类

Mach-O文件大致可分为如下这么多,分别在文件fat.hload.h中有说明我已上传github,有兴趣的可以下载来看,对一些字段也有相应的注释,文件出自xnu开源代码

可以在终端通过file + Mach-O文件名查看其架构,
早期有ARMV7,ARMV7s,等架构,现在主流的几乎都是ARM64的.

yangpei1@localhost Desktop % file WeChat
WeChat: Mach-O 64-bit executable arm64
yangpei1@localhost Desktop %
Mach-O文件种类

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;       标志信息
};

Mach-O头文件

3.Mach-O文件结构组成

Mach-O文件主要分为Header,Load Command,Data三部分组成,Data中每个段(Segment)的数据都保存在这里,段的概念与ELF文件中段的概念类似,每个段中都会有数目不等的额Section,他们存放了具体的数据代码.

Mach-O文件结构

这里可以用MachOView010Editor查看详细结构,

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

你可能感兴趣的:(Mach-O文件格式)