ios逆向工程-内部钩子(Method Swizzling)
Method Swizzling(方法调配)
怎么说呢,先了解什么是钩子为什么用钩子,学过C++的朋友应该清楚,hook就是用来获得(截断/改变)底层调用的方法。这样我们可以自由的修改或者读取一些想要的东西。(个人理解)
下面是百度百科的解释:钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件
那ios中我们就用Method Swizzling来实现,为什么说是内部钩子呢,因为需要在工程里实现,我改天会分享外部的。
----------------------------------------------凌乱的分割线------------------------------------------
先了解一下SEL和IMP的概念,
SEL可以理解为函数名的意思,我们常用的@selector()就是通过字符串获得SEL
IMP可以理解成函数指针的意思,是能正确读取到函数的内容
一般是这样的:盗个图

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

如果在执行完IMPn后还想继续调用IMPc的话,只需要在IMPn中调用selectorN就行了。
---------------------------------------------凌乱的分割线----------------------------------------
具体怎么做呢:
|
1
|
Method origMethod = class_getInstanceMethod(class, origSelector); //获取SEL的Method |
Method是一个结构体,我们想要的IMP就在里面,看看结构
|
1
2
3
4
5
|
struct objc_method { SEL method_name OBJC2_UNAVAILABLE; char *method_types OBJC2_UNAVAILABLE; IMP method_imp OBJC2_UNAVAILABLE;} |
|
1
|
IMP origIMP = method_getImplementation(origMethod); //获取Method中的IMP |
ok,IMP获取到了,连接SEL到别的IMP呢
|
1
2
|
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types); //先增加新方法名SEL+原来的IMPIMP method_setImplementation(Method m, IMP imp); //然后将原来的method(SEL)重新分配新的IMP |
|
1
|
void method_exchangeImplementations(Method m1, Method m2) //或者可以使用method的交换方法 |
---------------------------------------------凌乱的分割线-------------------------------------
实战,假设我们想知道app跳转都传送了什么值(如应用调用QQ分享什么的),那么我们可以勾取UIApplication的OpenUrl方法
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#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的交换方法实现:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#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 |
--------------------------------------------------------------------
另外再加一点,假如你只是想重写类的某些方法,分类也是不错的选择,分类一旦加入工程,不需要包含头文件有会生效,所以请慎重使用
|
1
2
3
4
5
6
7
8
|
@implementation UIApplication (test)- (BOOL)openURL:(NSURL*)url { NSLog(@"!!!!!%@", [url absoluteString]); return YES;}@end |
当然你没办法重新在掉回原来的IMP了!
ios逆向工程-内部钩子(Method Swizzling)的更多相关文章
- iOS中AOP与Method Swizzling 项目中的应用
引子:项目中需要对按钮点击事件进行统计分析,现在项目中就是在按钮的响应代码中添加点击事件,非常繁琐.所以使用了AOP(面向切面编程),将统计的业务逻辑统一抽离出来. 项目中添加的开源库:https:/ ...
- ios逆向工程
原 ios逆向工程-内部钩子(Method Swizzling) Method+Swizzling ios hook Method Swizzling(方法调配) 怎么说呢,先了解什么是钩子为什么 ...
- 【原】iOS动态性(三) Method Swizzling以及AOP编程:在运行时进行代码注入
概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为“移花接木 ...
- iOS运行时与method swizzling
C语言是静态语言,它的工作方式是通过函数调用,这样在编译时我们就已经确定程序如何运行的.而Objective-C是动态语言,它并非通过调用类的方 法来执行功能,而是给对象发送消息,对象在接收到消息之后 ...
- IOS 开发之 Method Swizzling + Category
ios 分类中如果增加的方法与被扩展的类方法名重复,则原方法就没法被调用….看以下例子 例如: @interface ClassA : NSObject - (NSString *) myMethod ...
- iOS 使用Method Swizzling隐藏Status Bar
在iOS 6中,隐藏Status Bar很的简单. // iOS 6及曾经,隐藏状态栏 [[UIApplication sharedApplication] setStatusBarHidden:YE ...
- iOS执行时与method swizzling
C语言是静态语言,它的工作方式是通过函数调用,这样在编译时我们就已经确定程序怎样执行的.而Objective-C是动态语言,它并不是通过调用类的方法来执行功能,而是给对象发送消息,对象在接收到消息之后 ...
- IOS 开发之 Method Swizzling
ios 分类中如果增加的方法与被扩展的类方法名重复,则原方法就没法被调用….看以下例子 例如: @interface ClassA : NSObject - (NSString *) myMethod ...
- ios method swizzling
阅读器 iOS开发iOS 本文由TracyYih[博客]翻译自NSHipster的文章Method Swizzling. 在上周associated objects一文中,我们开始探索Ob ...
随机推荐
- spark SQL学习(案例-统计每日销售)
需求:统计每日销售额 package wujiadong_sparkSQL import org.apache.spark.sql.types._ import org.apache.spark.sq ...
- Python学习札记(十) Function1 函数调用
参考:调用函数 Note 1.Python内置了很多函数,我们可以直接对这些函数进行调用.Python官网:Built in Fuctions eg.调用abs函数(取绝对值函数): >> ...
- LA 5135 井下矿工(点—双连通分量模板题)
https://vjudge.net/problem/UVALive-5135 题意:在一个无向图上选择尽量少的点涂黑,使得任意删除一个点后,每个连通分量至少有一个黑点. 思路: 首先dfs遍历求出割 ...
- spring 或 springboot统一异常处理
spring 或 springboot统一异常处理https://blog.csdn.net/xzmeasy/article/details/76150370 一,本文介绍spring MVC的自定义 ...
- 创建node.js,blog
terminal npm init //创建项目 npm install --save express //安装 express 模块 npm install --save body-parser / ...
- LM3S之boot loader学习笔记-1
LM3S之boot loader学习笔记-1 彭会锋 (首先声明,此系列文章编写参考了很多资料,其中一些内容是原版内容的引用和整理,并加入了一些自己的见解,我已经尽量标明引用部分,如有未全部标注部分, ...
- 什么情况下用resultType和 resultMap
MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap 那什么情况下用resultType? resultMap 一般用在什么情况下? 如 ...
- Shell_NotifyIcon托盘图标闪烁
之前的同事留下了一个程序会莫名闪退的bug,今天终于发现是托盘图标闪烁使得gdi资源耗尽导致的. 先定义 #include "shellapi.h" //托盘图标引用 NOTIFY ...
- pycharm debug
1 debug 的模式,只有在打断点是才能运行. 2 主方法运行的时候 ,可以在下面输入一行 a =1 .方便debug 打完断电的会出现三角头, 运行甲壳虫 3 一步一步运行, F8 , 当 ...
- 连接GitHub的方法
连接到GitHub 首先在本地创建 ssh key: ssh-keygen -t rsa -C "your_email@youremail.com" 后面的 your_email@ ...