文档章节

ios逆向工程-内部钩子(Method Swizzling)

余成海
 余成海
发布于 2015/05/06 16:37
字数 836
阅读 7193
收藏 7

Method Swizzling(方法调配)

怎么说呢,先了解什么是钩子为什么用钩子,学过C++的朋友应该清楚,hook就是用来获得(截断/改变)底层调用的方法。这样我们可以自由的修改或者读取一些想要的东西。(个人理解)

下面是百度百科的解释:钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件

那ios中我们就用Method Swizzling来实现,为什么说是内部钩子呢,因为需要在工程里实现,我改天会分享外部的。

----------------------------------------------凌乱的分割线------------------------------------------

先了解一下SEL和IMP的概念,

SEL可以理解为函数名的意思,我们常用的@selector()就是通过字符串获得SEL

IMP可以理解成函数指针的意思,是能正确读取到函数的内容

一般是这样的:盗个图

我们要做的就是把链接线解开,然后连到我们自定义的函数IMP上,如果有需要的话,我们再连回原来的IMP上

就是这样的:

如果在执行完IMPn后还想继续调用IMPc的话,只需要在IMPn中调用selectorN就行了。

---------------------------------------------凌乱的分割线----------------------------------------

具体怎么做呢:

Method origMethod = class_getInstanceMethod(class, origSelector);  //获取SEL的Method

Method是一个结构体,我们想要的IMP就在里面,看看结构

 struct objc_method {
    SEL method_name                                          OBJC2_UNAVAILABLE;
    char *method_types                                       OBJC2_UNAVAILABLE;
    IMP method_imp                                           OBJC2_UNAVAILABLE;
}
IMP origIMP = method_getImplementation(origMethod);  //获取Method中的IMP

ok,IMP获取到了,连接SEL到别的IMP呢

BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types);  //先增加新方法名SEL+原来的IMP
IMP method_setImplementation(Method m, IMP imp);                       //然后将原来的method(SEL)重新分配新的IMP
void method_exchangeImplementations(Method m1, Method m2) //或者可以使用method的交换方法


---------------------------------------------凌乱的分割线-------------------------------------

实战,假设我们想知道app跳转都传送了什么值(如应用调用QQ分享什么的),那么我们可以勾取UIApplication的OpenUrl方法

#import "KHookObjectWrapper.h"
#import "UIKit/UIKit.h"
#import <objc/objc.h>
#import <objc/runtime.h>

@implementation KHookObjectWrapper

+ (void)setup
{
    //openURL
    Method m = class_getInstanceMethod([UIApplication class], @selector(openURL:));
    class_addMethod([UIApplication class], @selector(hook_openURL:), method_getImplementation(m), method_getTypeEncoding(m));
    method_setImplementation(m, class_getMethodImplementation([self class], @selector(hook_openURL:)));
}

- (BOOL)hook_openURL:(NSURL *)url
{
    NSLog(@"hook_openURL:%@", [url absoluteString]);
    return [self hook_openURL:url];
}

使用method的交换方法实现:

#import "KHookObjectWrapper.h"
#import "UIKit/UIKit.h"
#import <objc/objc.h>
#import <objc/runtime.h>

@implementation KHookObjectWrapper

+ (void)setup
{
    //openURL
    Method m = class_getInstanceMethod([UIApplication class], @selector(openURL:));
    Method m2 = class_getInstanceMethod([self class], @selector(hook_openURL:));
    
    class_addMethod([UIApplication class], @selector(hook_openURL:), method_getImplementation(m), method_getTypeEncoding(m)); //为什么要有这句的,因为UIApplication没有hook_openURL方法会奔溃,大家觉得可以讲self的hook_openURL改名成openURL,大家可以试试,也是不行的
    
    method_exchangeImplementations(m, m2);
}

- (BOOL)hook_openURL:(NSURL *)url
{
    NSLog(@"hook_openURL:%@", [url absoluteString]);
    return [self hook_openURL:url];
}

@end


--------------------------------------------------------------------

另外再加一点,假如你只是想重写类的某些方法,分类也是不错的选择,分类一旦加入工程,不需要包含头文件有会生效,所以请慎重使用

@implementation UIApplication (test)

- (BOOL)openURL:(NSURL*)url {
    NSLog(@"!!!!!%@", [url absoluteString]);
    return YES;
}

@end

当然你没办法重新在掉回原来的IMP了!

© 著作权归作者所有

余成海
粉丝 62
博文 57
码字总数 29577
作品 0
杭州
iOS工程师
私信 提问
加载中

评论(1)

j
jack_rose
很不错的文章
one-stop-shop for all your method swizzling needs

JRSwizzle Description JRSwizzle is source code package that offers a single, easy, correct+consistent interface for exchanging Objective-C method implementations ("method swizzl......

mingxun
2014/04/27
58
0
iOS逆向工程- 学习整理(工具详解)

前言 一、逆向工程的要求 具备丰富的 iOS 开发经验 最好能非常熟悉 iOS 设备的硬件构成,iOS 系统的运行原理。 拿到任意一个 App 之后能够大致推断出它的项目规模和使用的技术,比如它的MVC模...

_小迷糊
2018/05/11
0
0
iOS逆向之旅(进阶篇) — HOOK(Method Swizzling)

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:656315826,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习...

_小迷糊
2018/10/26
0
0
iOS开发,我的2018进阶之路总结!

4G改变了生活,抓住机会的人已经在这个社会有了立足之地,马上迎来5G的时代,你做好准备了吗! 对于即将迎来的5G时代,无疑会是音视频的又一个高潮!那么作为程序员的我们,应该怎么样去迎接...

_小迷糊
01/08
0
0
iOS开发经验总结,我的2019进阶之路!

4G改变了生活,抓住机会的人已经在这个社会有了立足之地,马上迎来5G的时代,你做好准备了吗!对于即将迎来的5G时代,无疑会是音视频的又一个高潮!那么作为程序员的我们,应该怎么样去迎接它...

卓远
04/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

arcgis arcpy 克里金插值 掩膜 配置符号系统 自动生成图片

整体思路,最后要加载到mxd文件中,然后导出图片 首先加载mxd文件 mxd = mapping.MapDocument(r"./11.mxd") 然后读取数据 并加载到图层中 sr = arcpy.SpatialReference(4326) # 读取csv...

可达鸭Go
今天
4
0
漂亮有创意的思维导图模板分享

相信很多人使用在绘制思维导图时很喜欢使用模板进行编辑,它能够让你在短时间内快速创造出一个风格明显好看的思维导图,对绘制时间以及使用够感受影响都是较为深刻的,下面为大家分享几款漂亮...

干货趣分享
今天
4
0
使用js实现对cookie的增删改查

简单的操作cookie 存储cookie(key为test;value为testValue): document.cookie = "test=testValue"; 存储多个cookie: document.cookie = "test1=testValue1";document.cookie = "test2=te......

被毒打的程序猿_先瑞
今天
4
0
ApacheCN 公众号文章汇总 2019.9

ApacheCN 优质博文推荐计划正式启动 接受以下主题的博文: 人工智能(论文解读,比赛心得,面经,知识点讲解) 环材化生劝退 CS 留学申请,IT 外企求职 每日从所有投稿中精选两篇,在 Apache...

ApacheCN_飞龙
今天
5
0
Intellij Idea显示回退和前进按钮的方法

方法1:使用快捷键: 回到上一步 ctrl + alt + <-(左方向键) 回到下一步 ctrl + alt + ->(右方向键) 方法2:在界面显示: View -> 勾选ToolBar 方法3(推荐): (1)Preferences -> Ap...

孟飞阳
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部