在利用theos开发一些插件时,我们经常会用到以下几个指令:
%hook 指定需要hook的类名,以%end结尾
//hook的是SpringBoard这个类里面的方法 %hook SpringBoard -(void)_menuButtonDown:(id)down { NSLog(@"You've pressed home button"); %orig; //call the original _menuButtonDown } %end
%orig 执行被hook函数的原始代码,类似于super.method功能
%hook ClassName - (void) _menuButtonDown: (id)down { NSlog(@"ss"); //如果去掉%orig,那么原始函数不会得到执行。 %orig; } @end
%new 该指令用来给现有的class添加一个新的函数。与Runtime中的class_addMethod相同。
%hook SpringBoard //hook内部的代码 默认都是替换被hook类中函数的实现,所以如果不加%new,theos默认是去类中找namespaceNewMethod这个方法,替换它的方法实现。所以如果我们是新增的函数而不是更改原函数的内部实现则需要加%new这个指令 %new -(void) namespaceNewMethod { NSlog(@"你好"); } @end
%log 用来打印log的,将信息输入到syslog中,可以以%log([(<type>)<expr>,...])的格式追加其打印信息,如下:
%hook SpringBoard -(void) _menuButtonDown :(id)down { %log((NSString * )@"IOSER",(NSString *)@"Debug"); %orig; } @end
%group 该指令用于将%hook分组,便于代码管理及按条件初始化分组,必须以%end结尾:一个%group可以包含多个%hook,所有不属于某个自定义group的%hook会被隐式归类到%group _ungrounped中,%gruop的用法如下:
1 //这段代码的含义为在%group iOS7hook中勾住了iOS7Class的iOS7Method,同理在iOS8Class的iOS8Method。然后在%group _ungrouped中勾住SpringBoard类的powerDown函数。 2 3 %group iOS7Hook 4 %hook iOS7Class 5 -(id) iOS7Method 6 { 7 8 id result = %orig; 9 NSlog(@"This class & method only exist in ios 8."); 10 return result; 11 } 12 @end 13 @end // iOS7Hook 14 15 16 %group iOS8Hook 17 %hook iOS8Class 18 -(id) iOS8Method 19 { 20 21 id result = %orig; 22 NSlog(@"This class & method only exist in ios 8."); 23 return result; 24 } 25 @end 26 @end // iOS8Hook 27 28 29 //所有不属于某个自定义group的%hook会被隐式归类到%group _ungrounped 所以其实下面powerDown函数其实是属于group_ungrounped 组的 30 %hook SpringBoard 31 -(void) powerDown 32 { 33 %orig; 34 } 35 @end 36 37 //%ctor: tweak 的constructor ,完成初始化工作;如果不是显示定义,theos会自动生成一个一个%ctor并在其中调用%init(_ungrouped)。默认只会自动初始化_ungrouped,不会初始化自定义的group 38 %ctor { 39 //只有调用了%init,对应的%group才能起作用、 40 %init(iOS7Hook); 41 %init(iOS8Hook); 42 43 //默认组 44 %init(_ungrouped); 45 }