iOS逆向?qū)W習(xí)之四(初識(shí)Mach-O)

什么是Mach-O文件乘寒?

Mach-O是Mach object的縮寫,是Mac\iOS上用來存儲(chǔ)程序匪补、庫的標(biāo)準(zhǔn)格式

Mach-O文件類型

  • 可以點(diǎn)擊下載xnu源碼伞辛,在源碼中的<font color=red>EXTERNAL_HEADERS/mach-o/loader.h
    </font>文件中,我們可以看到Mach-O格式的所有文件類型
image

xun是蘋果MacOS\iOS等操作系統(tǒng)的內(nèi)核

  • 常見的Mach-O文件類型
Mach-O類型 示例文件
MH_OBJECT 目標(biāo)文件(.o)
靜態(tài)庫文件(.a)注:
MH_EXECUTE 可執(zhí)行文件夯缺,存放App的所有源碼信息蚤氏,在.app/xx
MH_DYLIB 動(dòng)態(tài)庫文件.dylib 或者 .framework/xx
MH_DYLINKER 動(dòng)態(tài)鏈接編輯器,也就是之前所說的/usr/lib/dyld工具
MH_DSYM 此文件中存儲(chǔ)這二進(jìn)制文件符號(hào)信息踊兜,在開發(fā)中竿滨,我們經(jīng)常使用此文件來分析App的崩潰信息

Mach-O的基本結(jié)構(gòu)

可以點(diǎn)擊官網(wǎng)查看Mach-O的介紹。

Mach-O組成

Mach-O由3個(gè)部分組成

  • Header捏境,包含文件類型于游、目標(biāo)架構(gòu)類型等等
  • Load commands,是描述文件在虛擬內(nèi)存中的邏輯結(jié)構(gòu)和布局,相當(dāng)于一份目錄索引
  • Raw segment data,在Load commands中所定義的Segment垫言,在這里都能找到原始數(shù)據(jù)贰剥。

Raw segment data存放了所有的原始數(shù)據(jù),而Load commands相當(dāng)于Raw segment data的索引目錄

image

窺探Mach-O的結(jié)構(gòu)

常用工具

  • 命令行工具筷频,通過file命令查看Mach-O文件的基本信息
file 文件路徑
  • otool鸠澈,查看Mach-O特定部分和段的內(nèi)容
#查看Mach-O文件的header信息
otool -h 文件路徑

#查看Mach-O文件的load commands信息
otool -l 文件路徑

更多使用方法,終端輸入otool -help查看

  • lipo截驮,用來處理多架構(gòu)Mach-O文件,常用命令如下
#查看架構(gòu)信息
lipo -info 文件路徑

#導(dǎo)出某種類型的架構(gòu)
lipo 文件路徑 -thin 架構(gòu)類型 -output 輸出文件路徑

#合并多種架構(gòu)類型
lipo 文件路徑1 文件路徑2 -output 輸出文件路徑

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

通用二進(jìn)制文件就是同時(shí)適用于多種架構(gòu)的二進(jìn)制文件际度,它包含了多種不同架構(gòu)的獨(dú)立的二進(jìn)制文件葵袭,它有以下特點(diǎn)

  • 因?yàn)樾枰鎯?chǔ)多種架構(gòu)的代碼,所以通用二進(jìn)制文件要比單架構(gòu)二進(jìn)制文件要大
  • 因?yàn)閮煞N種架構(gòu)之間可以共用一些資源乖菱,所以兩種架構(gòu)的通用二進(jìn)制文件大小不會(huì)達(dá)到單一架構(gòu)版本的兩倍坡锡。
  • 運(yùn)行過程中只會(huì)調(diào)用其中的部分代碼蓬网,所以運(yùn)行起來不會(huì)占用額外的內(nèi)存
  • 通用二進(jìn)制文件通常也被稱為“胖二進(jìn)制文件(Fat binary)”

dyld和Mach-O

dyld是iOS中用來加載可執(zhí)行文件、動(dòng)態(tài)庫的工具鹉勒,其實(shí)它本身也是一個(gè)Mach-O文件帆锋。

