12-MachO文件

前言

本篇文章主要分析MachO文件(也稱作二進(jìn)制可執(zhí)行文件),相信大家在平時(shí)開發(fā)中都會(huì)碰到MachO文件這個(gè)概念师崎,但是大部分人不清楚是個(gè)什么東西工扎,本篇文章就和大家一起來具體分析它的由來以及它的內(nèi)部結(jié)構(gòu)捉兴。

一、Mach-O

首先大家看看上面這張圖护昧,從左到右可以看出??
1.不論是哪種高級(jí)語言(C OC Swift等),第一步都會(huì)生成AST語法樹溜畅,只是編譯器前端不同而已(有Clang捏卓、Swift或Rust

  1. 接著通過CIL MIR 或SIL生成器生成IR中間代碼,這個(gè)中間代碼都屬于LLVM IR
  2. 最后交給MIR生成機(jī)器代碼慈格,這個(gè)機(jī)器代碼就是MachO文件

整個(gè)過程其實(shí)都是LLVM幫我們完成的怠晴,至于LLVM是什么,大家可以參考我之前的文章 ?? LLVM編譯流程浴捆。

常見的Mach-O文件格式

  • 目標(biāo)文件.o
  • 庫文件
    • .a
    • .dylib
    • .framework
  • 可執(zhí)行文件
  • dyld
  • .dsym

驗(yàn)證

.o蒜田、.out、可執(zhí)行文件

案例一
新建test.c文件选泻,內(nèi)容如下??

#include <stdio.h>

int main() {
    printf("test\n");
    return 0;
}

驗(yàn)證.o文件??

??注意:不指定-c默認(rèn)生成.out格式冲粤,如果報(bào)找不到'stdio.h' file not found美莫,則可以指定-isysroot仪缸。

驗(yàn)證.out可執(zhí)行文件??

驗(yàn)證可執(zhí)行文件??

再直接生成一個(gè)test3可執(zhí)行文件??

那么問題來了 ?? 生成的a.out而克、test2、test3是一樣的么蝶缀???

可以看到生成的可執(zhí)行文件md5相同傀顾。

??注意:原則上test3的md5應(yīng)該和test2和a.out相同襟铭。源碼沒有變化,所以應(yīng)該相同的短曾。在指定-isysroot后生成的可能不同寒砖,推測和CommandLineTools有關(guān)(系統(tǒng)中有一個(gè),Xcode中也有一個(gè))嫉拐。

案例二
再創(chuàng)建一個(gè)test1.c文件哩都,內(nèi)容如下??

#include <stdio.h>

void test1Func() {
    printf("test1 func \n");
}

修改test.c??

#include <stdio.h>

void test1Func();

int main() {
    test1Func();
    printf("test\n");
    return 0;
}

這個(gè)時(shí)候相當(dāng)于多了個(gè)test1.c文件了,編譯生成可執(zhí)行文件demo婉徘、demo1漠嵌、demo2??

clang -o demo  test1.c test.c 
clang -c test1.c test.c 
clang -o demo1 test.o test1.o
clang -o demo2 test1.o test.o

查看他們的MD5??

這里demo1和demo2的md5不同,是因?yàn)閠est.o和test1.o順序不同判哥。

objdump命令查看Mach-O

objdump --macho -d demo

上圖明顯可見方法調(diào)用的順序不同献雅,這也就解釋了md5不同的原因。這里很像Xcode中Build Phases -> Compile Sources源文件的順序塌计。

??注意:源文件順序不同挺身,編譯出來的二進(jìn)制文件不同( 大小相同),二進(jìn)制排列順序不同锌仅。

.a文件章钾、

直接創(chuàng)建一個(gè)library庫查看??

//find /usr -name "*.a"
file libTestLibrary.a
libTestLibrary.a: current ar archive random library
.dylib文件
 file /usr/lib/libprequelite.dylib
/usr/lib/libprequelite.dylib: Mach-O 64-bit dynamically linked shared library x86_64

