Mach-O --- 基础

Mach-O为Mach Object文件格式的缩写,它是一种用于可执行文件,目标代码,动态库,内核转储的文件格式。作为a.out格式的替代,Mach-O提供了更强的扩展性,并提升了符号表中信息的访问速度。

Mach-O 文件结构如下图:


Mach-O.png

另外可以下载MachOView工具查看Mach—O 文件结构。下面是UIKit 的截图

Screen Shot 2017-04-16 at 2.51.56 PM.png

下面主要从以下角度学习Mach-O

  • 文件头 mach64 Header
  • 加载命令 Load Commands
  • Sections

Mach Header

/*
 * The 32-bit mach header appears at the very beginning of the object file for
 * 32-bit architectures.
 */
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 */
};

/* Constant for the magic field of the mach_header (32-bit architectures) */
#define MH_MAGIC    0xfeedface  /* the mach magic number */
#define MH_CIGAM    0xcefaedfe  /* NXSwapInt(MH_MAGIC) */

/*
 * The 64-bit mach header appears at the very beginning of object files for
 * 64-bit architectures.
 */
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 */
};

/* Constant for the magic field of the mach_header_64 (64-bit architectures) */
#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */
#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */
字段
magic 魔数,系统加载器通过改字段快速,判断该文件是用于32位or64位。32位-0xfeedface 64位-0xfeedfacf
cputype CPU类型以及子类型字段,该字段确保系统可以将适合的二进制文件在当前架构下运行
cpusubtype CPU指定子类型,对于inter,arm,powerpc等CPU架构,其都有各个阶段和等级的CPU芯片,该字段就是详细描述其支持CPU子类型
filetype 说明该mach-o文件类型(可执行文件,库文件,核心转储文件,内核扩展,DYSM文件,动态库)
ncmds 说明加载命令条数
sizeofcmds 表示加载命令大小
flags 标志位,该字段用位表示二进制文件支持的功能,主要是和系统加载,链接相关
reserved 保留字段

Load Commands

Mach-O文件包含非常详细的加载指令,这些指令非常清晰地指示加载器如何设置并且加载二进制数据。Load Commands紧紧跟着二进制文件头。

Segment name
LC_SEGMENT_64 将文件中(32位或64位)的段映射到进程地址空间中
LC_DYLD_INFO_ONLY 动态库信息以及地址重定向重要的信息
LC_SYMTAB 符号表地址
LC_DYSYMTAB 动态符号表地址
LC_LOAD_DYLINKER 使用何种动态加载库
LC_UUID 文件的唯一标识
LC_VERSION_MIN_MACOSX 二进制文件要求的最低操作系统版本
LC_SOURCE_VERSION 构建该二进制文件使用的源代码版本
LC_MAIN 设置程序主线程的入口地址和栈大小
LC_LOAD_DYLIB 加载额外的动态库,仔细看这个命令格式,动态库地址和名,当前版本号,兼容版本号,该设计比较合理,如果对于动态库有版本管理能力
LC_FUNCTION_STARTS 函数起始地址表

Section

Section name
__text 主程序代码
__stubs 用于动态库链接的桩
__stub_helper 用于动态库链接的桩
__cstring 常亮字符串符号表描述信息,通过该区信息,可以获得常亮字符串符号表地址
__unwind_info
__objc_methname 保存着Objc 里面selector 的名字
__objc_classname 保存Objc类的名字
__objc_methtype 保存Objc类的一些信息(函数签名)
__objc_classlist Objective-C 的类列表
__objc_nlclslist Objective-C 的 +load 函数列表,比 __mod_init_func 更早执行
__objc_catlist categories
__objc_protolist protocol
__objc_imageinfo 保存文件中objc 执行代码的一些信息
__objc_selrefs 指向selectors 的引用
__objc_protorefs 指向protocol 的引用
__objc_classrefs 指向classes 的引用
__objc_superrefs 指向super classes 的引用
__mod_init_func 初始化的全局函数地址,在 main 之前被调用
__bss 未初始化的静态变量
_got 存储引用符号的实际地址,类似于动态符号表

以上仅个人学习记录,有错请指教。🙏

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Mach-O 概述 和 部分命令介绍 我们知道Windows下的文件都是PE文件,同样在OS X和iOS中可执行文...
    青花瓷的平方阅读 15,216评论 2 52
  • 前言 2000年,伊利诺伊大学厄巴纳-香槟分校(University of Illinois at Urbana-...
    星光社的戴铭阅读 16,171评论 8 180
  • 熟悉Linux和windows开发的同学都知道,ELF是Linux下可执行文件的格式,PE32/PE32+是win...
    Klaus_J阅读 9,461评论 1 10
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,833评论 19 139
  • 原文地址 写在之前 之前工作中对Mach-O文件有一定的接触, 原本早就想写一篇文章分享一下,但是奈何只是不够深入...
    南栀倾寒阅读 10,300评论 3 22

友情链接更多精彩内容