005——HOOK原理

HOOK概述

HOOK(鉤子)其實(shí)就是改變程序執(zhí)行流程的一種技術(shù)的統(tǒng)稱!


HOOK原理

IOS中HOOK技術(shù)的幾種方式


1、Method Swizzle

利用OC中的Runtime特性,動(dòng)態(tài)改變SEL(方法編號(hào))和IMP(方法實(shí)現(xiàn))的對(duì)應(yīng)關(guān)系,達(dá)到OC方法調(diào)用流程改變的目的。主要用于OC方法。

2、fishhook

它是*** Facebook***提供的一個(gè)動(dòng)態(tài)修改鏈接mach-O文件的工具。利用MachO文件的加載原理,通過(guò)修改懶加載和非懶加載倆個(gè)表的指針達(dá)到C函數(shù)的HOOK的目的。

fishhook在OC中的使用:

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"123");
    
    //定義rebinding結(jié)構(gòu)體
    struct rebinding nslogBind;
    //函數(shù)的名稱
    nslogBind.name = "NSLog";
    //新的函數(shù)地址
    nslogBind.replacement = myLog;
    //保存原始函數(shù)地址的變量的指針
    nslogBind.replaced = (void *)&old_mylog;

    //定義數(shù)組
    struct rebinding rebindings[] = {nslogBind};

    /*
     arg1 : 存放rebinding結(jié)構(gòu)體的數(shù)組
     arg2 : 數(shù)組的長(zhǎng)度
     */
    rebind_symbols(rebindings, 1);
}

//函數(shù)指針,用來(lái)保存原始的函數(shù)地址
static void (*old_mylog)(NSString *format, ...);

//新的NSLog
void myLog(NSString *format, ...) {
    format = [format stringByAppendingString:@"\n勾上了!"];
    //再調(diào)用原來(lái)的
    old_mylog(format);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"點(diǎn)擊了屏幕?。?!");
}

@end

NSLog的綁定過(guò)程:

在MachO文件中查看NSLog的內(nèi)存地址


  • 利用image list 找到程序執(zhí)行的動(dòng)態(tài)地址