??注意:dyld不是可執(zhí)行文件,它是一個(gè)dynamic linker热芹,由系統(tǒng)內(nèi)核觸發(fā)贱傀。

dyld文件
cd /usr/lib
file dyld
dyld: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit dynamic linker x86_64] [i386:Mach-O dynamic linker i386]
dyld (for architecture x86_64): Mach-O 64-bit dynamic linker x86_64
dyld (for architecture i386):   Mach-O dynamic linker i386
.dsym文件
file TestDsym.app.dSYM
TestDsym.app.dSYM: directory

cd TestDsym.app.dSYM/Contents/Resources/DWARF

file TestDsym
TestDsym: Mach-O 64-bit dSYM companion file arm64

二、工程配置

2.1 查看Mach-O文件的類型

我們可以在工程配置中查看Mach-O文件的類型伊脓,如下圖??

也可以使用命令行查看??

file your Mach-O文件路徑

可以看到是支持2個(gè)架構(gòu)的:arm64armv7府寒。當(dāng)然也可以在Xcode中直觀的看到支持的架構(gòu)??

同時(shí)Xcode中架構(gòu)設(shè)置在Build Settings -> Architectures中??

主要有以下配置選項(xiàng)??

  • Architectures ?? 支持的架構(gòu)。
  • Build Active Architecture Only ?? 默認(rèn)情況下debug模式下只編譯當(dāng)前設(shè)備架構(gòu)报腔,release模式下需要根據(jù)支持的設(shè)備株搔。
  • $(ARCHS_STANDARD) ?? 環(huán)境變量,代表當(dāng)前支持的架構(gòu)纯蛾。

如果我們要修改架構(gòu)直接在Architectures中配置(增加armv7s)??

2.2 通用二進(jìn)制文件(Universal binary)

  • 蘋果公司提出的一種程序代碼纤房,能同時(shí)適用多種架構(gòu)的二進(jìn)制文件。
  • 同一個(gè)程序包中同時(shí)為多種架構(gòu)提供最理想的性能翻诉。
  • 因?yàn)樾枰獌?chǔ)存多種代碼炮姨,通用二進(jìn)制應(yīng)用程序通常比單一平臺(tái)二進(jìn)制的程序要大捌刮。
  • 由于多種架構(gòu)有共同的非執(zhí)行資源(代碼以外的),所以并不會(huì)達(dá)到單一版本的多倍之多(特殊情況下舒岸,只有少量代碼文件的情況下有可能會(huì)大于多倍)绅作。
  • 由于執(zhí)行中只調(diào)用一部分代碼,運(yùn)行起來不需要額外的內(nèi)存蛾派。

當(dāng)我們將通用二進(jìn)制文件拖入Hopper時(shí)棚蓄,能夠看到讓我們選擇對應(yīng)的架構(gòu)??

2.3 lipo命令

lipo是管理Fat File的工具,可以查看cpu架構(gòu)碍脏,提取特定架構(gòu),整合和拆分庫文件稍算。

1. 查看MachO文件支持的架構(gòu)

lipo -info MachO文件

lipo -info EvergrandeCustomerApp_Example
Architectures in the fat file: EvergrandeCustomerApp_Example are: armv7 arm64
2. lifo –thin 拆分某種架構(gòu)

lipo MachO文件 –thin 架構(gòu) –output 輸出文件路徑

3. 使用lipo -create合并多種架構(gòu)

lipo -create MachO1 MachO2 -output 輸出文件路徑

三典尾、MachO文件結(jié)構(gòu)

macho文件是mac osios系統(tǒng)可執(zhí)行文件的格式,系統(tǒng)通過加載這個(gè)格式來執(zhí)行代碼糊探。相關(guān)結(jié)構(gòu)如下圖??

