文档章节

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

余成海
 余成海
发布于 2015/05/06 16:37
字数 836
阅读 7112
收藏 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了!

© 著作权归作者所有

共有 人打赏支持
余成海
粉丝 61
博文 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
0
0
iOS逆向工程- 学习整理(工具详解)

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

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

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

_小迷糊
10/26
0
0
《 iOS 应用逆向工程》作者沙梓社专访:运用逆向工程思维来优化自己的产品

小编语 本文为 DevLink 专访系列,本期采访嘉宾是 iDev 苹果开发者大会 iOS 逆向工程讲师——沙梓社。在即将到来的 iDev 大会上,他将和大家分享对逆向工程的理解,以此激发大家的思路和灵感...

DevLink
2016/10/21
154
1
iOS逆向工程

最近在看一本书叫《iOS逆向工程》,走appStore的开发都是正向开发,iOS逆向工程挺有意思的。但是现在还说不好。学习中ing.

peanut_iOS
2015/07/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周五乱弹 —— 这就是不要女朋友的理由

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @狄安娜的猫 :分享丁家鑫的单曲《丁家鑫 - 克罗地亚狂想曲 - 古筝remix》 《丁家鑫 - 克罗地亚狂想曲 - 古筝remix》 手机党少年们想听歌,请...

小小编辑
24分钟前
124
6
CentOS配置Tomcat监听80端口,虚拟主机

Tomcat更改默认端口为80 更改的配置文件是: /usr/local/tomcat/conf/server.xml [root@test-a ~]# vim /usr/local/tomcat/conf/server.xml # 找到 Connector port="8080" protocol="HTTP/1......

野雪球
今天
5
0
《稻盛和夫经营学》读后感心得体会3180字范文

《稻盛和夫经营学》读后感心得体会3180字范文: 一代日本经营之圣稻盛和夫凭借刻苦勤奋的精神以及深植于佛教的商业道德准则,成为了“佛系”企业家的代表人物。在《稻盛和夫经营学》“领导人...

原创小博客
今天
4
0
java框架学习日志-5(常见的依赖注入)

依赖注入(dependency injection) 之前提到控制反转(Inversion of Control)也叫依赖注入,它们其实是一个东西,只是看的角度不同,这章详细说一下依赖注入。 依赖——指bean对象创建依赖于...

白话
今天
5
0
红外接收器驱动开发

背景:使用系统的红外遥控软件没有反应,然后以为自己接线错误,反复测试,结果烧坏了一个红外接收器,信号主板没有问题。所以自己开发了一个红外接收器的python驱动。接线参见https://my.os...

mbzhong
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部