什么是dyld?
  • dyld 動(dòng)態(tài)加載器(又叫做動(dòng)態(tài)鏈接編輯器)
  • dyld的源碼可以點(diǎn)擊此處下載
dyld的作用禽额。

dyld可以用來加載以下三種類型的Mach-O文件

  • MH_EXECUTE
  • MH_DYLIB
  • MH_BUNDLE

通過查看dyld的源碼可以看到加載文件時(shí)的類型校驗(yàn)

image

從編碼到App安裝到手機(jī)

想要了解Mach-O文件锯厢,首先要了解從編寫代碼,開發(fā)App到App打包并安裝到手機(jī)上的整個(gè)過程脯倒。

  • 首先我們編寫完成代碼之后实辑,會(huì)通過LLVM編譯器預(yù)處理我們的代碼,比如將宏放在指定的位置
  • 預(yù)處理結(jié)束之后藻丢,LLVM會(huì)對代碼進(jìn)行詞法分析和語法分析剪撬,生成AST。AST是抽象語法樹悠反,主要用來進(jìn)行快速遍歷残黑,實(shí)現(xiàn)靜態(tài)代碼檢查的功能。
  • AST會(huì)生成IR斋否,IR是一種更加接近機(jī)器碼的語言梨水,通過IR可以生成不同平臺(tái)的機(jī)器碼。對于iOS平臺(tái)如叼,IR生成的可執(zhí)行文件就是Mach-O.
  • 然后通過鏈接器將符號(hào)和地址綁定在一起冰木,并且將項(xiàng)目中的多個(gè)Mach-O文件合并成一個(gè)Mach-O文件。
  • 最后通過簽名等操作生成.app文件笼恰,然后對.app文件進(jìn)行壓縮就生成了我們可以安裝的ipa包踊沸。
  • 當(dāng)然,ipa包的安裝途徑有兩種:
    • 通過開發(fā)者賬號(hào)上傳到App Store社证,然后在App Store上下載安裝逼龟。
    • 通過PP助手、iFunBox追葡、Xcode等工具來安裝

逆向App腺律,我們需要做哪些工作?

初步了解了什么是Mach-O文件宜肉,以及App從開發(fā)到安裝的過程,我們就可以來學(xué)習(xí)如何逆向一款A(yù)pp

  • 界面分析
    通過之前的學(xué)習(xí)匀钧,我們已經(jīng)可以使用Cycript和Reveal對App的界面進(jìn)行分析
  • 代碼分析
    iOS開發(fā)中,所有的代碼最后都會(huì)經(jīng)過編譯生成Mach-o文件谬返,所以我們需要對Mach-O文件進(jìn)行靜態(tài)分析

靜態(tài)分析的工具有MachOView之斯、class-dump、Hopper Disassembler遣铝、ida等等佑刷,后面會(huì)一一學(xué)習(xí)

  • 動(dòng)態(tài)調(diào)試
    除了靜態(tài)分析莉擒,我們還需要運(yùn)行目標(biāo)App,對App進(jìn)行動(dòng)態(tài)調(diào)試

動(dòng)態(tài)調(diào)試的工具有debugserver瘫絮、LLDB等等

  • 代碼編寫涨冀、注入
    進(jìn)行完界面分析、代碼分析和動(dòng)態(tài)調(diào)試之后麦萤,我們可以在特定位置注入我們自己寫的代碼鹿鳖,必要時(shí)可以重新簽名并且打包ipa

調(diào)試工具

calss-dump

class-dump的作用就是把Mach-O文件的class信息給導(dǎo)出來,生成對應(yīng)的.h頭文件

  • 可以點(diǎn)擊官網(wǎng)下載class-dump工具包
  • 下載完成之后將其中的class-dump可執(zhí)行文件復(fù)制到Mac上的<font color=red>/usr/local/bin</font>目錄中频鉴,這樣在終端就能識(shí)別class-dump命令了

在Mac中栓辜,終端執(zhí)行的所有指令都會(huì)去<font color=red>/usr/bin</font>目錄和<font color=red>/usr/local/bin</font>目錄下尋找

  • class-dump的常用命令如下