上圖中Mach-O的組成結(jié)構(gòu)如圖所示包括??

  • Header 包含該二進(jìn)制文件的一般信息
    • 字節(jié)順序钾埂、架構(gòu)類型、加載指令的數(shù)量等
    • 使得可以快速確認(rèn)一些信息科平,比如當(dāng)前文件用于32位還是64位褥紫,對應(yīng)的處理器是什么、文件類型是什么
  • Load commands 一張包含很多內(nèi)容的表
    • 內(nèi)容包括區(qū)域的位置瞪慧、符號(hào)表髓考、動(dòng)態(tài)符號(hào)表等
  • Data 通常是對象文件中最大的部分
    • 包含Segement的具體數(shù)據(jù)

3.1 查看MachO文件的方式

有2種方式可查看MachO文件的結(jié)構(gòu)??

  1. 命令行 otool -f MachO文件
$ otool -f xxx.app/xxx
Fat headers
fat_magic 0xcafebabe
nfat_arch 2
architecture 0
    cputype 12
    cpusubtype 9
    capabilities 0x0
    offset 16384
    size 69642576
    align 2^14 (16384)
architecture 1
    cputype 16777228
    cpusubtype 0
    capabilities 0x0
    offset 69664768
    size 80306624
    align 2^14 (16384)
  1. MachO View可視化工具

3.2 MachO Header的結(jié)構(gòu)

Fat Header

首先我們來看看Fat Header,什么是Fat Header??

對于多架構(gòu)MachO會(huì)有一個(gè)Fat Header弃酌,其中包含了CPU類型和架構(gòu)氨菇。OffsetSize代表了每一個(gè)架構(gòu)二進(jìn)制文件中的偏移大小

上圖中妓湘,armv7偏移量大小分別是1638479315040查蓉,再看arm64的偏移量79347712,可以發(fā)現(xiàn)16384 + 79315040 = 79331424 < 79347712榜贴,但是79347712 - 16384 = 79331328豌研,79331328/(1024 * 16) = 4842,其中(1024 * 16)代表16k字節(jié)大小唬党,因?yàn)??

iOS中一頁16K鹃共,MachO中都是以為單位對齊的。

這也驗(yàn)證了以頁對齊初嘹,并且這也是Load Commands中可以插入LC_LOAD_DYLIB的原因及汉。

Header的數(shù)據(jù)

上圖是arm64架構(gòu)下的Header,對應(yīng)dyld的定義代碼結(jié)構(gòu)如下(loader.h)??

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 */
};
參數(shù) 釋義
magic 魔數(shù)屯烦,快速定位屬于64位還是32位
cputype CPU類型坷随,比如ARM
cpusubtype CPU具體類型房铭,arm64,armv7
filetype 文件類型温眉,比如可執(zhí)行文件
ncmds Number of Load Commands缸匪,即Load Commands總的條數(shù)
sizeofcmds Size of Load Commands,即Load Commands總的大小
flags 標(biāo)識(shí)二進(jìn)制文件支持的功能类溢,主要是和系統(tǒng)加載凌蔬、鏈接有關(guān)
reserved arm64特有,保留字段

其中闯冷,filetype的類型有??

#define MH_OBJECT   0x1     /* relocatable object file */
#define MH_EXECUTE  0x2     /* demand paged executable file */
#define MH_FVMLIB   0x3     /* fixed VM shared library file */
#define MH_CORE     0x4     /* core file */
#define MH_PRELOAD  0x5     /* preloaded executable file */
#define MH_DYLIB    0x6     /* dynamically bound shared library */
#define MH_DYLINKER 0x7     /* dynamic link editor */
#define MH_BUNDLE   0x8     /* dynamically bound bundle file */
#define MH_DYLIB_STUB   0x9     /* shared library stub for static
                       linking only, no section contents */
#define MH_DSYM     0xa     /* companion file with only debug
                       sections */
#define MH_KEXT_BUNDLE  0xb     /* x86_64 kexts */
#define MH_FILESET  0xc     /* a file composed of other Mach-Os to
                       be run in the same userspace sharing
                       a single linkedit. */

3.3 Load Commands

dyld檢索完Header之后就開始加載和解析Load Commands了砂心,Load Comands的大致結(jié)構(gòu)如下??


