美文网首页
hook函数的三种方法

hook函数的三种方法

作者: 00d1ed2b53ae | 来源:发表于2018-10-11 09:53 被阅读10640次

方法一

hook已有公开头文件的类:

首先写一个Utility函数:

#import <objc/runtime.h>
void exchangeMethod(Class aClass, SEL oldSEL, SEL newSEL){    
Method oldMethod = class_getInstanceMethod(aClass, oldSEL);    
assert(oldMethod);    
Method newMethod = class_getInstanceMethod(aClass, newSEL);    
assert(newMethod);    
method_exchangeImplementations(oldMethod, newMethod);
}

现在,目标是hook UIWebView没公开的函数

- (void)webView:(id)arg1 didFinishLoadForFrame:(id)arg2;

因为已知类的声明,所以可以使用category:

@interface UIWebView (Hook)+ (void)hook;
- (void)hook_webView:(id)arg1 didFinishLoadForFrame:(id)arg2;
@end
@implementation 
UIWebView (Hook)+ (void)hook{   
 // hook UIWebView中表示一个HTML的frame加载完毕的函数    
exchangeMethod([UIWebView class],                   @selector(webView:didFinishLoadForFrame:),                   @selector(hook_webView:didFinishLoadForFrame:));
}
- (void)hook_webView:(id)arg1 didFinishLoadForFrame:(id)arg2{    
// 因为交换了selector和implementation的映射,原样调一下本函数实际会调用被hook的函数。    
[self hook_webView:arg1 didFinishLoadForFrame:arg2];    
NSLog(@"webView:didFinishLoadForFrame:");
}

在程序启动的时候调用一下 [UIWebView hook] 即可。使用一个UIWebView打开一个网页,即会打印NSLog。

方法二

hook没有公开头文件的类,需要另建一个类作为新函数载体,然后先为被hook的类增加函数,再替换。UIWebView体系中有一个类叫UIWebBrowserView,它是真正显示网页的UIView,并有部分函数是作为WebCore向外发送回调信息的接收者。现我们去hook UIWebBrowserView的这个函数:

- (void)webView:(id)arg1 didFinishLoadForFrame:(id)arg2;

嗯,是的,这个函数和UIWebView的一样,实际上就是UIWebBrowserView会再调用通知到UIWebView的同名函数。
创建一个类,不要与被hook的类同名,例如加了个Hook前缀:

@interface UIWebBrowserViewHook : NSObject
+ (void)hook;
- (void)hook_webView:(id)arg1 didFinishLoadForFrame:(id)arg2;
@end

其中以hook_为前缀的新增函数的实现与方法一中相同,差别在类函数中:

@implementation UIWebBrowserViewHook+ (void)hook{    
Class aClass = objc_getClass("UIWebBrowserView");    
SEL sel = @selector(hook_webView:didFinishLoadForFrame:);    
// 为UIWebBrowserView增加函数    
class_addMethod(aClass, sel, class_getMethodImplementation([self class], sel), "v@:@@");   
 // 交换实现    
exchangeMethod(aClass, @selector(webView:didFinishLoadForFrame:), sel);
}

在程序启动的时候调用一下 [UIWebBrowserViewHook hook] 即可。使用一个UIWebView打开一个网页,即会打印NSLog。

方法三

hook没有公开头文件的类,另建一个类作为新函数载体,用新函数替换旧函数,并把旧函数保存到静态变量里:

继续以UIWebBrowserView为例子。注意新函数可以与被hook的函数同名

@interface UIWebBrowserViewHook : NSObject
+ (void)hook;
- (void)webView:(id)arg1 didFinishLoadForFrame:(id)arg2;
@end

需要用到另一个Utility函数:

inline void replaceImplementation(Class newClass, Class hookedClass, SEL sel, IMP& oldImp){    
Method old = class_getInstanceMethod(hookedClass, sel);    
IMP newImp = class_getMethodImplementation(newClass, sel);  
oldImp = method_setImplementation(old, newImp);}

当两个selector不同名时,以上函数再增加一个参数即可。

下面是实现:

@implementation UIWebBrowserViewHookstatic IMP webView_didFinishLoadForFrame = NULL;+ (void)hook{    
Class hookedClass = objc_getClass("UIWebBrowserView");    
SEL sel = @selector(webView:didFinishLoadForFrame:);    
replaceImplementation([self class], hookedClass, sel, webView_didFinishLoadForFrame);
} 
- (void)webView:(id)arg1 didFinishLoadForFrame:(id)arg2{    
// 需要这样来调用被替换掉的原实现    
webView_didFinishLoadForFrame(self, @selector(webView:didFinishLoadForFrame:), arg1, arg2);    
NSLog(@"webView:didFinishLoadForFrame:");
}
@end

在程序启动的时候调用一下 [UIWebBrowserViewHook hook] 即可。使用一个UIWebView打开一个网页,即会打印NSLog。三种方法的比较:最方便的当然是第一种,但需要是hook有公开头文件的类。方法二和方法三都新建了一个类,方法二需要描述selector的types,这个比较麻烦,如例子中的"v@:@@"表示返回值为void,第一和第二个参数都是id。方法三不用types,但要增加全局变量。

相关文章

  • 遍历hook Dex中的类

    创建DexFile 遍历拿出所有类名 找到类对象,进行hook hook构造函数 hook方法 打印hook方法中的日志

  • hook函数的三种方法

    方法一 hook已有公开头文件的类: 首先写一个Utility函数: 现在,目标是hook UIWebView没公...

  • 方法hook和函数hook

    1.方法hook 先上代码 一个方法对应一个sel和imp,方法A的imp指针和方法B的imp指针进行了替换,并且...

  • netfilter hook函数

    HOOK函数注册 上图是netfilter中注册的部分hook函数.这些hook函数是通过 nf_register...

  • JavaScript函数定义和方法介绍

    一.函数定义三种方法 函数的三种定义方法分别是:函数声明、函数表达式和Function()构造函数的方法。下面依次...

  • Mach-O文件简介和fishhook原理解析

    利用runtime这个黑魔法可以hook Objective-c的方法。 如果有一个hook C语言函数的需求(比...

  • hook原理小结

    常用的hook方式主要有导入表hook、导出表hook和inline hook三种。 一,导入表hook 首先需要...

  • react中常见hook的使用方式与区别

    1、什么是hook?react hook是react 16.8推出的方法,能够让函数式组件像类式组件一样拥有sta...

  • Java回调

    回调callback 回调又称钩子函数 (hook), 模板方法, 利用对象的多态特性, 先定义函数结构, 再利用...

  • iOS 之 C 函数 Hook & MSHookFunc

    HOOK 是一个强大的东西,对于 iOS 来说可以很方便的 HOOK 到方法与函数。 近期发现,很多做逆向的小伙伴...

网友评论

      本文标题:hook函数的三种方法

      本文链接:https://www.haomeiwen.com/subject/khivaftx.html