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+原来的IMP
IMP 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)的更多相关文章

  1. iOS中AOP与Method Swizzling 项目中的应用

    引子:项目中需要对按钮点击事件进行统计分析,现在项目中就是在按钮的响应代码中添加点击事件,非常繁琐.所以使用了AOP(面向切面编程),将统计的业务逻辑统一抽离出来. 项目中添加的开源库:https:/ ...

  2. ios逆向工程

    原 ios逆向工程-内部钩子(Method Swizzling)   Method+Swizzling ios hook Method Swizzling(方法调配) 怎么说呢,先了解什么是钩子为什么 ...

  3. 【原】iOS动态性(三) Method Swizzling以及AOP编程:在运行时进行代码注入

    概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为“移花接木 ...

  4. iOS运行时与method swizzling

    C语言是静态语言,它的工作方式是通过函数调用,这样在编译时我们就已经确定程序如何运行的.而Objective-C是动态语言,它并非通过调用类的方 法来执行功能,而是给对象发送消息,对象在接收到消息之后 ...

  5. IOS 开发之 Method Swizzling + Category

    ios 分类中如果增加的方法与被扩展的类方法名重复,则原方法就没法被调用….看以下例子 例如: @interface ClassA : NSObject - (NSString *) myMethod ...

  6. iOS 使用Method Swizzling隐藏Status Bar

    在iOS 6中,隐藏Status Bar很的简单. // iOS 6及曾经,隐藏状态栏 [[UIApplication sharedApplication] setStatusBarHidden:YE ...

  7. iOS执行时与method swizzling

    C语言是静态语言,它的工作方式是通过函数调用,这样在编译时我们就已经确定程序怎样执行的.而Objective-C是动态语言,它并不是通过调用类的方法来执行功能,而是给对象发送消息,对象在接收到消息之后 ...

  8. IOS 开发之 Method Swizzling

    ios 分类中如果增加的方法与被扩展的类方法名重复,则原方法就没法被调用….看以下例子 例如: @interface ClassA : NSObject - (NSString *) myMethod ...

  9. ios method swizzling

      阅读器 iOS开发iOS   本文由TracyYih[博客]翻译自NSHipster的文章Method Swizzling.   在上周associated objects一文中,我们开始探索Ob ...

随机推荐

  1. [Pytorch]PyTorch使用tensorboardX(转

    文章来源: https://zhuanlan.zhihu.com/p/35675109 https://www.aiuai.cn/aifarm646.html 之前用pytorch是手动记录数据做图, ...

  2. mongodb可视化客户端下载

    网站:https://www.mongodbmanager.com/files/ 直接下载:https://www.mongodbmanager.com/files/mongodbmanagerpro ...

  3. springboot项目属性配置及注意事项

    在idea编辑器建的springboot项目中的resources包下的application.properties这个就是配置文件. 另外配置文件的文件名还可以是application.yml,在r ...

  4. IE类兼容一

    X-UA-Compatible是自从IE8新加的一个设置,对于IE8以下的浏览器是不识别的.通过在meta中设置X-UA-Compatible的值,可以指定网页的兼容性模式设置. 在网页中指定的模式优 ...

  5. Java String类为什么不可变?

    原文地址:# Why String is immutable in Java? 众所周知,String类在Java中是不可变的.不可变类简单地说是实例不可修改的类.对于一个实例创建后,其初始化的时候所 ...

  6. JSP 标准标签库(JSTL)

    JSP 标准标签库(JSTL) JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能. JSTL支持通用的.结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签, ...

  7. Dev-C++添加代码格式化(format source code)工具Artistic Style

    Dev-C++是一个轻便的C++ IDE开发环境,比起VS2010来轻巧得多.最新的版本是5.4.0是2013年2月14日发布的,下载地址如下: Dev-C++5.4.0 download 它是开源项 ...

  8. ArcMap加载在线地图

    SimpleGIS 小小的SimpleGIS除了提供6大地图让人喜爱之外,更有其他的能耐同样让你爱不释手. 功能1:作为出图底图地图提供商中Bing.天地图两家提供的地图是无偏移的地图,所以可直接应用 ...

  9. JS判断键盘上的上下左右键

    document.onkeydown=function(event){ var e = event || window.event || arguments.callee.caller.argumen ...

  10. CSS布局 — 圣杯布局与双飞翼布局

    圣杯布局 实现原理 html代码中,middle部分首先要放在container的最前部分,然后是left,right 将三者都设置 float:left, position:relative (因为 ...