2.3.1 load_command結(jié)構(gòu)體

對應(yīng)的代碼??

/*
 * The load commands directly follow the mach_header.  The total size of all
 * of the commands is given by the sizeofcmds field in the mach_header.  All
 * load commands must have as their first two fields cmd and cmdsize.  The cmd
 * field is filled in with a constant for that command type.  Each command type
 * has a structure specifically for it.  The cmdsize field is the size in bytes
 * of the particular load command structure plus anything that follows it that
 * is a part of the load command (i.e. section structures, strings, etc.).  To
 * advance to the next load command the cmdsize can be added to the offset or
 * pointer of the current load command.  The cmdsize for 32-bit architectures
 * MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple
 * of 8 bytes (these are forever the maximum alignment of any load commands).
 * The padded bytes must be zero.  All tables in the object file must also
 * follow these rules so the file can be memory mapped.  Otherwise the pointers
 * to these tables will not work well or at all on some machines.  With all
 * padding zeroed like objects will compare byte for byte.
 */
struct load_command {
    uint32_t cmd;       /* type of load command */
    uint32_t cmdsize;   /* total size of command in bytes */
};

每一個(gè)load_command都需要包含??

  1. cmd ?? 加載類型
  2. cmdsize ?? 加載的大小

2.3.2 所有load_command的具體信息

接下來我們仔細(xì)看看每個(gè)load_command具體包含哪些信息??

__PAGEZERO

空指針陷阱,目的是為了和32位指令完全分開蛇耀。(32位地址在4G以下辩诞,64位地址大于4G,其中0xffffffff = 4G)纺涤。有以下幾個(gè)重要的描述??

  • Segment Name ?? __PAGEZERO不占用數(shù)據(jù)(file size為0)译暂,唯一有的是VM Size(arm64 4G,armv7比較辛么丁)外永。
  • VM Addr ?? 虛擬內(nèi)存地址
  • VM Size ?? 虛擬內(nèi)存大小。運(yùn)行時(shí)刻在內(nèi)存中的大小拧咳,一般情況下和File size相同伯顶,__PAGEZERO例外。
  • File offset ?? 數(shù)據(jù)在文件中偏移量呛踊。
  • File size ?? 數(shù)據(jù)在文件中的大小砾淌。

一般我們定位地址是通過VM Addr + ASLR

__TEXT谭网、__DATA汪厨、__LINKEDIT

他們的結(jié)構(gòu)和__PAGEZERO大致差不多,用途是將文件中(32位/64位)的段映射到進(jìn)程地址空間中愉择。分為三大塊 ?? 分別對應(yīng)DATA中的Section(__TEXT + __DATA)劫乱、__LINKEDIT,告訴dyld占用多大空間锥涕。

LC_DYLD_INFO_ONLY

動(dòng)態(tài)鏈接相關(guān)信息衷戈。

  • Rebase ?? 重定向(ASLR)偏移地址大小。從Rebase Info Offset + ASLR開始加載336個(gè)字節(jié)數(shù)據(jù)层坠。
  • Binding ?? 綁定外部符號(hào)殖妇。
  • Weak Binding ?? 弱綁定。
  • Lazy Binding ?? 懶綁定破花,用到的時(shí)候再綁定谦趣。
  • Export info ?? 對外開放的函數(shù)疲吸。
LC_SYMTAB

符號(hào)表地址。

  • Symbol Table Offset ?? 符號(hào)表地址偏移量
  • Number of Symbol ?? 符號(hào)總數(shù)量
  • String Table Offset ?? 字符串表地址偏移量
  • Symbol Table Size ?? 字符串表大小
LC_DSYMTAB

動(dòng)態(tài)符號(hào)表地址前鹅。

也是包含一些索引摘悴、數(shù)量、地址偏移量等信息舰绘。

LC_LOAD_DYLINKER

使用誰加載蹂喻,iOS系統(tǒng)是使用dyld加載,如下圖??

LC_UUID

