Logos作为Theos开发组件的一部分,通过一组特殊的预处理指令,可以让编写函数钩子(hook)代码变得非常简单和清晰。
Logos提供的语法大大的简化了MobileSubstrate拓展程序(tweaks,能够hook系统中其他方法)的开发,这里所说的“Method hooking”是指通过替换或修改的方式改变其他应用中某些类的某些方法。
Logos是随着Theos发布的,你能够在用Theos创建的项目中直接使用Logos的语法。更多关于Theos的信息,请查看这里。
使用Logos
例子
下面是由logify.pl(/theos/bin/logify.pl)生成的一个非常简单的Logos tweak的例子
|
|
你可以使用logify.pl来创建一个头文件的Logos源文件,用来打印该头文件中所有函数:
|
|
Logos指令表
%init
|
|
用来初始化一个分组(group)或默认分组,如果不传参数会初始化“_ungrouped”分组,传 class=expr
参数会在指定类初始化的时候替换给定的表达式,+
号(作为Objective-C中类方法)在对应的类名中能够优先处理来替换元类的表达式,如果没有特别指定,默认标记是-
,只是替换当前类。
%hook
|
|
指定要hook的类,以%end结束。
|
|
%subclass
|
|
用于申明在运行时创建的类,支持方法,但暂时不支持成员变量。如果增加父类中不存在的方法,需要给这些方法指定%new标识。对象实例化时,你需要用到%c标识。
%group
|
|
开始一个hook分组,通常用于条件执行或代码组织。所有没有特别指定的%hook都被归为“_grouped”分组。
%new
|
|
为被hook的类或子类增加新的方法,功能与class_addMethod()
相同,signature
是新方法的类型编码(Objective-C type encoding),如果不指定,会自动生成一个。
%ctor
|
|
生成一个匿名构造函数(默认的优先级)。如果不指定,Theos会隐式定义:
|
|
作为tweak程序的入口,可以用于做一些其他初始化处理,如:
|
|
%end
|
|
结束%hook、 %subclass、 %group块。
%config
|
|
设置一个logos配置标记。
配置标记:
- generator
- MobileSubstrate
生成使用 MobileSubstrate来hook的代码。 - internal
生成只使用内置的Objective-C运行时函数来hook的代码。
- MobileSubstrate
- warnings
- none
忽略所有警告。 - default
报告非致命的警告。 - error
所有警告当做错误处理。
- none
- dump
- yaml
以YAML格式导出内部解析树。 - perl
以perl源码能处理的格式导出内部解析树。
- yaml
%c
|
|
在运行时获取一个类的定义,作用等同于objc_getClass()
,+
号获取元类,默认为-
号,获取当前类。
%orig
|
|
执行被hook函数的原始代码,不要在使用%new申明的方法中使用。奇怪的是能够在subclass中使用,因为MobileSubstrate在hook时会生成一个父调用闭包(supercall closure),如果所hook的函数在当前的类中不存在,就会调用父类的实现。参数会被传递给原始的函数,不用加self
和_cmd
,Logos已经帮你加了。
%log
|
|
默认将类名、函数名、参数等信息写入syslog,也可以追加其他信息。
|
|
Logos代码跨文件访问
默认情况下,Logos的预处理器在Build时只会处理一个 .xm 文件。然而,也可以实现将Logos hook代码分割到多个文件中。首先,主文件(通常为Tweak.xm)需要改为 .xmi 格式;然后可以在它里面使用#include
引入其他 .xm 文件。Logos的预处理器会在开始处理之前就将其他文件加到主文件,.xmi 会被优先处理。
Logos拓展名
Extension | Process order |
---|---|
.x | 先被Logos处理,然后被作为Objective-C预处理和编译 |
.xm | 先被Logos处理,然后被当做Objective-C++预处理和编译 |
.xi | 首先被当做Objective-C预处理,然后由Logos处理结果,最后被编译 |
.xmi | 首先被当做Objective-C++预处理,然后由Logos处理结果,最后被编译 |
xi 和 xmi 文件能够使用Logos指令作为 #define
宏进行预处理。
参考: