Mach-O详解

作者: 七维树 | 来源:发表于2021-05-05 18:26 被阅读0次

    是一种文件格式

    • 就像png/jpg是存储图片的格式,avi/mov/mpeg4是存储视频的文件格式,txt存储字符 一样,就是一种按照固定格式存储数据的文件格式。
    • 主要用于存储 可执行文件Exec,动态库/静态库等

    格式解析

    1. Header : 存储该Mach-O文件的基本信息,大小和Load Comand的个数等
    //usr/include/mach-o/Loader.h
    struct mach_header {
        uint32_t    magic;      /* mach magic number identifier */
        cpu_type_t  cputype;    /* cpu specifier */
        cpu_subtype_t   cpusubtype; /* machine specifier */
        uint32_t    filetype;   /* type of file */
        uint32_t    ncmds;      /* number of load commands */
        uint32_t    sizeofcmds; /* the size of all the load commands */
        uint32_t    flags;      /* flags */
    };
    
    struct mach_header_64 {
        uint32_t    magic;      /* mach magic number identifier */
        cpu_type_t  cputype;    /* cpu specifier */
        cpu_subtype_t   cpusubtype; /* machine specifier */
        uint32_t    filetype;   /* type of file */
        uint32_t    ncmds;      /* number of load commands */
        uint32_t    sizeofcmds; /* the size of all the load commands */
        uint32_t    flags;      /* flags */
        uint32_t    reserved;   /* reserved */
    };
    
    1. Load Command : 加载命令指定了这个文件在虚拟内存中的逻辑结构和文件布局,紧随着Header,是连续存储的
    - Segment command
    LC_SEGMENT(__PAZEZERO) : 空指针陷阱,主要用作区分32位和64位指令数据
    struct segment_command { /* for 32-bit architectures */
        uint32_t    cmd;        /* LC_SEGMENT */
        uint32_t    cmdsize;    /* includes sizeof section structs */
        char        segname[16];    /* segment name */
        uint32_t    vmaddr;     /* memory address of this segment */
        uint32_t    vmsize;     /* memory size of this segment */
        uint32_t    fileoff;    /* file offset of this segment */
        uint32_t    filesize;   /* amount to map from the file */
        vm_prot_t   maxprot;    /* maximum VM protection */
        vm_prot_t   initprot;   /* initial VM protection */
        uint32_t    nsects;     /* number of sections in segment */
        uint32_t    flags;      /* flags */
    };
    
    struct segment_command_64 { /* for 64-bit architectures */
        uint32_t    cmd;        /* LC_SEGMENT_64 */
        uint32_t    cmdsize;    /* includes sizeof section_64 structs */
        char        segname[16];    /* segment name */
        uint64_t    vmaddr;     /* memory address of this segment */
        uint64_t    vmsize;     /* memory size of this segment */
        uint64_t    fileoff;    /* file offset of this segment */
        uint64_t    filesize;   /* amount to map from the file */
        vm_prot_t   maxprot;    /* maximum VM protection */
        vm_prot_t   initprot;   /* initial VM protection */
        uint32_t    nsects;     /* number of sections in segment */
        uint32_t    flags;      /* flags */
    };
    
    LC_DYLD_INFO_ONLY //动态链接时的信息
    - ASLR(Slider)随机偏移值
    - Rebase + ASLR = 函数地址  //rebase是根据ASLR偏移计算函数地址
    
    LC_SYMTAB //符号表,字符串
    LC_DYSYMTAB //动态符号表
    LD_LOAD_DYLINKER //dyld地址
    LC_UUID //uuid
    LC_VERSION_MIN_IPHONEOS //最低支持版本
    LC_SOURCE_VERSION //当前程序版本
    LC_MAIN //main函数地址,快速定位到main函数很重要,有的app防护了会闪退
    LC_ENCRYPTION_INFO_64 //加密信息
    LC_LOAD_DYLIB //动态库,主要看这里改这里
    LC_RPATH //地址
    LC_FUNCTION_STARTS//方法开始地方
    LC_DATA_IN_CODE
    LD_CODE_SIGNATURE //代码签名
    
    
    1. Data:包含数据段具体数据
    __TEXT //代码段
    __stubs //符号绑定
    __stub_helper //符号绑定
    
    __DATA //数据段
    __got //外部符号绑定,非懒加载
    __la_symbol_ptr //外部符号,懒加载
    
    
    __LINKEDIT
    
    - VM Address //虚拟内存地址,看这个偏移值
    - VM Size //虚拟内存大小
    - File offset : 数据在文件中的偏移量
    - File size :数据大小
    
    

    胖二进制(Fat Binary)多种cpu架构的Mach-O 打包在一起

    //合并二进制文件
    lipo -create  <file1> <file2> -o <outFile>
    //拆分二进制文件
    lipo <demo> -thin i386 -output <outFile>
    //查看信息
    lipo -info
    

    工具推荐

    • MachOView(烂苹果)
    • Hopper Disassable

    相关命令

    //查看文件格式
    file filename
    //查看二进制文件
    objdump <filename>
    objdump --macho --exports-trie <filename>
    
    //生成中间文件.0
    clang -c <fileName>
    clang -o <inFile> <outFile>
    // 查看二进制信息
    otool -f <filename>
    //内存页大小
    pagesize
    

    相关文章

      网友评论

        本文标题:Mach-O详解

        本文链接:https://www.haomeiwen.com/subject/vbwscltx.html