文件的UUID捂寿,即MachO文件的唯一識(shí)別標(biāo)識(shí)口四。

LC_VERSION_MIN_IPHONES

支持最低的操作系統(tǒng)版本。

LC_SOURCE_VERSION

源代碼的版本號(hào)秦陋。

LC_MAIN

程序主程序的入口地址和棧大小窃祝。

LC_ENCRYPTION_INFO_64

加密的信息。

LC_LOAD_DYLIB

依賴的庫的路徑踱侣,包含第三方的庫。

系統(tǒng)的庫??

第三方庫??

LC_RPATH

Frameworks庫的路徑大磺。

  • @executable_path ??
  • @loader_path??
LC_FUNCTION_STARTS

函數(shù)起始地址表抡句。

LC_DATA_IN_CODE

定義在代碼段內(nèi)的非指令的表。

LC_DATA_SIGNATURE

代碼簽名杠愧。

3.4 Data

Data包含Section(__TEXT + __DATA)待榔、__LINKEDIT

3.4.1 __TEXT

__TEXT即代碼段流济,就是我們寫的代碼锐锣。主要的幾個(gè)子段有??

1. __text: 代碼節(jié),存放機(jī)器編譯后的代碼
2. __stubs: 用于輔助做動(dòng)態(tài)鏈接代碼(dyld).
3. __stub_helper:用于輔助做動(dòng)態(tài)鏈接(dyld).
4. __objc_methname:objc的方法名稱
5. __cstring:代碼運(yùn)行中包含的字符串常量,比如代碼中定義`#define kGeTuiPushAESKey        @"DWE2#@e2!"`,那DWE2#@e2!會(huì)存在這個(gè)區(qū)里绳瘟。
6. __objc_classname:objc類名
7. __objc_methtype:objc方法類型
8. __ustring:
9. __gcc_except_tab:
10. __const:存儲(chǔ)const修飾的常量
11. __dof_RACSignal:
12. __dof_RACCompou:
13. __unwind_info:

3.4.2 __DATA

__DATA數(shù)據(jù)段雕憔。主要的幾個(gè)子段有??

1. __got:存儲(chǔ)引用符號(hào)的實(shí)際地址,類似于動(dòng)態(tài)符號(hào)表糖声,存儲(chǔ)了`__nl_symbol_ptr`相關(guān)函數(shù)指針斤彼。
2. __la_symbol_ptr:lazy symbol pointers。懶加載的函數(shù)指針地址(C代碼實(shí)現(xiàn)的函數(shù)對應(yīng)實(shí)現(xiàn)的地址)蘸泻。和__stubs和stub_helper配合使用琉苇。具體原理暫留。
3. __mod_init_func:模塊初始化的方法悦施。
4. __const:存儲(chǔ)constant常量的數(shù)據(jù)并扇。比如使用extern導(dǎo)出的const修飾的常量。
5. __cfstring:使用Core Foundation字符串
6. __objc_classlist:objc類列表,保存類信息抡诞,映射了__objc_data的地址
7. __objc_nlclslist:Objective-C 的 +load 函數(shù)列表穷蛹,比 __mod_init_func 更早執(zhí)行土陪。
8. __objc_catlist: categories
9. __objc_nlcatlist:Objective-C 的categories的 +load函數(shù)列表。
10. __objc_protolist:objc協(xié)議列表
11. __objc_imageinfo:objc鏡像信息
12. __objc_const:objc常量俩莽。保存objc_classdata結(jié)構(gòu)體數(shù)據(jù)旺坠。用于映射類相關(guān)數(shù)據(jù)的地址,比如類名扮超,方法名等取刃。
13. __objc_selrefs:引用到的objc方法
14. __objc_protorefs:引用到的objc協(xié)議
15. __objc_classrefs:引用到的objc類
16. __objc_superrefs:objc超類引用
17. __objc_ivar:objc ivar指針,存儲(chǔ)屬性。
18. __objc_data:objc的數(shù)據(jù)出刷。用于保存類需要的數(shù)據(jù)璧疗。最主要的內(nèi)容是映射__objc_const地址,用于找到類的相關(guān)數(shù)據(jù)馁龟。
19. __data:暫時(shí)沒理解崩侠,從日志看存放了協(xié)議和一些固定了地址(已經(jīng)初始化)的靜態(tài)量。
20. __bss:存儲(chǔ)未初始化的靜態(tài)量坷檩。比如:`static NSThread *_networkRequestThread = nil;`其中這里面的size表示應(yīng)用運(yùn)行占用的內(nèi)存却音,不是實(shí)際的占用空間。所以計(jì)算大小的時(shí)候應(yīng)該去掉這部分?jǐn)?shù)據(jù)矢炼。
21. __common:存儲(chǔ)導(dǎo)出的全局的數(shù)據(jù)系瓢。類似于static,但是沒有用static修飾句灌。比如KSCrash里面`NSDictionary* g_registerOrders;`, g_registerOrders就存儲(chǔ)在__common里面