# -H表示需要生成頭文件  -o用于指定頭文件的存放目錄
class-dump -H Mach-O文件路徑 -o 頭文件存放目錄

Hopper Disassmbler

Hopper Disassmbler可以將Mach-O文件的機(jī)器語言反編譯成匯編代碼、OC偽代碼或者是Swift偽代碼垛孔。最常使用的快捷鍵有

#找出哪里引用了這個(gè)方法
Shift + Option + X

下載地址:https://pan.baidu.com/s/1yP_VcBlQ2G-rWsRue3uSBg


靜態(tài)庫和動(dòng)態(tài)庫

在iOS開發(fā)中藕甩,有很多功能都是現(xiàn)成可用的,不關(guān)你的App在用周荐,其它的App也在用狭莱,比如UIKit框架、GUI框架概作、I/O腋妙、網(wǎng)絡(luò)等等。這些庫都是通過鏈接器鏈接到Mach-O文件中的讯榕。

靜態(tài)庫

靜態(tài)庫是編譯時(shí)鏈接的庫骤素,需要連接進(jìn)入Mach-O文件中,如果需要更新就必須重新編譯一次愚屁,無法做到動(dòng)態(tài)加載和更新

動(dòng)態(tài)庫

動(dòng)態(tài)庫是運(yùn)行時(shí)鏈接的庫济竹。

Mach-O是文件編譯之后的產(chǎn)物,所以動(dòng)態(tài)庫并沒有參與Mach-O文件的編譯和鏈接霎槐。所以Mach-O文件中沒有包含動(dòng)態(tài)庫的符號(hào)定義送浊,也就是說這些符號(hào)會(huì)直接顯示未定義,但是他們的名字和對應(yīng)庫的路徑會(huì)被記錄下來丘跌。在運(yùn)行時(shí)通過dlopen和dlsym導(dǎo)入動(dòng)態(tài)庫時(shí)袭景,會(huì)根據(jù)記錄的路徑找到對應(yīng)的庫,再通過記錄的名字符號(hào)找到綁定的地址闭树。

動(dòng)態(tài)庫共享緩存(dyld shared cache)

從iOS3.1開始耸棒,為了提高性能,絕大部分的系統(tǒng)動(dòng)態(tài)庫文件都打包存放到了一個(gè)緩存文件中(dyld shared cache)报辱,緩存路徑是<font color=red>/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armX</font>

dyld_shared_cache_armX里面的X代表ARM處理器指令集的架構(gòu)

ARM指令集

ARM指令集(CPU指令的集合)有以下幾種

ARM指令集 支持的設(shè)備
armv6 iPhone榆纽、iPhone3G
iPod Touch、iPod Touch2
armv7 iPhone3GS、iPhone4奈籽、iPhone4S
iPad、iPad2鸵赫、iPad3(The New iPad)衣屏、iPad mini
iPod、Touch3G辩棒、iPod Touch4狼忱、iPod Touch5
armv7s iPhone5、iPhone5C一睁、iPad4
arm64 iPhone5S钻弄、iPhone6、iPhone6 Plus者吁、iPhone6S窘俺、iPhone6S Plus
iPhoneSE、iPhone7复凳、iPhone7Plus瘤泪、iPhone8、iPhone8 Plus育八、iPhoneX
iPad5对途、iPad Air、iPad Air2髓棋、iPad Pro实檀、iPad Pro2
iPad mini with Retina display、iPad mini3按声、iPad mini4
iPod Touch6

以上所有的指令集都是向下兼容的
為什么要使用動(dòng)態(tài)庫共享緩存呢膳犹?最大的好處就是節(jié)省內(nèi)存。

從動(dòng)態(tài)庫共享緩存抽取動(dòng)態(tài)庫

