MachO文件分析

MachO文件

Mach-O是Mach Object文件格式的縮寫调炬,是mac以及iOS上可執(zhí)行文件的格式。是一種用于可執(zhí)行文件舱馅、目標(biāo)代碼缰泡、動(dòng)態(tài)庫的文件格式。作為a.out格式的替代代嗤,Mach-O提供了更強(qiáng)的擴(kuò)展性棘钞。
類似于windows上的PE格式 (Portable Executable ),linux上的elf格式 (Executable and Linking Format)

Mach-O文件格式

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

實(shí)際開發(fā)中干毅,MatchO文件有很多不同的類型宜猜,可以通過在Xcode上指定。
TargetsBuild SettingsLinkingMach-O Type

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

  • 蘋果公司提出的一種程序代碼硝逢,能同時(shí)適用多種架構(gòu)的二進(jìn)制文件姨拥。
  • 同一個(gè)程序包中同時(shí)為多種架構(gòu)提供最理想的性能绅喉。
  • 因?yàn)樾枰獌?chǔ)存多種代碼,通常比單一平臺(tái)二進(jìn)制的程序要大叫乌。
  • 由于執(zhí)行中只調(diào)用一部分代碼柴罐,運(yùn)行起來也不需要額外的內(nèi)存。

在Xcode編譯可以指定生成哪些架構(gòu)的Match-O文件憨奸,同時(shí)也可以添加其他架構(gòu)
TargetsBuild SettingsArchitecturesArchitectures

設(shè)備的CPU架構(gòu)(指令集)

  • 模擬器:
    • 4s-5: i386
    • 5s-6s Plus: x86_64
  • 真機(jī)(iOS設(shè)備):
    • armv6: iPhone革屠、iPhone 2、iPhone 3G排宰、iPod Touch(第一代)似芝、iPod Touch(第二代)
    • armv7: iPhone 3Gs、iPhone 4板甘、iPhone 4s国觉、iPad、iPad 2
    • armv7s: iPhone 5虾啦、iPhone 5c
    • arm64: iPhone 5s之后機(jī)型

Mach-O架構(gòu)拆分、合并

  1. lipo工具
  • 查看MachO架構(gòu)

$lipo -info 'MachO文件'

  • 拆分MachO架構(gòu)

$lipo 'MachO文件' –thin '架構(gòu)名' –output '目標(biāo)MachO文件'

  • 合并MachO架構(gòu)

$lipo -create '第一個(gè)MachO文件' '第二個(gè)MachO文件 -output '目標(biāo)MachO文件'

  1. file指令:查看文件信息

$file 文件路徑

MachO文件結(jié)構(gòu)

Mach-O 的組成結(jié)構(gòu)如圖所示痕寓,主要包括三個(gè)部分:Header傲醉、Load commands、Data

Header

包含二進(jìn)制文件的一般信息呻率,架構(gòu)類型硬毕、字節(jié)順序、加載指令的數(shù)量等礼仗。

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:定位結(jié)構(gòu)是64位還是32位 (e.g. MH_MAGIC_64)
cputype:CPU類型 (e.g. CPU_TYPE_ARM64)
cpusubtype:CPU具體類型 (e.g. CPU_SUBTYPE_ARM64_ALL)
filetype:文件類型 (e.g. MH_EXECUTE)
ncmds:Load Commands條數(shù)
sizeofcmds:Load Commands大小
flags:標(biāo)志位吐咳。標(biāo)識(shí)二進(jìn)制文件支持的功能,主要和系統(tǒng)加載元践、鏈接有關(guān)
reserved:預(yù)留區(qū)(只有64位才有)

Load Commands

