"乘风破浪: iOS逆向HOOK的实践"

上一篇文章: "心旷神怡:挖掘LLDB调试的无限可能性"

前篇文章介绍了如何运用LLDB进行动态调试。在本篇中,我们将深入探讨HOOK的原理。

回顾之前的内容,我们已经了解了一些关于HOOK的知识,包括如何通过砸壳、使用class-dump工具来获取目标应用的信息,并且实现了在tweak工程中进行类的hook等一系列操作,从而实现我们想要的功能。

因此,我们不仅需要掌握如何熟练地使用HOOK技术,还需要理解其背后的原理。

1.HOOK本质

  • HOOK ,中文称之为“钩子”,意味着在程序执行过程中插入的一种机制,可以用来监视、修改或者拦截程序的行为。

注意

HOOK技术实质上是一种改变程序执行流程的技术。在软件工程中,程序的执行流程是按照一定的逻辑和顺序进行的,而HOOK技术可以介入这个流程,改变其正常执行的路径,从而实现特定的功能或修改程序的行为。

举例来说,我们可以考虑视频广告的情况。在某些应用中,如果用户不是会员,就需要观看一定时长的广告才能继续使用。通过使用HOOK技术,我们可以修改应用的代码,以拦截广告播放的部分,从而实现跳过广告的效果。这个例子只是一个示范,实际上,HOOK技术可以应用于各种场景,包括增加功能、修改行为、调试应用等等。

当然,拦截广告只是HOOK技术的一个应用案例,实际上,它的应用远不止于此。在以后的技术分享中,我们可以进一步探讨不同的应用场景和具体实现方法。

2.HOOK原理

  • 1. HOOK原理第一种方式,通过Method Swizzle进行实现.
Method Swizzle

首先,Method Swizzle离不开Objective-C的运行时(Runtime)特性,因为它需要在运行时动态地交换方法的实现。其次,这项技术在越狱平台和非越狱平台都可以使用。

另外,提到了通过交换两个selector来实现方法交换调用,这是Method Swizzle的核心原理之一。通过交换两个方法的实现,可以改变原本的方法调用顺序或行为,从而实现一些特定的功能或修复bug。

2.1 方法的实现保存在IMP(Implementation)中,这是一种函数指针,指向了具体的方法实现代码。

2.2 Runtime提供了修改IMP和交换两个IMP实现的方法。

案例

ViewController.m

#import "ViewController.h"
#import <Objc/Runtime.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self originalMehtod];
    
    [self newMethod];
}

+ (void)load{
    
    Class class = [self class];
    
    SEL originalSelector = @selector(originalMehtod);
    
    SEL newSelector = @selector(newMethod);
    
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    
    Method newMethod = class_getInstanceMethod(class, newSelector);
    
    method_exchangeImplementations(originalMethod,newMethod);
    
}

-(void)originalMehtod{
    
    NSLog(@"原方法");
}

-(void)newMethod{
    
    NSLog(@"新方法");
}

@end

结果

2020-02-27 15:50:24.226036+0800 SwizzleMethod[4372:221449] 新方法
2020-02-27 15:50:24.226125+0800 SwizzleMethod[4372:221449] 原方法

我们通过方法的交换实现,修改了方法的调用.

  • 3. 如果我们在新创建的方法调用自己,会不会循环调用?

我们看一下调用结果

-(void)newMethod{
    
    NSLog(@"新方法");
    
    [self newMethod];
}

打印结果

2020-02-27 15:54:47.515105+0800 SwizzleMethod[4475:226449] 新方法
2020-02-27 15:54:47.515193+0800 SwizzleMethod[4475:226449] 原方法
2020-02-27 15:54:47.515261+0800 SwizzleMethod[4475:226449] 原方法

通过结果可见,我们成功地利用方法交换技术修改了方法的调用,避免了循环调用的问题。

Method Swizzling技术,我们可以在用户无感知的情况下拦截某个方法并进行统计处理。

3. Cydia Substrate

Cydia Substrate

Cydia Substrate地址: Cydia Substrate

To install Substrate, you will need to "jailbreak" your device, as making 

