逆向第三課(Mach-O)

Mach-O

Mach-O是Mach object的縮寫,是Mac\iOS上用于存儲(chǔ)程序假褪、庫的標(biāo)準(zhǔn)格式
一個(gè)Mach-O可執(zhí)行文件包含一個(gè)由一組加載命令組成的頭文件。對(duì)于使用共享庫或框架的程序筐带,其中一個(gè)命令指定用于加載程序的鏈接器的位置彪薛。如果你使用Xcode,它總是/usr/lib/dyld坯汤,這是標(biāo)準(zhǔn)的OS X動(dòng)態(tài)鏈接器虐唠。

#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 */

屬于Mach-O格式的文件類型有
可以在xnu源碼中,查看到Mach-O格式的詳細(xì)定義(https://opensource.apple.com/tarballs/xnu/
EXTERNAL_HEADERS/mach-o/fat.h
EXTERNAL_HEADERS/mach-o/loader.h

1.常見的Mach-O文件類型

MH_OBJECT
**目標(biāo)文件(.o)**
**靜態(tài)庫文件(.a)惰聂,靜態(tài)庫其實(shí)就是N個(gè).o合并在一起**
MH_EXECUTE:可執(zhí)行文件
**.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)信息的文件
**.dSYM/Contents/Resources/DWARF/xx(常用于分析APP的崩潰信息)**

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

官方描述
https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/MachOTopics/0-Introduction/introduction.html

**一個(gè)Mach-O文件包含3個(gè)主要區(qū)域**
Header 
文件類型疆偿、目標(biāo)架構(gòu)類型等

**Load commands**
描述文件在虛擬內(nèi)存中的邏輯結(jié)構(gòu)、布局

**Raw segment data**
在Load commands中定義的Segment的原始數(shù)據(jù)

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

命令行工具
file:查看Mach-O的文件類型
file  文件路徑

otool:查看Mach-O特定部分和段的內(nèi)容

lipo:常用于多架構(gòu)Mach-O文件的處理
查看架構(gòu)信息:lipo  -info  文件路徑
導(dǎo)出某種特定架構(gòu):lipo  文件路徑  -thin  架構(gòu)類型  -output  輸出文件路徑
合并多種架構(gòu):lipo  文件路徑1  文件路徑2  -output  輸出文件路徑

GUI工具
MachOView(https://github.com/gdbinit/MachOView)

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

通用二進(jìn)制文件
同時(shí)適用于多種架構(gòu)的二進(jìn)制文件
包含了多種不同架構(gòu)的獨(dú)立的二進(jìn)制文件

因?yàn)樾枰獌?chǔ)存多種架構(gòu)的代碼搓幌,通用二進(jìn)制文件通常比單一平臺(tái)二進(jìn)制的程序要大

由于兩種架構(gòu)有共同的一些資源杆故,所以并不會(huì)達(dá)到單一版本的兩倍之多

由于執(zhí)行過程中,只調(diào)用一部分代碼溉愁,運(yùn)行起來也不需要額外的內(nèi)存

因?yàn)槲募仍瓉淼囊蟠︻酰脖环Q為“胖二進(jìn)制文件”(Fat Binary)

dyld和Mach-O

dyld用于加載以下類型的Mach-O文件
MH_EXECUTE

MH_DYLIB

MH_BUNDLE

APP的可執(zhí)行文件、動(dòng)態(tài)庫都是由dyld負(fù)責(zé)加載的

APP從開發(fā)到安裝到手機(jī)的過程

app安裝過程.png
app安裝過程2.png

MJRefreshExample.app中的MJRefreshExample文件是iOS中的可執(zhí)行文件,文件格式是Mach-O

逆向APP的思路

界面分析
Cycript撤蟆、Reveal

代碼分析
對(duì)Mach-O文件的靜態(tài)分析
MachOView奕塑、class-dump、Hopper Disassembler枫疆、ida等

動(dòng)態(tài)調(diào)試
對(duì)運(yùn)行中的APP進(jìn)行代碼調(diào)試
debugserver爵川、LLDB

代碼編寫
注入代碼到APP中
必要時(shí)還可能需要重新簽名、打包ipa

class-dump

顧名思義息楔,它的作用就是把Mach-O文件的class信息給dump出來(把類信息給導(dǎo)出來)寝贡,生成對(duì)應(yīng)的.h頭文件

官方地址:http://stevenygard.com/projects/class-dump/

下載完工具包后將class-dump文件復(fù)制到Mac的/usr/local/bin目錄,這樣在終端就能識(shí)別class-dump命令了
常用格式
class-dump -H Mach-O文件路徑 -o 頭文件存放目錄
-H表示要生成頭文件
-o用于制定頭文件的存放目錄

代碼的編譯過程

代碼的編譯1.png
代碼的編譯2.png

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