3.4.3 __LINKEDIT

__LINKEDIT主要包含??

  • Dynamic Loader Info ?? 動(dòng)態(tài)加載信息

  • Function Starts ?? 入口函數(shù)

  • Symbol Table ?? 符號(hào)表

  • Dynamic Symbol Table ?? 動(dòng)態(tài)庫符號(hào)表

  • String Table ?? 字符串表

  • Code Signature ?? 代碼簽名

驗(yàn)證

我們知道夷陋,獲取類名可以用_objc_classname, 獲取方法名可以用_objc_methname,但是這兩個(gè)數(shù)據(jù)怎么串聯(lián)匹配起來的胰锌?根據(jù)查相關(guān)資料骗绕,是通過__objc_classlist來映射的。

驗(yàn)證該問題需借助2個(gè)工具 ?? MachOViewHopper资昧。

  1. MachOView中打開Mach-O文件酬土,直接看__objc_classlist??

我們選擇第一個(gè)地址,在Hopper中看看102725E28(按G搜索)??

雙擊格带,對應(yīng)到__objc_class??

__objc_class對應(yīng)的源碼??

typedef struct objc_class{
        struct __objc_class* isa;
        struct __objc_class* superclass;
        struct __objc_cache* cache;
        struct __objc_vtable* vtable;
        struct __objc_ data* data;
}objc_class;
  1. 第1個(gè)成員是isa指針诺凡,指向了MetaClass,對應(yīng)的地址是102badf90??
  1. 第2個(gè)成員是指向父類的指針践惑,對應(yīng)地址為0000000000000000
  2. 第5個(gè)成員指向__objc_ data腹泌,雙擊它,對應(yīng)的地址為102737e30??

接著我們看看__objc_data對應(yīng)的數(shù)據(jù)結(jié)構(gòu)源碼??

typedef struct objc_data{
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
    uint32_t reserved;
    void* ivarlayout;
    char* name;
    struct __objc_method_list* baseMethod;
    struct __objc_protos* baseProtocol;
    struct __objc_ivars* ivars;
    struct __objc_ivars weakIvarLayout;
    struct __objc_ivars baseProperties;
}

主要的幾個(gè)成員??

  1. 第6個(gè)成員name 保存的類名尔觉,對應(yīng)的地址是0x102445615

該地址對應(yīng)的類名稱是_AFURLSessionTaskSwizzling凉袱,至此,找到了類名稱

  1. 第7個(gè)成員baseMethod 保存了類所有方法专甩,一樣钟鸵,對應(yīng)的地址是102737de0??

接著查看__objc_method_list的源碼??

typedef struct objc_method_list{
    uint32_t flags;
    uint32_t count;
}

使用到的數(shù)據(jù)主要是count,對應(yīng)數(shù)據(jù)為3,對應(yīng)10進(jìn)制數(shù)也是3涤躲,說明有3個(gè)方法??

具體方法對應(yīng)的數(shù)據(jù)結(jié)構(gòu)為??