包含區(qū)域的位置韭脊、符號(hào)表、動(dòng)態(tài)符號(hào)表等单旁。描述了文件中數(shù)據(jù)的具體組織結(jié)構(gòu)沪羔,不同的數(shù)據(jù)類型使用不同的加載命令表示。

  • LC_SEGMENT_64(__PAGEZERO)
    • VM Size:虛擬內(nèi)存象浑,大小4G(32位是16M)蔫饰。用于區(qū)分32位及存儲(chǔ)位置
  • LC_SEGMENT_64(__TEXT)
  • LC_SEGMENT_64(__DATA)
  • LC_SEGMENT_64(__LINKEDIT)
    • VM Address:虛擬內(nèi)存地址
    • VM Size:虛擬內(nèi)存大小
    • File Offset:數(shù)據(jù)在文件中的起始位置
    • File Size:數(shù)據(jù)在文件中的大小
  • LC_DYLD_INFO_ONLY(動(dòng)態(tài)鏈接相關(guān)信息)
    • Rebase:進(jìn)行重定向的位置信息。當(dāng)MachO加載到內(nèi)存里愉豺,系統(tǒng)會(huì)隨機(jī)分配一個(gè)內(nèi)存偏移大小aslr篓吁,和rebase里面的offset,對接(位置相加)獲取代碼在內(nèi)存中的實(shí)際位置蚪拦。再根據(jù)size開辟實(shí)際內(nèi)存
    • Binding:綁定的位置信息
    • Weak Binding:弱綁定的位置信息
    • Lazy Binding:懶加載綁定的位置信息
    • Export:對外的位置信息
  • LC_SYMTAB(符號(hào)表地址)
    • Symbol Table Offset:符號(hào)表的位置杖剪。函數(shù)名稱冻押、函數(shù)地址關(guān)聯(lián)的信息
    • Number of Symbol:符號(hào)數(shù)
    • String Table Offset:符號(hào)名稱位置
    • String Table Size:符號(hào)名稱大小
  • LC_DYSYMTAB(動(dòng)態(tài)符號(hào)表地址)
  • LC_LOAD_DYLINKER(動(dòng)態(tài)庫連接器:dyld)
    • Str Offset:動(dòng)態(tài)庫連接器位置
    • Name:動(dòng)態(tài)庫連接器路徑(dyld)
  • LC_UUID(MachO文件唯一標(biāo)識(shí))
  • LC_VERSION_MIN_IPHONESOS(MachO文件支持最低的操作系統(tǒng)版本)
  • LC_SOURCE_VERSION(源代碼版本)
  • LC_MAIN(MachO程序入口:設(shè)置程序主線程的入口地址和棧大小)
    • Entry Offset:入口位置
    • Stacksize:堆棧大小
    • Entry Point:入口點(diǎn)(內(nèi)存地址)
  • LC_ENCRYPTION_INFO_64(加密信息)
    • Crypt Offset:加密信息位置
    • Crypt Size:加密信息大小
    • Crypt ID:加密信息ID摘盆。非加密是0翼雀,加密是1
  • LC_LOAD_DYLIB(依賴庫的路徑,包含三方庫)
    • Str Offset:動(dòng)態(tài)庫位置
    • Time Stamp:動(dòng)態(tài)庫時(shí)間
    • Current Version:動(dòng)態(tài)庫版本
  • LC_RPATH(frameworks信息)
  • LC_FUNCTION_STARTS(函數(shù)的起始位置表)
  • LC_DATA_IN_CODE(代碼數(shù)據(jù)信息)
  • LC_CODE_SIGNATURE(代碼簽名信息)

Data

由 Segment 段和 Section 節(jié)組成孩擂。存放具體數(shù)據(jù):代碼狼渊、數(shù)據(jù)、字符串常量类垦、類狈邑、方法等。

  1. Segment 組成
#define SEG_PAGEZERO    "__PAGEZERO" /* 當(dāng)時(shí) MH_EXECUTE 文件時(shí)蚤认,捕獲到空指針 */
#define SEG_TEXT    "__TEXT" /* 代碼/只讀數(shù)據(jù)段 */
#define SEG_DATA    "__DATA" /* 數(shù)據(jù)段 */
#define SEG_OBJC    "__OBJC" /* Objective-C runtime 段 */
#define SEG_LINKEDIT    "__LINKEDIT" /* 包含需要被動(dòng)態(tài)鏈接器使用的符號(hào)和其他表米苹,包括符號(hào)表、字符串表等 */
  1. Segment 的數(shù)據(jù)結(jié)構(gòu)
