1. Mach-O

Mach-O(Mach Object)是macOS、iOS、iPadOS 存储程序(可执行文件)、库(动态库和静态库)或者目标文件(.o)的文件格式,是一个可读可写的二进制文件。对应系统通过应用二进制接口(application binary interface,缩写为ABI)来运行该格式的文件。
Mach-O格式用来替代BSD系统的a.out格式。Mach-O文件格式保存了在 编译过程和链接过程中产生的机器代码和数据,从而为静态链接和动态链接的代码提供了单一文件格式。

2. 可执行文件的调用过程:

  1. 调用fork函数,创建一个process
    2. 调用execve或其衍生函数,在该进程上加载Mach-O文件到虚拟内存中
    3. 开始分析Mach-O中的Mach Header,以确认它是有效可执行的Mach-O文件,即文件类型为EXCUTE的。

    3. mach-o内部的格式

    Mach-O = Mach Header + 二进制代码. 如下图所示:
    image.png
    header 中存放的是Mach-O的配置信息,包含Mach-O文件的类型,动态库信息,静态库信息,代码段的大小及偏移,main函数的位置,链接器等信息。

    3.1 Mach-O 可读

    3.1.1 读取 Mach Header

    objdumpotool 命令,均可读取 Mach-O 内部数据。

    1. 读取 Mach Header 总览信息

    获取 Mach-O 的一些基础信息,如支持的CPU架构、文件的类型、Load Commond数量及大小等。 ``` // 读取 Mach Header(可读性比较好) // —macho 可缩写为 -m objdump —macho -private-header ${MACH-PATH}

// 显示整个文件头的内容, 缩写为 -f —file-headers - Display the contents of the overall file header

  1. 随便找一个 Mach-O 文件,执行一下:<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/94660/1616468829771-c5cbc377-983c-4c13-ab55-9bc6884a5e63.png#align=left&display=inline&height=114&margin=%5Bobject%20Object%5D&name=image.png&originHeight=228&originWidth=1586&size=101840&status=done&style=none&width=793)<br />**与目标文件的格式一样,动态库与静态库的类型为OBJECT ,只能被链接,不能被执行。**
  2. <a name="Rzsdy"></a>
  3. #### 2.读取 Mach Header 的所有信息

// —all-headers 可缩写为-x objdump -macho —all-headers test

![image.png](https://cdn.nlark.com/yuque/0/2021/png/94660/1616481570172-5aed5264-0552-450a-aae8-b411c124e2a1.png#align=left&display=inline&height=632&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1264&originWidth=1436&size=340140&status=done&style=none&width=718)
<a name="NGTu7"></a>
### 3.1.2 读取Mach-O绑定信息

—bind - Display mach-o binding inf —lazy-bind - Display mach-o lazy binding info —weak-bind - Display mach-o weak binding info

![image.png](https://cdn.nlark.com/yuque/0/2021/png/94660/1616485934212-e7275791-c6d0-4a24-8af4-12e3b62fcfac.png#align=left&display=inline&height=238&margin=%5Bobject%20Object%5D&name=image.png&originHeight=476&originWidth=1630&size=151661&status=done&style=none&width=815)
<a name="Aitlp"></a>
### 
<a name="nTZaE"></a>
### 3.1.4 显示机器指令的汇编助记符

// -d - Alias for —disassemble —disassemble - Display assembler mnemonics for the machine instructions // -D - Alias for —disassemble-all —disassemble-all - Display assembler mnemonics for the machine instructions —disassemble-functions= - List of functions to disassemble. Accept demangled names when —demangle is specified, otherwise accept mangled names // -z - Alias for —disassemble-zeroes —disassemble-zeroes - Do not skip blocks of zeroes when disassembling // -M - Alias for —disassembler-options —disassembler-options= - Pass target specific disassembler options

```
// 读取__TEXT段机器指令的汇编助记符
objdump --macho -d ${MACH-PATH}

源码:image.png__text 中存储的代码:image.png

3.1.5 读取 section 信息

1.读取 section header 的信息

// --section-headers可缩写为 --headers 或者 -h
objdump -m --section-headers test

image.png

2. 读取section 全部信息

// 缩写为-s
objdump -m --full-contents  test.o

image.png

3.1.6 objdump所有参数

objdump --help查看帮助文档,或者man objdump


USAGE: objdump [options] <input object files>

OPTIONS:

Generic Options:

  --help                           - Display available options (--help-hidden for more)
  --help-list                      - Display list of available options (--help-list-hidden for more)
  --version                        - Display the version of this program

llvm-objdump MachO Specific Options:

  --arch=<string>                  - architecture(s) from a Mach-O file to dump
  --archive-member-offsets         - Print the offset to each archive member for Mach-O archives (requires -macho and -archive-headers)
  --bind                           - Display mach-o binding info
  --data-in-code                   - Print the data in code table for Mach-O objects (requires -macho)
  --dis-symname=<string>           - disassemble just this symbol's instructions (requires -macho)
  --dsym=<string>                  - Use .dSYM file for debug info
  --dylib-id                       - Print the shared library's id for the dylib Mach-O file (requires -macho)
  --dylibs-used                    - Print the shared libraries used for linked Mach-O files (requires -macho)
  --exports-trie                   - Display mach-o exported symbols
  --full-leading-addr              - Print full leading address
  -g                               - Print line information from debug info if available
  --indirect-symbols               - Print indirect symbol table for Mach-O objects (requires -macho)
  --info-plist                     - Print the info plist section as strings for Mach-O objects (requires -macho)
  --lazy-bind                      - Display mach-o lazy binding info
  --link-opt-hints                 - Print the linker optimization hints for Mach-O objects (requires -macho)
  --no-leading-headers             - Print no leading headers
  --no-symbolic-operands           - do not symbolic operands when disassembling (requires -macho)
  --non-verbose                    - Print the info for Mach-O objects in non-verbose or numeric form (requires -macho)
  --objc-meta-data                 - Print the Objective-C runtime meta data for Mach-O files (requires -macho)
  --private-header                 - Display only the first format specific file header
  --rebase                         - Display mach-o rebasing info
  --universal-headers              - Print Mach-O universal headers (requires -macho)
  --weak-bind                      - Display mach-o weak binding info

