iOS 逆向開發(fā)17:HOOK原理下(HOOK OC方法)

iOS 逆向開發(fā) 文章匯總

目錄


一彼宠、符號表之間的關(guān)聯(lián)

懶加載符號表凭峡、間接符號表、符號表倍踪、字符串表之間的關(guān)聯(lián)

懶加載符號表
間接符號表
符號表
字符串表

懶加載符號表間接符號表index一一對應(yīng)
接符號表保存了在符號表中的index
符號表中保存了在字符串表中的index

上面的流程和fishhook查找符號的流程圖一致:The process of looking up the name of a given entry in the lazy or non-lazy pointer tables looks like this:


二扩借、去符號

一般情況下我們的APP會去掉所有符號(不包括間接符號)缤至、動態(tài)庫會保留全局符號供外部調(diào)用领斥。

Xcode 默認是去掉所有符號的,但是Deployment Postprocessing 需要設(shè)置為Yes何恶,否者只有在打包時才會去掉所有符號细层。

符號表中只有間接符號了今艺,本地符號和全局符號都去掉了

添加如下代碼:

運行APP后斷點是不起作用的虚缎,因為去掉了所有符號钓株。添加NSLog符號斷點可以斷住轴合,但是去掉符號后函數(shù)名會變?yōu)?code>___lldb_unnamed_symbol2

如果調(diào)用的是OC方法可以添加符號斷點并通過參數(shù)寄存器查看方法名和參數(shù)
還可以通過地址斷點(ASLR+地址偏移值)受葛、恢復(fù)符號表等方法查看方法名


三、恢復(fù)符號

- (void)differtest {
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"第一次外部函數(shù)的調(diào)用!");
    
    NSLog(@"第二次外部函數(shù)的調(diào)用!");
}

- (void)test1 {
    NSLog(@"第一次外部函數(shù)的調(diào)用!");
}

- (void)test {
    [self test1];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self test];
}

雖然去掉所有符號后符號表中沒有符號了,但是類的方法列表中還是存在闰渔。因此通過方法列表冈涧,類名列表等信息可以恢復(fù)出相關(guān)的符號


通過restore-symbol工具恢復(fù)符號(C函數(shù)正蛙、靜態(tài)函數(shù)不能恢復(fù)乒验,只能恢復(fù)Runtime相關(guān)的)

執(zhí)行代碼./restore-symbol -o symbolDemo2 symbolDemo后即可恢復(fù)符號徊件,恢復(fù)符號的MachO還需要重新簽名打包


四蒜危、使用fishhook HOOK系統(tǒng)MethodSwizzle方法辐赞,以檢測APP是否被HOOK

目標:APP中可以MethodSwizzle方法硝训,破解APP時直接調(diào)用MethodSwizzle方法會失敗窖梁。

4.1 新建項目AntiHook模擬我們自己的APP、添加兩個按鈕并關(guān)聯(lián)方法

代碼如下:

- (IBAction)btnClick1:(id)sender {
    NSLog(@"按鈕1調(diào)用!");
}

- (IBAction)btnClick2:(id)sender {
    NSLog(@"按鈕2調(diào)用了!");
}

防護代碼需要寫在Framework中邀窃,因為Framework加載比主工程中的代碼加載更快瞬捕,別人注入的HOOK代碼在Framework加載之后舵抹、在主工程之前惧蛹。

添加主Framework

// AntiHookCode.m

#import "fishhook.h"

@implementation AntiHookCode

+ (void)load {
    //exchange方法防護
    struct rebinding exchange;
    exchange.name = "method_exchangeImplementations";
    exchange.replacement = my_exchange;
    exchange.replaced = (void *)&exchangeP;
    
    //set香嗓、get方法防護
    //setIMP
    struct rebinding setIMP;
    setIMP.name = "method_setImplementation";
    setIMP.replacement = my_exchange;
    setIMP.replaced = (void *)&setIMP_p;
    
    //getIMP
    struct rebinding getIMP;
    getIMP.name = "method_getImplementation";
    getIMP.replacement = my_exchange;
    getIMP.replaced = (void *)&getIMP_p;

    
    struct rebinding bds[] = {exchange,setIMP,getIMP};
    rebind_symbols(bds, 3);
    
}

//指針!這個可以暴露給外接!我自己的工程使用!!
void (*exchangeP)(Method _Nonnull m1, Method _Nonnull m2);

IMP _Nonnull (*setIMP_p)(Method _Nonnull m, IMP _Nonnull imp);
IMP _Nonnull (*getIMP_p)(Method _Nonnull m);


void my_exchange(Method _Nonnull m1, Method _Nonnull m2){
    NSLog(@"檢測到了HOOK!");
}

@end

HookMgr.h中暴露AntiHookCode.h頭文件

HookMgr.h設(shè)置為Public供外界使用

ViewController.m:自己項目交換按鈕2的實現(xiàn)

#import <HookMgr/HookMgr.h>

- (void)viewDidLoad {
    [super viewDidLoad];
    //HOOK
    exchangeP(class_getInstanceMethod(self.class, @selector(btnClick2:)), class_getInstanceMethod(self.class, @selector(test)));
}

- (void)test {
    NSLog(@"本工程的HOOK!很順利!!!");
}

4.2 新建項目HookDemo用來HOOK我們的APP

將編譯好的AntiHook拷貝到HookDemo項目中的APP/Payload目錄中(真機編譯)

終端進入APP目錄
zip -ry WeChat.ipa Payload (ipa的名字這里沿用之前的)
刪除Payload目錄