struct segment_command_64 { 
    uint32_t    cmd;        /* LC_SEGMENT_64 */
    uint32_t    cmdsize;    /* section_64 結(jié)構(gòu)體所需要的空間 */
    char        segname[16];    /* segment 名字砰琢,上述宏中的定義 */
    uint64_t    vmaddr;     /* 所描述段的虛擬內(nèi)存地址 */
    uint64_t    vmsize;     /* 為當(dāng)前段分配的虛擬內(nèi)存大小 */
    uint64_t    fileoff;    /* 當(dāng)前段在文件中的偏移量 */
    uint64_t    filesize;   /* 當(dāng)前段在文件中占用的字節(jié) */
    vm_prot_t   maxprot;    /* 段所在頁所需要的最高內(nèi)存保護(hù)蘸嘶,用八進(jìn)制表示 */
    vm_prot_t   initprot;   /* 段所在頁原始內(nèi)存保護(hù) */
    uint32_t    nsects;     /* 段中 Section 數(shù)量 */
    uint32_t    flags;      /* 標(biāo)識(shí)符 */
};
  1. Section 數(shù)據(jù)結(jié)構(gòu)
    部分的 Segment (主要指的 __TEXT 和 __DATA)進(jìn)一步分解為 Section。
struct section_64 { 
    char        sectname[16];   /* Section 名字 */
    char        segname[16];    /* Section 所在的 Segment 名稱 */
    uint64_t    addr;       /* Section 所在的內(nèi)存地址 */
    uint64_t    size;       /* Section 的大小 */
    uint32_t    offset;     /* Section 所在的文件偏移 */
    uint32_t    align;      /* Section 的內(nèi)存對齊邊界 (2 的次冪) */
    uint32_t    reloff;     /* 重定位信息的文件偏移 */
    uint32_t    nreloc;     /* 重定位條目的數(shù)目 */
    uint32_t    flags;      /* 標(biāo)志屬性 */
    uint32_t    reserved1;  /* 保留字段1 (for offset or index) */
    uint32_t    reserved2;  /* 保留字段2 (for count or sizeof) */
    uint32_t    reserved3;  /* 保留字段3 */
};

以下列舉一些常見的 Section:

__TEXT,__text: 主程序代碼
__TEXT,__stubs / __stub_helper: 用于動(dòng)態(tài)鏈接的樁
__TEXT,__objc_methname: OC方法名稱
__TEXT,__objc_classname: OC類名
__TEXT,__objc_methtype: OC方法類型
__TEXT,__cstring: 程序中c語言字符串
__DATA,__got: 非懶加載符號(hào)表
__DATA,__la_symbol_ptr: 懶加載符號(hào)表
__DATA,__objc_classlist: OC類列表
__DATA,__objc_protollist: OC原型列表
__DATA,__objc_imageinfo: OC鏡像信息
__DATA,__objc_const: OC常量
__DATA,__objc_selfrefs: OC類自引用(self)
__DATA,__objc_superrefs: OC類超類引用(super)
__DATA,__objc_protolrefs: OC原型引用
__DATA,__objc_data / __data: OC代碼數(shù)據(jù)
Dynamic Loader Info: 動(dòng)態(tài)鏈接器所需要使用的信息 (重定向,符號(hào)綁定,懶加載綁定等..)
Function Starts: 方法的起始位置
Symbol Table: 符號(hào)表
Dynamic Symbol Table: 動(dòng)態(tài)符號(hào)表
String Table: 字符串表
Code Signature: 代碼簽名信息

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末陪汽,一起剝皮案震驚了整個(gè)濱河市训唱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挚冤,老刑警劉巖况增,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異训挡,居然都是意外死亡澳骤,警方通過查閱死者的電腦和手機(jī)澜薄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門为肮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人表悬,你說我怎么就攤上這事弥锄。” “怎么了蟆沫?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵籽暇,是天一觀的道長。 經(jīng)常有香客問我饭庞,道長戒悠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任舟山,我火速辦了婚禮绸狐,結(jié)果婚禮上卤恳,老公的妹妹穿的比我還像新娘。我一直安慰自己寒矿,他們只是感情好突琳,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著符相,像睡著了一般拆融。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上啊终,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天镜豹,我揣著相機(jī)與錄音,去河邊找鬼蓝牲。 笑死趟脂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的例衍。 我是一名探鬼主播昔期,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼佛玄!你這毒婦竟也來了镇眷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤翎嫡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后永乌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惑申,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年翅雏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了圈驼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡望几,死狀恐怖绩脆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情橄抹,我是刑警寧澤靴迫,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站楼誓,受9級特大地震影響玉锌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜疟羹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一主守、第九天 我趴在偏房一處隱蔽的房頂上張望禀倔。 院中可真熱鬧,春花似錦参淫、人聲如沸救湖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鞋既。三九已至,卻和暖如春憔维,著一層夾襖步出監(jiān)牢的瞬間涛救,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工业扒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留检吆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓程储,卻偏偏與公主長得像蹭沛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子章鲤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353

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