llvm-objdump Options:

  -C                               - Alias for --demangle
  -D                               - Alias for --disassemble-all
  -M                               - Alias for --disassembler-options
  -R                               - Alias for --dynamic-reloc
  -S                               - Alias for -source
  -a                               - Alias for --archive-headers
  --adjust-vma=<offset>            - Increase the displayed address by the specified offset
  --all-headers                    - Display all available header information
  --arch-name=<string>             - Target arch to disassemble for, see -version for available targets
  --archive-headers                - Display archive header information
  -d                               - Alias for --disassemble
  --demangle                       - Demangle symbols names
  --disassemble                    - Display assembler mnemonics for the machine instructions
  --disassemble-all                - Display assembler mnemonics for the machine instructions
  --disassemble-functions=<string> - List of functions to disassemble. Accept demangled names when --demangle is specified, otherwise accept mangled names
  --disassemble-zeroes             - Do not skip blocks of zeroes when disassembling
  --disassembler-options=<options> - Pass target specific disassembler options
  --dwarf=<value>                  - Dump of dwarf debug sections:
    =frames                        -   .debug_frame
  --dynamic-reloc                  - Display the dynamic relocation entries in the file
  -f                               - Alias for --file-headers
  --fault-map-section              - Display contents of faultmap section
  --file-headers                   - Display the contents of the overall file header
  --full-contents                  - Display the content of each section
  -h                               - Alias for --section-headers
  --headers                        - Alias for --section-headers
  -j                               - Alias for --section
  -l                               - Alias for --line-numbers
  --line-numbers                   - Display source line numbers with disassembly. Implies disassemble object
  -m                               - Alias for --macho
  --macho                          - Use MachO specific object file parser
  --mattr=<a1,+a2,-a3,...>         - Target specific attributes
  --mcpu=<cpu-name>                - Target a specific cpu type (-mcpu=help for details)
  --no-leading-addr                - Print no leading address
  --no-show-raw-insn               - When disassembling instructions, do not print the instruction bytes.
  -p                               - Alias for --private-headers
  --print-imm-hex                  - Use hex format for immediate values
  --private-headers                - Display format specific file headers
  -r                               - Alias for --reloc
  --raw-clang-ast                  - Dump the raw binary contents of the clang AST section
  --reloc                          - Display the relocation entries in the file
  -s                               - Alias for --full-contents
  --section=<string>               - Operate on the specified sections only. With -macho dump segment,section
  --section-headers                - Display summaries of the headers for each section.
  --show-lma                       - Display LMA column when dumping ELF section headers
  --source                         - Display source inlined with disassembly. Implies disassemble object
  --start-address=<address>        - Disassemble beginning at address
  --stop-address=<address>         - Stop disassembly at address
  --syms                           - Display the symbol table
  -t                               - Alias for --syms
  --triple=<string>                - Target triple to disassemble for, see -version for available targets
  -u                               - Alias for --unwind-info
  --unwind-info                    - Display unwind information
  --wide                           - Ignored for compatibility with GNU objdump
  -x                               - Alias for --all-headers
  -z                               - Alias for --disassemble-zeroes

3.1.7 otool

// 读取 Mach Header 所有原始信息(可读性比较差)
otool -h ${MACH-PATH}

image.png

// 读取 Mach-O load commad 信息
otool -l  ${MACH-PATH}

image.png
otool 所有命令:man otool

otool [-arch arch_type] [-fahlLDtdorSTMRIHGvVcXmqQjCP] [-mcpu=arg] [--version] <object file> ...
    -f print the fat headers
    -a print the archive header
    -h print the mach header
    -l print the load commands
    -L print shared libraries used
    -D print shared library id name
    -t print the text section (disassemble with -v)
    -x print all text sections (disassemble with -v)
    -p <routine name>  start dissassemble from routine name
    -s <segname> <sectname> print contents of section
    -d print the data section
    -o print the Objective-C segment
    -r print the relocation entries
    -S print the table of contents of a library (obsolete)
    -T print the table of contents of a dynamic shared library (obsolete)
    -M print the module table of a dynamic shared library (obsolete)
    -R print the reference table of a dynamic shared library (obsolete)
    -I print the indirect symbol table
    -H print the two-level hints table (obsolete)
    -G print the data in code table
    -v print verbosely (symbolically) when possible
    -V print disassembled operands symbolically
    -c print argument strings of a core file
    -X print no leading addresses or headers
    -m don't use archive(member) syntax
    -B force Thumb disassembly (ARM objects only)
    -q use llvm's disassembler (the default)
    -Q use otool(1)'s disassembler
    -mcpu=arg use `arg' as the cpu for disassembly
    -j print opcode bytes
    -P print the info plist section as strings
    -C print linker optimization hints
    --version print the version of /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool

2. Mach-O 可写

macho可修改,修改后需要重新签名。 2016年,iphone7,8的时候,限制TEXT.text 段最大60M,现在改成500M了,有项目比较大的人,为了符合苹果规定,将text 移到别的段,同时对应修改了 Mach Header 中指向text 的 LOAD Commad __TEXT ,然后重新签名上架。