2019-06-26 06:11:58 亲,请 登录 或者 注册
新闻主页 国内新闻 国外新闻 民生资讯 社会动态 各地新闻 经济资讯 时证要闻
 
当前位置:: 瞬间新闻网 >> 各地新闻 >> 利用Objective 内容
利用Objective
来源:瞬间新闻网 时间:2015-12-23   点击发表评论


方法一,hook已有公开头文件的类:

首先写一个Utility函数:

#importobjc/runtime.h

voidexchangeMethod(ClassaClass,SELoldSEL,SELnewSEL)
MethodoldMethod=class_getInstanceMethod(aClass,oldSEL);
assert(oldMethod);
MethodnewMethod=class_getInstanceMethod(aClass,newSEL);
assert(newMethod);
method_exchangeImplementations(oldMethod,newMethod);
}

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

-(void)webView:(id)arg1didFinishLoadForFrame:(id)arg2;

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

@interfaceUIWebView(Hook)

+(void)hook;
-(void)hook_webView:(id)arg1didFinishLoadForFrame:(id)arg2;
@implementationUIWebView(Hook)
+(void)hook
//hookUIWebView中表示一个HTML的frame加载完毕的函数
exchangeMethod([UIWebViewclass],
@selector(webView:didFinishLoadForFrame:),
@selector(hook_webView:didFinishLoadForFrame:));
-(void)hook_webView:(id)arg1didFinishLoadForFrame:(id)arg2
//因为交换了selector和implementation的映射,原样调一下本函数实际会调用被hook的函数。
[selfhook_webView:arg1didFinishLoadForFrame:arg2];
NSLog(@webView:didFinishLoadForFrame:
}
在程序启动的时候调用一下[UIWebViewhook]即可。使用一个UIWebView打开一个网页,即会打印NSLog。


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

-(void)webView:(id)arg1didFinishLoadForFrame:(id)arg2;
嗯,是的,这个函数和UIWebView的一样,实际上就是UIWebBrowserView会再调用通知到UIWebView的同名函数。
创建一个类,不要与被hook的类同名,例如加了个Hook后缀:
@interfaceUIWebBrowserViewHook:NSObject

+(void)hook;
-(void)hook_webView:(id)arg1didFinishLoadForFrame:(id)arg2;
@end
其中以hook_为前缀的新增函数的实现与方法一中相同,差别在类函数中:
@implementationUIWebBrowserViewHook

+(void)hook
ClassaClass=objc_getClass(UIWebBrowserView
SELsel=@selector(hook_webView:didFinishLoadForFrame:);
//为UIWebBrowserView增加函数
class_addMethod(aClass,sel,class_getMethodImplementation([selfclass],sel),v@:@@
//交换实现
exchangeMethod(aClass,@selector(webView:didFinishLoadForFrame:),sel);
}
在程序启动的时候调用一下[UIWebBrowserViewHookhook]即可。使用一个UIWebView打开一个网页,即会打印NSLog。


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

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

@interfaceUIWebBrowserViewHook:NSObject

+(void)hook;
-(void)webView:(id)arg1didFinishLoadForFrame:(id)arg2;
@end
需要用到另一个Utility函数:
inlinevoidreplaceImplementation(ClassnewClass,ClasshookedClass,SELsel,IMPoldImp)

Methodold=class_getInstanceMethod(hookedClass,sel);
IMPnewImp=class_getMethodImplementation(newClass,sel);
oldImp=method_setImplementation(old,newImp);
}

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

下面是实现:

@implementationUIWebBrowserViewHook

staticIMPwebView_didFinishLoadForFrame=NULL;
+(void)hook
ClasshookedClass=objc_getClass(UIWebBrowserView
SELsel=@selector(webView:didFinishLoadForFrame:);
replaceImplementation([selfclass],hookedClass,sel,webView_didFinishLoadForFrame);
-(void)webView:(id)arg1didFinishLoadForFrame:(id)arg2
//需要这样来调用被替换掉的原实现
webView_didFinishLoadForFrame(self,@selector(webView:didFinishLoadForFrame:),arg1,arg2);
NSLog(@webView:didFinishLoadForFrame:
@end
在程序启动的时候调用一下[UIWebBrowserViewHookhook]即可。使用一个UIWebView打开一个网页,即会打印NSLog。


三种方法的比较:

最方便的当然是第一种,但需要是hook有公开头文件的类。

方法二和方法三都新建了一个类,方法二需要描述selector的types,这个比较麻烦,如例子中的v@:@@表示返回值为void,第一和第二个参数都是id。方法三不用types,但要增加全局变量。


Objective-C的runtime参考资料:
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008048



email:hursing@163.com

weibo:@hursing

微信:(干IT的应该都能猜出来)

QQ:(比上面那个动多点脑筋还是能找到的)

程序员内部培训

hursing:
@wy5761:感觉不能完全依赖公司文化。公司大到一定程度,会招收很多的应届生,不能指望他们一来就很...



程序员内部培训

wy5761:
赞!写的很好!对于培训,也许有总比没有好,不过效果就难说了。优秀的程序员、优秀的团队肯定不是培训出来...



利用Objective-C运行时hook函数的三种方法

hursing:
@u012005181:经过测试确实是这样。.m文件不能用inline。我把原本的inline删掉就...



程序员内部培训

HorkyChen:
赞!写得很好!公司由小及大,开始遇到问题时,见神杀神,实在杀不掉就绕着走,都是直接的从解决问题的术的...



程序员内部培训

hursing:
@u011731233:嗯,解bug能力是锻炼出来的,包含基础知识和思维方式,后者很难培训出来。这是...



程序员内部培训

u011731233:
就算有些简单的培训也远远不够应付实际开发中遇到的各种bug。人家用码农来贬低程序员,其实当程序员要求...



IDA反汇编/反编译静态分析iOS模拟器程序(九)block

yinhanmsn:
@hursing:恩,感谢大神指导。同时也希望大神有时间能出篇C++stripsymbol的文章...



IDA反汇编/反编译静态分析iOS模拟器程序(九)block

hursing:
@yinhanmsn:只要是objC写的代码,类名函数名变量名都会看得到,跟block没关系,除非你...






 
推荐新闻
 
 
手机浏览
瞬间新闻网 Total 0.067446(s) query 6, 报料QQ:点击这里给我发消息