從iOS3.1開始值依,為了提高性能圃泡,絕大部分的系統(tǒng)動(dòng)態(tài)庫文件都打包存放到了一個(gè)緩存文件中(dyld shared cache)
緩存文件路徑:/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armX

dyld_shared_cache_armX的X代表ARM處理器指令集架構(gòu)
v6
iPhone、iPhone3G
iPod Touch愿险、iPod Touch2

v7
iPhone3GS颇蜡、iPhone4、iPhone4S
iPad辆亏、iPad2风秤、iPad3(The New iPad)
iPad mini
iPod Touch3G、iPod Touch4扮叨、iPod Touch5

v7s
iPhone5缤弦、iPhone5C
iPad4

arm64
iPhone5S、iPhone6彻磁、iPhone6 Plus碍沐、iPhone6S、iPhone6S Plus
iPhoneSE衷蜓、iPhone7累提、iPhone7 Plus、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)庫共享緩存一個(gè)非常明顯的好處是節(jié)省內(nèi)存

動(dòng)態(tài)庫的加載

在Mac\iOS中,是使用了/usr/lib/dyld程序來加載動(dòng)態(tài)庫
dyld
dynamic link editor构拳,動(dòng)態(tài)鏈接編輯器
dynamic loader咆爽,動(dòng)態(tài)加載器

dyld源碼
https://opensource.apple.com/tarballs/dyld/

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

可以使用dyld源碼中的launch-cache/dsc_extractor.cpp
將#if 0前面的代碼刪除(包括#if 0)梁棠,把最后面的#endif也刪掉

編譯dsc_extractor.cpp
clang++ -o dsc_extractor dsc_extractor.cpp

使用dsc_extractor
./dsc_extractor  動(dòng)態(tài)庫共享緩存文件的路徑   用于存放抽取結(jié)果的文件夾
mach-o.png

執(zhí)行Mach-O文件

為了執(zhí)行它們的目標(biāo),程序必須執(zhí)行流程并鏈接到動(dòng)態(tài)共享庫斗埂。要使用其他庫或模塊符糊,
應(yīng)用程序必須定義對(duì)這些模塊中的符號(hào)的引用;這些引用在運(yùn)行時(shí)解析。在運(yùn)行時(shí)呛凶,
應(yīng)用程序使用的所有模塊的符號(hào)名稱都位于共享的名稱空間中男娄,類似于目錄。
為了在將來增強(qiáng)應(yīng)用程序及其使用的庫漾稀,應(yīng)用程序和庫開發(fā)人員必須確保為其函數(shù)和數(shù)據(jù)選擇的
名稱與其他模塊中使用的名稱不沖突模闲。

OS X v10.1的兩級(jí)命名空間特性

OS X v10.1引入了兩級(jí)符號(hào)命名空間特性。兩級(jí)名稱空間的第一級(jí)是包含符號(hào)的庫的名稱崭捍,第二級(jí)是符號(hào)的名稱尸折。啟用了兩級(jí)名稱空間特性后,當(dāng)靜態(tài)鏈接器記錄對(duì)導(dǎo)入符號(hào)的引用時(shí)殷蛇,它將記錄對(duì)包含符號(hào)和符號(hào)名稱的庫的名稱的引用实夹。與平面名稱空間相比,使用兩級(jí)名稱空間特性鏈接程序有兩個(gè)好處:

增強(qiáng)了搜索符號(hào)時(shí)的性能粒梦。使用兩級(jí)名稱空間亮航,動(dòng)態(tài)鏈接器知道從哪里開始查找符號(hào)的實(shí)現(xiàn)。使用平面名稱空間匀们,動(dòng)態(tài)鏈接器必須搜索所有加載的庫塞赂,以查找包含符號(hào)的庫。
增強(qiáng)向前兼容性昼蛀。在平面命名空間中,兩個(gè)或多個(gè)庫不能包含具有相同名稱的不同實(shí)現(xiàn)的符號(hào)圆存,因?yàn)閯?dòng)態(tài)鏈接器無法知道哪個(gè)庫包含首選實(shí)現(xiàn)叼旋。這在一開始并不是一個(gè)問題,因?yàn)殪o態(tài)鏈接器會(huì)在您第一次構(gòu)建應(yīng)用程序時(shí)捕獲任何此類問題沦辙。但是夫植,如果某個(gè)依賴共享庫的供應(yīng)商后來發(fā)布了一個(gè)新版本的庫,其中包含與您的程序或另一個(gè)依賴共享庫中的代碼同名的符號(hào)油讯,則程序?qū)o法運(yùn)行详民。
您的應(yīng)用程序必須直接鏈接到包含符號(hào)的共享庫(或者,如果該庫是傘形框架的一部分陌兑,則必須鏈接到包含符號(hào)的傘形框架)沈跨。