由于動(dòng)態(tài)庫共享緩存太大儒喊,如果想獲取其中某個(gè)動(dòng)態(tài)庫镣奋,例如UIKit,就需要從動(dòng)態(tài)庫共享緩存中抽取對應(yīng)的動(dòng)態(tài)庫

  • 使用dyld源碼中提供的方式來進(jìn)行抽取怀愧,工具在源碼中的<font color=red>launch-cache/dsc_extractor.cpp</font>文件中

    • 首先需要去掉源碼中的<font color=red>#if 0</font>判斷
    • 然后使用如下命令編譯<font color=red>dsc_extractor.cpp</font>文件
    clang++ -o dsc_extractor dsc_extractor.cpp
    

    此處是將dsc_extractor.cpp編譯生成可執(zhí)行文件dsc_extractor

    • 進(jìn)入執(zhí)行文件dsc_extractor所在目錄侨颈。通過以下的命令來抽取動(dòng)態(tài)庫
    ./dsc_extractor 動(dòng)態(tài)庫共享緩存文件的路徑 用于存放抽取結(jié)果的目錄
    
image
>建議抽取armv7s架構(gòu)的動(dòng)態(tài)庫,arm64抽取時(shí)會(huì)報(bào)以上錯(cuò)誤芯义,原因是dsc_extractor.bundle不能在Xcode10之后使用

- 抽取完成之后哈垢,使用Hopper Disassmbler打開想要逆向的動(dòng)態(tài)庫,就可以看到動(dòng)態(tài)庫中的源碼信息扛拨。


![image](https://upload-images.jianshu.io/upload_images/20878107-73f56e5bab50be16?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耘分,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌求泰,老刑警劉巖央渣,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異渴频,居然都是意外死亡芽丹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門卜朗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拔第,“玉大人,你說我怎么就攤上這事场钉∥冒常” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵逛万,是天一觀的道長泳猬。 經(jīng)常有香客問我,道長泣港,這世上最難降的妖魔是什么暂殖? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮当纱,結(jié)果婚禮上呛每,老公的妹妹穿的比我還像新娘。我一直安慰自己坡氯,他們只是感情好晨横,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著箫柳,像睡著了一般手形。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上悯恍,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天库糠,我揣著相機(jī)與錄音,去河邊找鬼涮毫。 笑死瞬欧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的罢防。 我是一名探鬼主播艘虎,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咒吐!你這毒婦竟也來了野建?” 一聲冷哼從身側(cè)響起属划,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎候生,沒想到半個(gè)月后同眯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡唯鸭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年嗽测,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肿孵。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖疏魏,靈堂內(nèi)的尸體忽然破棺而出停做,到底是詐尸還是另有隱情,我是刑警寧澤大莫,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布蛉腌,位于F島的核電站,受9級特大地震影響只厘,放射性物質(zhì)發(fā)生泄漏烙丛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一羔味、第九天 我趴在偏房一處隱蔽的房頂上張望河咽。 院中可真熱鬧,春花似錦赋元、人聲如沸忘蟹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽媚值。三九已至,卻和暖如春护糖,著一層夾襖步出監(jiān)牢的瞬間褥芒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工嫡良, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锰扶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓皆刺,卻偏偏與公主長得像少辣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子羡蛾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

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

  • 一漓帅、APP從開發(fā)到安裝到手機(jī)的過程 1.1、生成ipa包的過程選擇手機(jī)下的可執(zhí)行文件 1.2、真正安裝的過程安裝方...
    IIronMan閱讀 1,807評論 0 4
  • 一、ipa了解是個(gè)壓縮包捐迫,解壓后 二乾翔、逆向app思路; 界面分析Cycript:通過命令行查看界面的組成情況施戴,子控...
    Lovell_閱讀 1,377評論 0 1
  • 逆向App的基本步驟 界面分析Cycript反浓、Reveal 代碼分析對Mach-O文件的靜態(tài)分析MachOView...
    迷心迷閱讀 746評論 0 0
  • Cycript簡介 Cycript是Objective-C++、ES6(JavaScript)赞哗、Java等語法的混...
    斑駁的流年無法釋懷閱讀 805評論 0 0
  • 原文鏈接 dyld簡介 共享緩存機(jī)制1. dyld_cache_extract提取2. jtool提取3. dsc...
    三三At你閱讀 1,358評論 0 4