(lldb) image list
[  0] D92A4EC1-406D-3C26-9F39-C3D4A46A2948 0x00000001049f4000 /Users/yaoqi/Library/Developer/Xcode/DerivedData/001-fishHookDemo-cwtlojyvecrawmdgeiokwkgwddql/Build/Products/Debug-iphoneos/001-fishHookDemo.app/001-fishHookDemo 
[  1] 477A8A1F-098B-3A80-860D-656A3F4918EA 0x0000000104d38000 /Users/yaoqi/Library/Developer/Xcode/iOS DeviceSupport/11.2.1 (15C153)/Symbols/usr/lib/dyld 
[  2] B0F8DF97-77EC-3600-8A9F-35035B889EFD 0x0000000184dd9000 /Users/yaoqi/Library/Developer/Xcode/iOS DeviceSupport/11.2.1 (15C153)/Symbols/System/Library/Frameworks/Foundation.framework/Foundation 
(lldb) x 0x00000001049f4000+0x8018
0x1049fc018: 24 af de 84 01 00 00 00 34 b9 dd 84 01 00 00 00  $.......4.......
0x1049fc028: 90 f5 a2 8d 01 00 00 00 58 ab 9f 04 01 00 00 00  ........X.......
(lldb) dis -s 0x0184deaf24
Foundation`NSLog:
    0x184deaf24 <+0>:  sub    sp, sp, #0x20             ; =0x20 
    0x184deaf28 <+4>:  stp    x29, x30, [sp, #0x10]
    0x184deaf2c <+8>:  add    x29, sp, #0x10            ; =0x10 
    0x184deaf30 <+12>: add    x8, x29, #0x10            ; =0x10 
    0x184deaf34 <+16>: str    x8, [sp, #0x8]
    0x184deaf38 <+20>: add    x1, x29, #0x10            ; =0x10 
    0x184deaf3c <+24>: mov    x2, x30
    0x184deaf40 <+28>: bl     0x184ec6d38               ; _NSLogv
(lldb) ni
(lldb) ni
(lldb) ni
(lldb) ni
(lldb) ni
(lldb) ni
(lldb) x 0x00000001049f4000+0x8018
0x1049fc018: bc 9d 9f 04 01 00 00 00 34 b9 dd 84 01 00 00 00  ........4.......
0x1049fc028: 90 f5 a2 8d 01 00 00 00 3c ee f7 83 01 00 00 00  ........<.......
(lldb) dis -s 0x01049f9dbc
001-fishHookDemo`myLog:
    0x1049f9dbc <+0>:  sub    sp, sp, #0x30             ; =0x30 
    0x1049f9dc0 <+4>:  stp    x29, x30, [sp, #0x20]
    0x1049f9dc4 <+8>:  add    x29, sp, #0x20            ; =0x20 
    0x1049f9dc8 <+12>: mov    x8, #0x0
    0x1049f9dcc <+16>: stur   x8, [x29, #-0x8]
    0x1049f9dd0 <+20>: sub    x9, x29, #0x8             ; =0x8 
    0x1049f9dd4 <+24>: str    x0, [sp, #0x10]
    0x1049f9dd8 <+28>: mov    x0, x9
(lldb)

NSLog在MachO文件中的反向查找過(guò)程

MachO文件的查找過(guò)程

3、Cydia Substrate

Cydia Substrate原名為*** Mobile Substrate***,它的主要作用是針對(duì)OC方法、C函數(shù)以及函數(shù)地址進(jìn)行HOOK操作。當(dāng)然它并不是僅僅針對(duì)iOS而設(shè)計(jì)的,安卓一樣可以用。官方地址:http://www.cydiasubstrate.com/

Cydia Substrate主要由3部分組成:

  • MobileHooker
    MobileHooker顧名思義用于HOOK。它定義一系列的宏和函數(shù),底層調(diào)用objc的runtime和fishhook來(lái)替換系統(tǒng)或者目標(biāo)應(yīng)用的函數(shù)。

    • MSHookMessageEx 主要作用于Objective-C方法

    void MSHookMessageEx(Class class, SEL selector, IMP replacement, IMP result)

    • MSHookFunction 主要作用于C和C++函數(shù)

    void MSHookFunction(voidfunction,void* replacement,void** p_original)

Logos語(yǔ)法的%hook就是對(duì)此函數(shù)做了一層封裝

  • MobileLoader

MobileLoader用于加載第三方dylib在運(yùn)行的應(yīng)用程序中。啟動(dòng)時(shí)MobileLoader會(huì)根據(jù)規(guī)則把指定目錄的第三方的動(dòng)態(tài)庫(kù)加載進(jìn)去,第三方的動(dòng)態(tài)庫(kù)也就是我們寫(xiě)的破解程序.

  • safe mode
    因?yàn)锳PP程序質(zhì)量參差不齊崩潰再所難免,破解程序本質(zhì)是dylib,寄生在別人進(jìn)程里。 系統(tǒng)進(jìn)程一旦出錯(cuò),可能導(dǎo)致整個(gè)進(jìn)程崩潰,崩潰后就會(huì)造成iOS癱瘓。所以CydiaSubstrate引入了安全模式,在安全模 式下所有基于CydiaSubstratede 的三方dylib都會(huì)被禁用,便于查錯(cuò)與修復(fù)。

代碼的基本防護(hù)

在自己的APP中添加一個(gè)Framework庫(kù),庫(kù)中的代碼如下

#import "hookMgr.h"
#import "fishhook.h"
#import <objc/message.h>

@implementation hookMgr
//專門(mén)HOOK
+(void)load
{
    NSLog(@"hookMgr--Load");
    //內(nèi)部用到的交換代碼!
    Method old = class_getInstanceMethod(objc_getClass("ViewController"), @selector(btnClick1:));
    Method new = class_getInstanceMethod(self, @selector(click1Hook:));
    method_exchangeImplementations(old, new);
    
    
    //基本防護(hù)
    struct rebinding bd;
    bd.name = "method_exchangeImplementations";
    bd.replacement = myExchang;
    bd.replaced = (void *)&exchangeP;
    
    struct rebinding bd1;
    bd1.name = "method_getImplementation";
    bd1.replacement = myExchang;
    bd1.replaced = (void *)&getIMP;
    
    struct rebinding bd2;
    bd2.name = "method_setImplementation";
    bd2.replacement = myExchang;
    bd2.replaced = (void *)&setIMP;
    
//    method_getImplementation
//    method_setImplementation
    
    struct rebinding rebindings[] = {bd,bd1,bd2};
    rebind_symbols(rebindings, 3);
}

//保留原來(lái)的交換函數(shù)
IMP _Nonnull (*setIMP)(Method _Nonnull m, IMP _Nonnull imp);
IMP _Nonnull (*getIMP)(Method _Nonnull m);
void (*exchangeP)(Method _Nonnull m1, Method _Nonnull m2);

//新的函數(shù)
void myExchang(Method _Nonnull m1, Method _Nonnull m2){
    NSLog(@"檢測(cè)到了HOOK!!!");
    //強(qiáng)制退出!
    exit(1);
}


-(void)click1Hook:(id)sendr{
    NSLog(@"原來(lái)APP的HOOK保留!!");
}

@end

使用Monkey創(chuàng)建的工程去Hook App中的代碼:

如果別人要Hook自己寫(xiě)的App中的代碼,就會(huì)閃退。

// 修改 MachO

#import <UIKit/UIKit.h>

%hook ViewController

- (void)btnClick2:(id)org
{
    NSLog(@"??????????????????????????????");
    exit(0);
}

%end

HOOK原理總結(jié)

  • MachO文件是被誰(shuí)加載?DYLD(負(fù)責(zé)加載系統(tǒng)動(dòng)態(tài)庫(kù))加載
  • ASLR技術(shù) MachO文件加載的時(shí)候是隨機(jī)地址
  • PIC位置代碼獨(dú)立

如果MachO內(nèi)部需要調(diào)用系統(tǒng)的庫(kù)函數(shù)
現(xiàn)在_DATA段(可讀可寫(xiě))中建立一個(gè)指針,指向外部函數(shù)
DYLD會(huì)動(dòng)態(tài)的進(jìn)行綁定,將MachO中的_DATA中的指針,指向外部函數(shù)
_DATA中的指針就是一個(gè)symbols

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容