在啟用兩級(jí)名稱空間特性的程序中獲取符號(hào)時(shí),必須指定對(duì)包含符號(hào)的共享庫的引用兔综。

默認(rèn)情況下饿凛,OS X v10.1及以后版本中的靜態(tài)鏈接器對(duì)所有Mach-O文件使用兩級(jí)名稱空間狞玛。

這里作為補(bǔ)充引入幾個(gè)問題
1.可執(zhí)行文件與動(dòng)態(tài)庫同為mach-o 的最終產(chǎn)物,它們的關(guān)系是什么

可執(zhí)行文件與動(dòng)態(tài)庫同為mach-o文件涧窒,當(dāng)可執(zhí)行文件里面用到動(dòng)態(tài)庫心肪,就會(huì)在其內(nèi)部保留對(duì)動(dòng)態(tài)庫的引用。

2.動(dòng)態(tài)庫與可執(zhí)行文件作為最終產(chǎn)物纠吴,它為什么比可執(zhí)行文件大

動(dòng)態(tài)庫里面所有的.o都會(huì)被保留硬鞍,因?yàn)樗鼰o法確定哪些符號(hào)會(huì)被外部引用,因此一般的動(dòng)態(tài)庫比可執(zhí)行文件要大

3.靜態(tài)庫也支持two-level namespace嗎戴已?

只有mach-o的文件才支持two-level namespace功能固该。

4.two-level namespace 解決了符號(hào)重復(fù)的問題,但是類名也還是那個(gè)類名恭陡,會(huì)不會(huì)有問題

KVO 的實(shí)現(xiàn)簡(jiǎn)單來說就是創(chuàng)建了一個(gè)NSKVONotifying_A的新類蹬音,繼承被觀察的類A,它替換原有A類的isa 指針休玩,重寫了所提供的keyPath 相關(guān)的setter方法著淆,實(shí)現(xiàn)觀察A類屬性變化。平時(shí)用拴疤,一般不會(huì)有什么問題永部,但是當(dāng)遇上動(dòng)態(tài)庫,情況就不一樣了呐矾。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末苔埋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蜒犯,更是在濱河造成了極大的恐慌组橄,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罚随,死亡現(xiàn)場(chǎng)離奇詭異玉工,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)淘菩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門遵班,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人潮改,你說我怎么就攤上這事狭郑。” “怎么了汇在?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵翰萨,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我糕殉,道長(zhǎng)缨历,這世上最難降的妖魔是什么以蕴? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮辛孵,結(jié)果婚禮上丛肮,老公的妹妹穿的比我還像新娘。我一直安慰自己魄缚,他們只是感情好宝与,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冶匹,像睡著了一般习劫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嚼隘,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天诽里,我揣著相機(jī)與錄音,去河邊找鬼飞蛹。 笑死谤狡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的卧檐。 我是一名探鬼主播墓懂,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼霉囚!你這毒婦竟也來了捕仔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤盈罐,失蹤者是張志新(化名)和其女友劉穎榜跌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盅粪,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡斜做,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了湾揽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笼吟,死狀恐怖库物,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贷帮,我是刑警寧澤戚揭,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站撵枢,受9級(jí)特大地震影響民晒,放射性物質(zhì)發(fā)生泄漏精居。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一潜必、第九天 我趴在偏房一處隱蔽的房頂上張望靴姿。 院中可真熱鬧,春花似錦磁滚、人聲如沸佛吓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽维雇。三九已至,卻和暖如春晒他,著一層夾襖步出監(jiān)牢的瞬間吱型,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國打工陨仅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留津滞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓掂名,卻偏偏與公主長(zhǎng)得像据沈,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子饺蔑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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

  • 逆向App的基本步驟 界面分析Cycript锌介、Reveal 代碼分析對(duì)Mach-O文件的靜態(tài)分析MachOView...
    迷心迷閱讀 746評(píng)論 0 0
  • Cycript簡(jiǎn)介 Cycript是Objective-C++、ES6(JavaScript)猾警、Java等語法的混...
    斑駁的流年無法釋懷閱讀 805評(píng)論 0 0
  • 一发皿、ipa了解是個(gè)壓縮包崔慧,解壓后 二、逆向app思路穴墅; 界面分析Cycript:通過命令行查看界面的組成情況惶室,子控...
    Lovell_閱讀 1,377評(píng)論 0 1
  • iOS逆向開發(fā)(二)----Cycript,class-dump,Mach-O Cycript 在逆向開發(fā)中經(jīng)常要...
    會(huì)笑的Even閱讀 730評(píng)論 0 0
  • 我們編寫的C皇钞、C++、swift松捉、OC夹界,最終編譯鏈接生成Mach-O可執(zhí)行文件,它不僅僅代表可執(zhí)行文件隘世,還有很多可柿。...
    Lovell_閱讀 2,587評(píng)論 1 5