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 ...
随机推荐
- RabbitMQ入门(5)——主题(Topic)
前面我们介绍了通过使用direct exchage,改善了fanout exchange只能进行虚拟广播的方式.尽管如此,直接交换也有自身的局限,它不能基于多个条件路由. 在我们的日志系统中,也许我们 ...
- php中点击下载按钮后待下载文件被清空
在php中设置了文件下载,下载按钮使用表单的方式来提交 <form method="post" class="form-inline" role=&quo ...
- Jenkins Pipeline shell脚本用svn_revision当做系统版本号
1. 使用dir命令,进入发布目录,版本号所在文件夹. 2. 使用sed命令 修改替换版本号,这里使用vvvv作为要替换的版本号. 3. 最后一步可以不加.只是方便查看效果. stage(" ...
- spring boot 笔记--第三章
spring boot 笔记 第三章,使用Spring boot 构建系统: 强烈建议支持依赖管理的构建系统,Maven或Gradle 依赖管理: Spring Boot的每版本都会提供它支持的依赖列 ...
- switchhosts使用技巧
https://jingyan.baidu.com/article/1974b289a3cfd1f4b0f7744d.html
- 深入了解JavaScript中的Symbol的使用方法
这篇文章主要介绍了深入了解JavaScript中的Symbol的使用方法,本文针对ES6版本的JS进行讲解,需要的朋友可以参考下 Symbol 是什么? Symbols 不是图标,也不是指在代码中可以 ...
- python ssh登录
3. 编写linkssh.py #!/usr/bin/env python# -*- coding: utf-8 -*-# filename: pexpect_test.py'''Created on ...
- C++ 线程的创建、挂起、唤醒和结束 &&&& 利用waitForSingleObject 函数陷入死锁的问题解决
最近在写一个CAN总线的上位机软件,利用CAN转USB的设备连到电脑上,进行数据的传输.在接收下位机发送的数据的时候采用的在线程中持续接收数据. 1.在连接设备的函数中,开启线程. ,CREATE_S ...
- "".indexOf() "",replace(",","")的应用
自动化校验时,可能有些时候需要校验生成的值,如销售机会编号,每次生成时都是不一样的:所以我们需要提取出他们 assertTrue("SL17-001100".indexOf(dri ...
- Struts2中的包的作用描述
asm-3.3.jar作用:操作java字节码的类库包路径及主要类:未提供 asm-commons-3.3.jar作用:提供了基于事件的表现形式包路径及主要类:未提供 asm-tree-3.3.jar ...