為什么會(huì)有這邊博文?
因?yàn)楣驹?領(lǐng)導(dǎo)又讓我撿起荒廢了一年多的ios,了解對(duì)ios應(yīng)用脫殼以及反編譯hook相關(guān)知識(shí).相比于安卓的hook來(lái)說(shuō)(想了解安卓hook的可以參考我的另外一篇文章),ios的hook要麻煩的多,前人栽樹后人乘涼,希望我的這邊文章能給大家對(duì)ios的hook有個(gè)清晰的認(rèn)識(shí)和思路.
一. 項(xiàng)目需求
本文以很久以前上架的一個(gè)練手app為例(app有點(diǎn)爛,將就一下吧,點(diǎn)擊傳送門). app大概是這個(gè)樣子
點(diǎn)擊生成二維碼,會(huì)進(jìn)入到一個(gè)生成二維碼的界面.我們本次的任務(wù)就是篡改點(diǎn)擊事件,實(shí)現(xiàn)點(diǎn)擊生成二維碼,彈出一個(gè)彈窗.
二. 項(xiàng)目流程
邏輯比較清晰,參考下圖:
三. 工具準(zhǔn)備
1. 一臺(tái)越獄設(shè)備(不知道怎么越獄的自己先行百度,本人試驗(yàn)機(jī)是ipad 11.3.1系統(tǒng))
2. 安裝要脫殼的應(yīng)用
四. 脫殼
以下是主流的目前三種脫殼方式,前兩種貌似在高版本中都會(huì)出現(xiàn)問(wèn)題,如果你的系統(tǒng)在9.0以下,可以考慮使用,如果是9.0以上,建議使用第三種.
1. Clutch工具靜態(tài)砸殼
這個(gè)方式主要是利用Clutch工具進(jìn)行砸殼,可以參考友軍的文章,我就不重復(fù)造輪子了.(注意高版本ios系統(tǒng)可能會(huì)出現(xiàn)kill9錯(cuò)誤,無(wú)法脫殼)
2.dumpdecrypted.dylib動(dòng)態(tài)庫(kù) 砸殼
從github上下載代碼(傳送門),編譯動(dòng)態(tài)庫(kù)dumpdecrypted.dylib.利用該動(dòng)態(tài)庫(kù)進(jìn)行脫殼,可以參考友軍文章,缺點(diǎn)是低版本有效,高版本會(huì)出現(xiàn)各種問(wèn)題.
3.frida-ios-dump 砸殼
由于該項(xiàng)目是個(gè)python項(xiàng)目,所以需要python環(huán)境.
++第一步++,
手機(jī)端
打開cydia 添加源: https://build.frida.re
打開剛剛添加的源 安裝 frida
安裝完成!檢查是否工作可以可在手機(jī)終端運(yùn)行 frida-ps -U 查看
++第二步:++
電腦端下載源碼,千萬(wàn)注意這個(gè)源碼是分3.x和2.x python版本的,一定要根據(jù)自己的ptthon環(huán)境版本下載相應(yīng)版本的源碼!!!
++第三步++
編譯源碼(可能會(huì)遇到各種安裝第三方庫(kù)錯(cuò)誤,耐心解決近,或者下方私信我).修改dump.py文件,把ip改成手機(jī)端ip
++第四步++:
執(zhí)行脫殼命令
./dump.py 應(yīng)用名稱
成功后就會(huì)在項(xiàng)目目錄中產(chǎn)生相應(yīng)的脫殼后的ipa文件,如下圖
五. 使用Class-dump導(dǎo)出頭文件
第一步:
下載
Class-dump
,得到Class-dump 運(yùn)行庫(kù)
第二步,解壓我們剛才得到的ipa文件(修改成.zip解壓即可),得到QrCode.app文件
第三步:
導(dǎo)出.h文件
執(zhí)行命令
class-dump -H QrCode.app文件路徑 -o 導(dǎo)出的文件夾路徑
完成后就能看到導(dǎo)出的.h文件了
六. 分析源碼
第一步.
安裝MonkeyDev,如何安裝請(qǐng)參考神器開源項(xiàng)目[傳送門],里面有詳細(xì)文檔
第二步.
安裝成功后您的xcode新建項(xiàng)目時(shí)就會(huì)出現(xiàn)如下圖工程:
第三步:
選擇MonkeyApp新建工程,將我們脫殼后的ipa文件放入項(xiàng)目對(duì)應(yīng)文件夾,其他都不用修改,選擇真機(jī)直接運(yùn)行
第四步:
調(diào)試應(yīng)用,得到掃描界面的控制器類MainController,我試圖獲取uiveiw的action,但發(fā)現(xiàn)他的action是動(dòng)態(tài)寫在代碼中的
我們搜索我們上面得到的頭文件,找到MainController.h文件,代碼如下:
可以看到有個(gè)setListener方法和兩個(gè)uiveiw,基本我們可以確定我們需要的點(diǎn)擊事件就在setListener方法中.下面我們驗(yàn)證下.
第四步:
對(duì)剛才我們得到的QRCode.app文件顯示包內(nèi)容,可以得到moth-o類型的源碼文件QRCode
下載Hopper工具,將QRCode文件拖進(jìn)去,就可以查看響應(yīng)的oc偽碼,以及匯編代碼.如下圖
搜索MainController,找到setListener方法,查看oc偽碼
發(fā)現(xiàn)他跳轉(zhuǎn)了menuAction方法,我們雙擊點(diǎn)進(jìn)去
可以看到,就是通過(guò)在這里處理跳轉(zhuǎn)事件,控制程序跳轉(zhuǎn)到下個(gè)控制,也驗(yàn)證了我們的猜想是正確的,我們只需要攔截 setListener方法,當(dāng)他點(diǎn)擊生成二維碼這個(gè)圖片view的時(shí)候,讓他彈個(gè)窗即可.
七.編寫hook攔截代碼
回到我們新建的MonkeyApp工程,新建HookAlert.m文件,編寫hook邏輯,攔截代碼
運(yùn)行后點(diǎn)擊生成二維碼查看效果:
出現(xiàn)彈窗,攔截成功!
補(bǔ)充說(shuō)明:
MonkeyApp提供了多種hook的寫法,這里我們使用的是CaptainHook的寫法,我簡(jiǎn)單介紹下用法(官方竟然沒有詳細(xì)的api說(shuō)明!)
一個(gè)單獨(dú)的hook類,大概包含以下三部分,看一查看我寫的注釋
#import <Foundation/Foundation.h>
#import <CaptainHook/CaptainHook.h>
#import <UIKit/UIKit.h>
CHDeclareClass(MainController) //聲明hook的類
//聲明hook的方法,數(shù)字代碼參數(shù)個(gè)數(shù),第一個(gè)參數(shù)一般是self,第二個(gè)參數(shù)代表返回值,第三個(gè)參數(shù)是類名,第四個(gè)是方法名,后面接方法參數(shù)以及類型
CHOptimizedMethod1(self, void, MainController, menuAction,id,arg1){
//獲取類變量view的值
UIView* item2= CHIvar(self, _item2_bgview,__strong UIView*) ;
UIView* item=[arg1 view];
if(item2==item){
//攔截 點(diǎn)擊事件
UIAlertView *alert=[UIAlertView new];
[alert setTitle:@"提示"];
[alert setMessage:@"攔截成功"];
[alert show];
NSLog(@"測(cè)試成功...%@ : %@",arg1,item2);
}else{
// 其他邏輯正常執(zhí)行元源代碼
CHSuper1(MainController, menuAction, arg1);
}
}
// 構(gòu)造方法,
CHConstructor{
CHLoadLateClass(MainController); //再次聲明hook的類
CHClassHook1(MainController, menuAction); //再次聲明hook的方法
}
八. 總結(jié)
至此,我們的ios從脫殼到分析再到代碼攔截就完成了,網(wǎng)上很多文章都是要么寫怎么脫殼,要么怎么寫hook,要么就是寫怎么分析,很少有一個(gè)寫全面流程的文章.希望這邊文章對(duì)大家有幫助,喜歡就伸手點(diǎn)個(gè)關(guān)注吧.