美文网首页
初识Mach-O文件

初识Mach-O文件

作者: 小沛2016 | 来源:发表于2022-04-22 12:27 被阅读0次

    详细版本 https://www.yuque.com/docs/share/077aaf76-0fe6-47da-a7c9-d2af0c4b4e3a?# 《初识Mach-O 文件》

    何为Mach-O文件?

    Mach-O为Mach Object文件格式的缩写,它是一种用于可执行文件,目标代码动态库内核转储的档案格式,mac和iOS的可执行文件都是这种格式

    当然了,他也有很多种存在的格式

    • 目标文件.o
    • 库文件:.a静态库文件;.dylib动态库文件;.framework系统级为动态库文件,自己创建的为静态库文件
    • 可执行文件及MDW.app内部的MDW文件(通用二进制文件)
    • .dyld动态链接器将依赖的动态库加载到内存
    • .dsym符号表

    发展历史

    macOS系统一路走来,支持的CPU及硬件平台都有了很大的变化,从早期的PowerPC平台,到后来的x86,再到现在主流的arm、x86-64平台。软件开发人员为了做到不同硬件平台的兼容性,如果需要为每一个平台编译一个可执行文件,这将是非常繁琐的。为了解决软件在多个硬件平台上的兼容性问题,苹果开发了一个通用的二进制文件格式(Universal Binary)。

    Mach-O文件的内部结构

    官方图片

    image.png

    文件分为三个部分:

    1、Header:包含Mach-O文件的基本信息,字节顺序、架构类型、加载指令的数量等

    2、Load commands:包含区域位置、符号表、动态符号表,加载Mach-O文件时使用这里的数据确定内存分布

    3、Data:数据段segement,包含具体代码、常量、类、方法等,有多个segment,每个segment有0到多个section,每个段有一个虚拟地址映射到进程的地址空间

    通过Mach-O文件 可以查看到里面的内容


    image.png

    Header

    image.png
    • magic:魔数,确定是64位还是32位
    • cputype:cpu类型
    • cpusubtype:cpu子类型(arm64 armv7)
    • filetype:Mach-O支持多种文件类型,使用filetype来标注具体文件类型,比如可执行文件、目标文件等等
    • ncmds:加载命令(load commands)的数量
    • sizeofcmds:命令区域(load commands)总的字节大小
    • flags:标识二进制文件所支持的功能,主要与系统的加载、链接有关

    Load commands

    image.png
    • LC_SEGMENT_64:将文件中的段映射到进程地址空间中
    • LC_DYLD_INFO_ONLY:动态链接相关信息
    • LC_SYMTAB:符号表信息,位置、偏移、数据个数,供dyld使用
    • LC_DYSYMTAB:动态符号表信息,供dyld使用
    • LC_LOAD_DYLINKER:链接器信息,记录使用那些链接器完成内核后序的加载工作
    • LC_UUID:Mach-O文件的唯一标识
    • LC_VERSION_MIN_MACOSX:支持最低操作系统版本
    • LC_SOURCE_VERSION:源代码的版本号
    • LC_MAIN:设置主线程的入口即栈大小
    • LC_LOAD_DYLIB:依赖库信息,dyld通过该命令去加载依赖库
    • LC_FUNCTION_STARTS:函数的起始地址表
    • LC_CODE_SIGNATURE:代码签名
    image.png
    • sectname:是__text ,就是主程序代码
    • segname:该section所属的segment名,第一个是__TEXT
    • addr:当前section在内存中的起始位置
    • size:当前section所占内存大小
    • offset:当前section的文件偏移
    • align:字节大小对齐
    • reloff:重定位入口的文件偏移,0
    • nreloc:需要重定位的入口数量,0
    • flags:包含section的type和attributes
    • reserved1、reserved2预留字段

    Data

    Data区域由Segment段和Section节组成

    Segment

    segment主要有__TEXT和__DATA组成

    __text:是主程序代码
    __stubs、__stub_helper:是动态链接的桩
    __cstring:程序中c语言字符串
    __const:常量
    
    image.png image.png

    Section
    在 Segment 里面会包含不同的 section ,其结构如下

    struct section_64 { /* for 64-bit architectures */
        char        sectname[16];   /* name of this section */
        char        segname[16];    /* segment this section goes in */
        uint64_t    addr;       /* memory address of this section */
        uint64_t    size;       /* size in bytes of this section */
        uint32_t    offset;     /* file offset of this section */
        uint32_t    align;      /* section alignment (power of 2) */
        uint32_t    reloff;     /* file offset of relocation entries */
        uint32_t    nreloc;     /* number of relocation entries */
        uint32_t    flags;      /* flags (section type and attributes)*/
        uint32_t    reserved1;  /* reserved (for offset or index) */
        uint32_t    reserved2;  /* reserved (for count or sizeof) */
        uint32_t    reserved3;  /* reserved */
    };
    
    sectname: section 的名字
    segname: segment 的名字
    addr: 映射到虚拟地址的偏移
    size: section 的大小
    offset: section 在当前架构中的偏移
    align: section的字节对齐大小 n
    reloff: 重定位入口的文件偏移
    nreloc: 重定位入口的个数
    flags: section的类型与属性:
    reserved: 保留位
    

    相关文章

      网友评论

          本文标题:初识Mach-O文件

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