changes to other software is not something that Apple normally allows.

要安装Substrate,你需要“jailbreak”你的设备,因为修改其他软件不是苹果通常允许的。

Depending on your iOS version and device, you will need to use one of a 

few different jailbreaking tools such as redsn0w or evasi0n.

根据你的iOS版本和设备,你需要使用一些不同的越狱工具,如redsn0w或evasi0n。

The various jailbreaking tools install Cydia Installer, which you can then 

use to install Substrate and any of thousands of Substrate extensions.

各种越狱工具安装Cydia安装程序,然后您可以使用它们来安装Substrate和数千个Substrate扩展中的任何一个。

  • Cydia Substrate
    针对OC方法,C函数以及函数地址进行HOOK操作.从上图可以看到,Android和iOS都可以使用.

1. MobileHooker

MobileHooker 替换系统函数

void MSHookMessageEx(Class _class, SEL message, IMP hook, IMP *old);

void MSHookFunction(void *symbol, void *hook, void **old);

  • MSHookMessageEx 主要作用于OC函数,Logos语法主要是对MSHookFunction函数进行了封装.

  • 关于Logos语法的文章在这里: iOS逆向之Logos语法介绍,大家可以了解一下.

  • MSHookFunction 主要作用于C和C++函数

2. MSHookMessageEx的使用

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    MSHookMessageEx([NSObject class], @selector(description), &newDescription, &oldDescription);
}

NSString * (* oldDescription)(id self , SEL _cmd);

NSString *newDescription(id self, SEL _cmd){
    
    NSString * description = (*oldDescription)(self,_cmd);
    
    description = [description stringByAppendingString:@"!"];
    
    return description;

}

我们首先创建oldDescription 用于保存原来的NSString类description方法的地址,通过实现新的newDescription.
最后通过MSHookMessageEX函数替换原来的description方法,实现Hook.

刚才有提到,其实Logos语法是对MSHookMessageEx函数的封装.

3. MSHookFunction

MSHookFunction函数的作用对象是C,C++函数,然后C,C++并不提供runtime这种高级的API,所以我们想HOOK更加困难.

void MSHookFunction(void *symbol, void *hook, void **old);

  • MSHookFunction 三个参数分别是 替换的原函数,替换函数,MobileHooker保存的原函数.
void (*oldFunction)(void);

void newFunction(void){
    
    MSImageRef image = MSGetImageByName("");
    
    void * symbol = MSFindSymbol(image, "symbol");
    
    if (symbol) {
        
        MSHookFunction((void *)symbol, (void *)&newFunction,(void **)&oldFunction);
        
    }else{
        
        NSLog(@"没有symbol");
    }
    
}

我们通过定义原方法用户保存要HOOK函数被替换的指令,

接着实现新的newFunction方法,使用MSHookFunction来对修改的函数进行Hook.

4. MobileLoader

MobileLoader 加载第三方dylib在运行的应用程序中.

4.1 MobileLoader主要是系统启动时由Launchd进程将Mobileloader加载进内存

4.2 Moblieloader会通过环境变量(DYLD_INSERT_LIBRARIES)将自己加载进设备各个进程

4.3 并遍历 /Library/MobileSubstrate/DynamicLibraries/目录下的文件,如下图


4.4 每个dylib及plist文件来确定dylib的作用范围.如果当前进程满足该作用范围,则会使用dlopen函数加载对应的dylib.

5. SafeMode

注入应用进程,修改应用的逻辑存在一定风险.因为寄生在应用进程中,系统进程很容易造成崩溃.如果崩溃的是SpringBoard等系统进程,则会造成系统瘫痪.

我们可以在安全模式下进行第三方插件的禁用,卸载,从而帮助系统修复.

4.Fishhook

fishhook地址

注意

本篇文章不会过多介绍Fishhook的内容,下一篇文章将会专门针对Fishhook进行详细介绍。

总结

  • 1. 本篇文章主要介绍了HOOK的原理。

  • 2. 我们探讨了三种通过HOOK实现的方式:Method Swizzle(利用runtime机制进行hook)、Cydia Substrate和FishHook。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351