typedef struct objc_method{
    char* name;
    char* signature;
    void* implementation;
}

objc_method_list結(jié)構(gòu)體占用8(4+4)字節(jié)棺耍,而__objc_method_list的地址是0000000102737de0 + 8字節(jié) = 第1個(gè)方法的地址0000000102737de8objc_method結(jié)構(gòu)體占用24(8*3)字節(jié)种樱,再加24字節(jié)得到第2個(gè)方法的地址0000000102737e00蒙袍,同理再加24字節(jié)得到第3個(gè)方法的地址0000000102737e18

接著我們在MachOView中查看第1個(gè)方法的地址0000000102737de8??

上圖中嫩挤,0000000102737de8中存儲(chǔ)的第一個(gè)8字節(jié)地址是0102331F27害幅,再去到Hopper中搜索該地址??

image.png

同理,第2個(gè)8字節(jié)地址是01023326C4??

第3個(gè)8字節(jié)地址是010232C51D??

至此岂昭,我們從__objc_classlist中查找地址以现,首先通過__objc_classisa指針找到類名稱,接著找到下面的成員變量base method的地址约啊,找到objc_method_list方法列表邑遏,再根據(jù)objc_method結(jié)構(gòu)體大小,計(jì)算內(nèi)存平移后的地址恰矩,找到了所有的方法名稱无宿。

以上就是dyld加載類名并關(guān)聯(lián)方法列表的一個(gè)示例過程。

總結(jié)

  • Mach-O屬于一種文件格式
    • 包含:可執(zhí)行文件枢里、靜態(tài)庫、動(dòng)態(tài)庫蹂午、dyld等
    • 可執(zhí)行文件:
      • 通用二進(jìn)制文件:集合了多種架構(gòu)
      • lipo命令
        • -info 查看架構(gòu)
        • ‐thin 拆分架構(gòu)
        • ‐creat 合并架構(gòu)
  • Mach-O結(jié)構(gòu)
    • Header:用于快速確定文件的CPU類型栏豺、文件類型等
    • Load Commands:指示加載器(例如dyld)如何設(shè)置并且加載二進(jìn)制數(shù)據(jù)
    • Data:存放數(shù)據(jù)??
      • 代碼
      • 數(shù)據(jù)
      • 字符串常量
      • 方法
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市豆胸,隨后出現(xiàn)的幾起案子奥洼,更是在濱河造成了極大的恐慌,老刑警劉巖晚胡,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灵奖,死亡現(xiàn)場離奇詭異,居然都是意外死亡估盘,警方通過查閱死者的電腦和手機(jī)瓷患,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遣妥,“玉大人擅编,你說我怎么就攤上這事。” “怎么了爱态?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵谭贪,是天一觀的道長。 經(jīng)常有香客問我锦担,道長俭识,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任洞渔,我火速辦了婚禮套媚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痘煤。我一直安慰自己凑阶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布衷快。 她就那樣靜靜地躺著宙橱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蘸拔。 梳的紋絲不亂的頭發(fā)上师郑,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天,我揣著相機(jī)與錄音调窍,去河邊找鬼宝冕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛邓萨,可吹牛的內(nèi)容都是我干的地梨。 我是一名探鬼主播,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼缔恳,長吁一口氣:“原來是場噩夢啊……” “哼宝剖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起歉甚,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤万细,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后纸泄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赖钞,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年聘裁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了雪营。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,768評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡衡便,死狀恐怖卓缰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤征唬,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布捌显,位于F島的核電站,受9級(jí)特大地震影響总寒,放射性物質(zhì)發(fā)生泄漏攻礼。R本人自食惡果不足惜调违,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝠引,春花似錦闷畸、人聲如沸播歼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熏兄。三九已至品洛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間摩桶,已是汗流浹背桥状。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留硝清,地道東北人辅斟。 一個(gè)月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像芦拿,于是被迫代替她去往敵國和親士飒。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評論 2 350

推薦閱讀更多精彩內(nèi)容