发新帖

ios逆向工程-Method Swizzling

[复制链接]
3088 0
本帖最后由 dark1090 于 2015-9-7 20:48 编辑

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




举报 使用道具

回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表