Mach-O文件內(nèi)部揭秘

在windows上可執(zhí)行文件的格式是exe,在Linux上ELF是可執(zhí)行文件,而在蘋果系統(tǒng)上,Mac OS X和ios系統(tǒng)上,可執(zhí)行文件的格式是Mach-O格式。官方解釋地址:https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/MachORuntime/index.html

1、Mach與Mach-O

這里先提醒大家一下,Mach不是Mac,Mac是蘋果電腦Macintosh的簡稱,而Mach則是一種操作系統(tǒng)內(nèi)核。Mach內(nèi)核被NeXT公司的NeXTSTEP操作系統(tǒng)使用。在Mach上,一種可執(zhí)行的文件格是就是Mach-O(Mach Object file format)。Mac OS X是Unix的“后代”,但所主要支持的可執(zhí)行文件格式是Mach-O。

iOS是從OS X演變而來,所以同樣是支持Mach-O格式的可執(zhí)行文件。

2、ios可執(zhí)行文件初探

作為ios開發(fā)者,我們比較熟悉ipa包,這種文件格式,然而,實際上這只是一個變相的zip的壓縮包。我們將其解壓之后發(fā)現(xiàn)


這其實是一個Payload的包 打開這個包 不能發(fā)現(xiàn) 這是一個test1.app的文件 也就是xcode生成的product文件

而這其實也就是一個文件夾,打開這個文件夾(顯示包含內(nèi)容)發(fā)現(xiàn)其中有一個同名的test1的可執(zhí)行文件,這就是我們最終要尋找的在ios上的可執(zhí)行文件

我們用file命令來查看這個文件的文件類型


這是一個64位的Mach-O 格式的可執(zhí)行文件


3、Mach-O文件細究

根據(jù)蘋果官方文檔提供Mach-O文件的數(shù)據(jù)主體可分為三個部分


頭部(Header)、加載命令(Load Commands)、數(shù)據(jù)(Data)

而數(shù)據(jù)部分則又被分割成了一段段的Segments。

下面我們使用otool工具來一探究竟

a) 先來查看下這個可執(zhí)行文件的頭部是怎樣的


一堆看不明白的東西,分別予以解釋

magic:0xfeedfacf 。這個東西是Mach-O的魔數(shù)。簡單介紹下什么叫做魔數(shù):很多類型的文件,其起始的幾個字節(jié)的內(nèi)容是固定的(或是有意填充,或是本就如此)。根據(jù)這幾個字節(jié)的內(nèi)容就可以確定文件類型,因此這幾個字節(jié)的內(nèi)容被稱為魔數(shù) (magic number)。

在OS X上 可執(zhí)行文件的標識有這樣幾個魔數(shù):cafebabe、feedface、feadfacf、還有就是以#!開頭的。

cputype、cpusubtype:指的是CPU類型和CPU子類型

在/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/mach里找到machine.h的定義 如下圖


這里有支持的cpu的詳細編號命名 0代表ARM的格式都將支持

caps: 額 官網(wǎng)上都沒介紹 這個待查

filetype 2:代表可執(zhí)行文件

ncmds:指的是加載命令(load commands)的數(shù)量,例子中一共22個,編號0-21

sizeofcmds:表示要load的22個commands的總的大小

flags:可用來檢驗是否開啟了PIE,如開啟了則需要移除方能正常使用MachOView才能把文件結(jié)構(gòu)檢測出來

它有這么幾種定義值:我們的文件無未定義引用?(MH_NOUNDEFS),是為動態(tài)鏈接器(MH_DYLDLINK),使用two-level名Cheng綁定(MH_TWOLEVEL)且應(yīng)被加載到隨機地址?(MH_PIE).

b)再來看加載命令(Load Commands) 截取其中一個Commands來分析


Load command 0 :command編號

cmdLC_SEGMENT_64:即是將文件中的段映射進內(nèi)存中的地址空間

segname:16字節(jié)段名稱

vmaddr:段虛擬內(nèi)存的起始地址

vmsize:段虛擬內(nèi)存的大小

fileoff:段在內(nèi)存中的偏移量

filesize:段在文件中的大小

maxprot:段頁面所需要的最高內(nèi)存保護

initprot:段頁面初始內(nèi)存保護

nsects:段中包含section的數(shù)量

flags:其他雜項標志位

c)接下來看data,注意到command和data都是以segment為大單元字節(jié),但是在data里還有section字節(jié) 所以重點介紹section的組織格式 截取一個section供分析


sectname:section的名字

segname:section歸屬為哪一個segment

addr:secction起始內(nèi)存地址

size:section的大小

offset:該section的文件偏移量

align:字節(jié)大小對齊

reloff:重定位入口的文件偏移

nreloc:需要重定位的入口數(shù)量

flags:包含了section的類型和獨自的屬性

最后兩項保留用

了解了這些 才能根據(jù)Mach-O的文件結(jié)構(gòu) 去分析類的名稱和類的方法 即是class-dump的實現(xiàn)原理,同時這也是MachOView等的分析原理

參考自:http://turingh.github.io/2016/03/07/mach-o%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F%E5%88%86%E6%9E%90/

附上otool命令大全

-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)

-p ? start dissassemble from routine name

-s 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

-T print the table of contents of a dynamic shared library

-M print the module table of a dynamic shared library

-R print the reference table of a dynamic shared library

-I print the indirect symbol table

-H print the two-level hints table

-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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

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