HookDemo項目編譯運行到手機中

添加注入代碼:模擬別人HOOK按鈕1

添加腳本執(zhí)行

運行項目將APP安裝到手機、控制臺會直接輸出:檢測到了HOOK!
點擊按鈕1也不會執(zhí)行test方法掺出。這樣就達到了HOOK APP方法失敗的目的
點擊按鈕2會顯示本工程的HOOK!很順利!!!


五汤锨、使用MonkeyDev進行重新簽名和代碼注入

項目地址安裝方法

安裝好后重新打開Xcode就有如下功能(安裝MonkeyDev后Xcode如果打開崩潰牍汹,刪除Xcode重裝一次就可以了)

MonkeyDev

5.1 重簽名

  • 選擇MonkeyApp模板創(chuàng)建項目MonkeyDemo并運行安裝APP
  • 將需要重簽名的ipa or app 拖到TargetApp目錄中
  • 運行項目MonkeyDemo到手機即可進行重簽名

5.2 代碼注入:OC方法HOOK

修改MonkeyDemoDylib.xm文件的type

HOOK APP中ViewController的BtnClick1方法

Monkey實際上使用的是MethodSwizzle 中的method_getImplementation/method_setImplementation方法


六、總結(jié)

  1. HOOK:鉤子露该,改變程序的執(zhí)行流程的一種技術(shù)
  • MethodSwizzle
    • 利用OC的運行時(Runtime) 特性修改SEL和IMP (函數(shù)指針) 對應(yīng)關(guān)系第煮。達到HOOK OC方法的目的
    • method_exchangelMP... 交換兩個IMP
    • class_replaceMethod替換某個SEL的IMP (如果沒有該方法包警,就添加。相當于替換掉這個方法)
    • method_getlmplementation特铝、method_setlmplementation 獲取和設(shè)置某個方法的IMP (很多三方框架都使用)
  • fishhook
    • Facebook提供的一個工具篱瞎,利用MachO文件的加載原理,動態(tài)修改懶加載和非懶加載兩個符號表!
  • Cydia Substrate
    • 一個強大的框架牵素。
  1. fishhook
  • 可以HOOK 系統(tǒng)的函數(shù)笆呆,但是無法HOOK自定義的函數(shù)
  • 原理:
    • 共享緩存
      • iOS系統(tǒng)有一塊特殊的位置粱挡,存放公用動態(tài)庫询筏。動態(tài)庫共享緩存(dyld shared cache)
    • PIC技術(shù)
      • 由于外部的函數(shù)調(diào)用, 在我們編譯時刻是沒法確定其內(nèi)存地址的逆屡。
      • 蘋果就采用了PIC技術(shù)(位置無關(guān)代碼)。在MachO文件DATA段砍的,建立兩張表莺治,懶加載和非懶加載表谣旁,里面存放執(zhí)行外部函數(shù)的指針!
      • 首次調(diào)用懶加載函數(shù), 會去找執(zhí)行代碼夕土。首次執(zhí)行會執(zhí)行binder函數(shù)!
  • 通過字符找到懶加載表
    • fshhook利用stringTable --> Symbols --> indirect Symbols --> 懶加載符號表之間的對應(yīng)關(guān)系瘟判。通過重綁定修改指針的值達到HOOK的目的拷获。
  1. 反H0OK基本防護
  • 利用fishhook修改Methodswizzle 相關(guān)函數(shù)來檢測是否被HOOK
  • 防護代碼要最先被加載减细,否則先HOOK就修改完畢了,防護無效驮吱。
  • 原始工程編寫的Framework庫會優(yōu)先于注入庫加載左冬。所以適合寫防護代碼纸型。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末狰腌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瑰枫,更是在濱河造成了極大的恐慌丹莲,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逊谋,死亡現(xiàn)場離奇詭異土铺,居然都是意外死亡悲敷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門部宿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來理张,“玉大人绵患,你說我怎么就攤上這事≈” “怎么了移迫?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵厨埋,是天一觀的道長病瞳。 經(jīng)常有香客問我,道長亲善,這世上最難降的妖魔是什么逗柴? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮屠尊,結(jié)果婚禮上耕拷,老公的妹妹穿的比我還像新娘骚烧。我一直安慰自己,他們只是感情好既峡,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布运敢。 她就那樣靜靜地躺著忠售,像睡著了一般档痪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天乐纸,我揣著相機與錄音摇予,去河邊找鬼侧戴。 笑死,一個胖子當著我的面吹牛积仗,可吹牛的內(nèi)容都是我干的蜕猫。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼漱挚,長吁一口氣:“原來是場噩夢啊……” “哼旨涝!你這毒婦竟也來了侣背?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤衬鱼,失蹤者是張志新(化名)和其女友劉穎鸟赫,沒想到半個月后消别,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寻狂,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蛇券,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年纠亚,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片图呢。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖骗随,靈堂內(nèi)的尸體忽然破棺而出蛤织,到底是詐尸還是另有隱情,我是刑警寧澤鸿染,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布指蚜,位于F島的核電站,受9級特大地震影響牡昆,放射性物質(zhì)發(fā)生泄漏姚炕。R本人自食惡果不足惜摊欠,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望些椒。 院中可真熱鬧,春花似錦掸刊、人聲如沸免糕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽石窑。三九已至,卻和暖如春蚓炬,著一層夾襖步出監(jiān)牢的瞬間松逊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工肯夏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留经宏,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓驯击,卻偏偏與公主長得像烁兰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子徊都,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

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