LOGOS语法

初始化函数

%init 
%init([<class>=<expr>, …])
%init(Group[, [+|-]<class>=<expr>, …])

初始化一个组,如果没有参数表示初始化’_ungrouped’组.

代码块指令
这类指令定义HOOK代码块,必须以%end结束.

%hook class

对类设置钩子,这一行只是说明hook块的开始,并没有真正设置钩子,theos使用objc_getClass(Classname)获取要被HOOK的类,在%hook和%end之间编写代理函数,对于钩子的安装,Theos使用MSHookMessageEx(Class class, SEL selector, IMP replacement, IMP *result)完成,这些对我们来说是透明的,我们不需要手动调用,Logos预处理器会自动生成这些代码.

例子:

%hook SBApplicationController

-(void)uninstallApplication:(SBApplication *)application {
    NSLog(@”Hello World!”);
    %orig; // 调用原始方法
    return;
}

%end //结束标记

预处理后为:

//先获取类对象,对应%hook SBApplicationController
Class _logos_class$initGroup$SBApplicationController = objc_getClass(“SBApplicationController”);

//设置hook
MSHookMessageEx(
_logos_class$initGroup$SBApplicationController, //要hook的类
@selector(uninstallApplication), //要hook的函数
(IMP)&_logos_method$initGroup$SBApplicationController$uninstallApplication, //代理函数
(IMP*)&_logos_orig$initGroup$SBApplicationController$uninstallApplication); //存储原始函数

%subclass
%subclass Classname: Superclass <Protocol, Protocol>

为现有的类(Supercalss)添加子类,这个动作在运行时创建并填充.
theos使用objc_allocateClassPair()再调用objc_registerClassPair()完成子类的添加功能.

%group
%group Groupname

这是为hook块分组,,由于有些类在一些特殊条件下才会被初始化,一如果在Tweaks初始化时就去设置钩子,肯定是失败的,所以我们也可以在特定条件下init,比如hook一些不常驻内存的类,再或者在不同的IOS版本中hook不同的函数.有些简单的Tweaks并没有显式声明%group,其实Theos也提供了一个默认的组叫”ungrouped”,所有未被分组的hook都会被设置到这个组里,默认在%ctor函数里面调用.

%new
%new(signature)

为类或子类添加一个新的方法.必须在%hook块或%subclass块使用.theos使用class_addMethod完成.

%ctor
%ctor { … }

这是Theos提供的默认构造函数(默认优先级),当然我们可以编写自己的构造函数让Theos来调用,但是自定义的%ctor函数里面必须手动调用%init对%group自定义的组进行初始化.

%end

表示一个钩子/子类/组作用块的结束

%c
%c([+|-]Class)

动态获取一个类,如果用’+’标记,则获取类的对象,如果用’-’标记则获取实例对象,默认是’-’
%c在经过Logos预处理后变为_logos_static_class_lookup(classname),其实内部还是调用objc_getClass(classname)

%orig
%orig(arg1,arg2,arg3)

调用被hook的原始函数,这个函数不能用在%new创建的函数中.

%log
%log([(<type>)<expr>, …])

打印函数的参数.

Logos的文件扩展名

.x 由Logos处理,然后预处理并编译成object-c
.xm 由Logos处理,然后预处理并编译为objective-c++
.xi 先处理为objective-c,然后Logos处理返回结果最后被编译
.xmi 先处理为objective-c++
默认情况下,Logos的预处理器只在生成时处理.xm文件,不过,有时一个hook代码可能要用在多个文件里.首先把主文件名改为.xmi文件,其他的.xm文件可以使用#include命令,Logos在预处理之前会将这些文件添加到主文件中.

%group SSGroup
%hook SSDownloadAsset
– (NSString *)downloadFileName 
{ 
    %log; 
    NSString * r = %orig; 
    NSLog(@” = %@”, r); 
    return r; 
}
+ (id)assetWithURL:(id)url type:(int)type 
{ 
    %log; 
    id r = %orig; 
    NSLog(@” = %@”, r); 
    return r; 
}

%end //%hook
%end //%group

添加新评论

返回顶部