相识Mach-O文件

源代码 2024-9-15 23:23:58 98 0 来自 中国
Mach-O文件

想要一个应用步伐运行起来,那么它的可实行文件格式肯定要被利用体系所理解。在Windows体系的可实行文件是PE,而在OS X和iOS 中的可实行文件是Mach-O。
那么Mach-O是怎么天生的呢?苹果公司如今利用的编译器是LLVM,在步伐编译时,编译器会对每个文件举行编译,然后天生Mach-O文件,而后链接器会将项目中的多个 Mach-O 文件归并成一个,终极的这个就是我们的可实行Mach-O文件.
那么Mach-O 文件内里有哪些内容呢?着实紧张还是数据和代码,此中数据是一些初始值的界说,代码就是一些是函数的界说。下面我们一起相识下Mach-O文件。
Mach-O文件简介

Mach-O 是Mach Object文件格式的缩写,是运用于mac以及iOS上;它是一种用于可实行文件、目的代码、动态库的文件格式;
Mach-O文件范例


  • Executable:应用可实行的二进制文件
  • Dylib Library:动态链接库
  • Static Library:静态链接库
  • Bundle:不能被链接 Dylib,只能在运利用用dlopen()加载
  • Relocatable Object File:可重定向文件
Mach-O文件结构

Mach-O文件紧张由三部门构成:Header、Load commands、Data
Header部门描述当前Mach-O文件的根本信息 (架构,是否Fat二进制文件,CUP范例等等);
Load commands部门紧张描述:1.Mach-O文件中在虚拟内存中空间是怎样分配,从哪个内存地点开始到哪个内存地点竣事。 2.不同段在Mach-O文件中的位置,巨细分布。
Data部门是描述内存怎样被分配的内容。包罗__TEXT, __DATA等
Header

范例:区分32位、64位
结构
// 32位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 */};// 64位 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 */};解释
magic:确定Mach-O文件运行框架,如64位/32位
cputype:CPU范例,如arm
cpusubtype:对应CPU范例的具体型号
filetype:文件范例
ncmds:加载下令条数
sizeofcmds:全部加载下令的巨细
flags:保存字段
reserved:标志位
LoadCommand


  • cmd:指令范例
  • cmdsize: 指令长度
以下是load_command的结构:
struct load_command {    uint32_t cmd;       /* type of load command */    uint32_t cmdsize;   /* total size of command in bytes */};command 指令范例阐明


  • LC_SEGMENT/LC_SEGMENNT_64  :将对应段中的数据加载并映射到历程的内存空间
  • LC_SEGMENT_TEXT   :代码段,此中_stub_helper用于关联函数bind/rebind
  • LC_SEGMENT_DATA  :可读/可写的数据段,函数指针,此中_la_symbol_ptr动态函数个数,及相对动态符号表的偏移量
  • LC_SEGMENT_LINKEDIT  : :动态链接加载指令,支持动态链接dyld,该段长度覆盖符号表等数据(盘算链接时步伐的基址),符号表,动态符号表,字符串表段中界说的offset偏移量都是基于_LINKEDIT的vm_add
  • LC_SYMTAB :符号表信息,分析函数名
  • LC_DYSYMTAB :动态符号表信息,地点值为动态函数相对符号表的索引,_la_symbol_ptr对应的cmd可以换算出第一个动态函数对应动态符号表的初始地点,其次存储是连续,结构长度固定的,可以通过遍历获取全部动态函数的对应的符号表索引
2.png Data

Data中就是由Segment构成的,每一个Segment界说了一些Mach-O文件的数据、地点和内存掩护属性,这些数据在动态链接器加载步伐时被映射到了虚拟内存中。每个段都有不同的功能。
Segment一般包罗下列功能:

  • __PAGEZERO: 空指针陷阱段,映射到虚拟内存空间的第一页,用于捕捉对NULL指针的引用;
  • __TEXT: 包罗了实行代码以及其他只读数据。 为了让内核将它 直接从可实行文件映射到共享内存, 静态毗连器设置该段的虚拟内存权限为不允许写。当这个段被映射到内存后,可以被全部历程共享。(这紧张用在frameworks, bundles和共享库等步伐中,也可以为同一个可实行文件的多个历程拷贝利用)
  • __DATA: 包罗了步伐数据,该段可写;
  • __LINKEDIT: 含有为动态链接库利用的原始数据,比如符号,字符串,重定位表条目等等。
一般Segment又会按不同的功能分别为几个区(Section),即段全部字母巨细,加两个下横线作为前缀,而区则为小写,同样加两个下横线作为前缀,
Segment结构体:
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 */};Section结构体:
struct section { /* for 32-bit architectures */    char        sectname[16];   /* name of this section */    char        segname[16];    /* segment this section goes in */    uint32_t    addr;       /* memory address of this section */    uint32_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) */};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 */};
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-22 00:36, Processed in 0.128114 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表