[iOS逆向] deb插件Tweak开发 – Logos语法
iOS逆向-Logos语法大全
我的博客 https://xlsn0w.github.io/
插件开发指令会开辟一个代码块,以%end结束。
%group
用来将代码分组。开发中hook代码会很多,
这样方便管理Logos代码。所有的group都必须初始化,否则编译报错。

#import <UIKit/UIKit.h>%group group1%hook RichTextView- (_Bool)setPrefixContent:(id)arg1 TargetContent:(NSString *)arg2 TargetParserString:(id)arg3 SuffixContent:(id)arg4 {//hook后要处理的方式1return %orig;}%end%end%group group2%hook RichTextView- (_Bool)setPrefixContent:(id)arg1 TargetContent:(NSString *)arg2 TargetParserString:(id)arg3 SuffixContent:(id)arg4 {//hook后要处理的方式2return %orig;}%end%end%group group3%hook RichTextView- (_Bool)setPrefixContent:(id)arg1 TargetContent:(NSString *)arg2 TargetParserString:(id)arg3 SuffixContent:(id)arg4 {//hook后要处理的方式3return %orig;}%end%end//使用group要配合ctor%ctor {//[[UIDevice currentDevice] systemVersion].doubleValue 可以用来判断版本或其它逻辑。if ([[UIDevice currentDevice] systemVersion].doubleValue >= 11.0) {//这里group3会覆盖group1,不会执行group1逻辑。%init(group1)%init(group3);} else {%init(group2);}}
-
group初始化在%ctor中,需要%init初始化。
-
所有group必须初始化,否则编译报错。
-
在一个逻辑中同时初始化多个group,后面的会覆盖前面的。
-
在不添加group的情况下,默认有个_ungrouped组,会自动初始化。
%hookHOOK某个类里面的某个方法。%hook RichTextView- (_Bool)setPrefixContent:(id)arg1 TargetContent:(NSString *)arg2 TargetParserString:(id)arg3 SuffixContent:(id)arg4 {//hook后要处理的方式1return %orig;}%end%hook后面需要跟需要hook的类名。%new为某个类添加新方法,在%hook 和 %end 中使用。%hook RichTextView%new- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {}%end
%subclass
%subclass Classname: Superclass <Protocol list>
运行时创建子类,只能包含方法或者关联属性,不能包含属性。可以通过%c创建类实例。

#import <UIKit/UIKit.h>@interfaceMyObject- (void)setSomeValue:(id)value;@end%subclass MyObject : NSObject- (id)init {self = %orig;[self setSomeValue:@"value"];return self;}%new- (id)someValue {return objc_getAssociatedObject(self, @selector(someValue));}%new- (void)setSomeValue:(id)value {objc_setAssociatedObject(self, @selector(someValue), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}%end

%property
%property (nonatomic|assign|retain|copy|weak|strong|getter|setter) Type name;
为subclass或者hook的类添加属性。必须在 %subclass 或%hook中。
%property(nonatomic,assign) NSInteger age;
%end
与其它命令配对出现。
2.2、Top level
TopLevel指令不放在BlockLevel中。
%config
%config(Key=Value);
为logos设置标记。
Configuration Flags
|
key |
values |
notes |
|
generator |
MobileSubstrate |
生成的代码使用MobileSubstrate hook |
|
generator |
internal |
生成的代码只使用OC runtime方法hook |
|
warnings |
none |
忽略所有警告 |
|
warnings |
default |
没有致命的警告 |
|
warnings |
error |
使所有警告报错 |
|
dump |
yaml |
以YAML格式转储内部解析树 |
%
config(enerator=internal);
%config(warnings=error);
%config(dump=yaml);
%hookf
hook函数,类似fishhook。语法%hookf(rtype, symbolName, args...) { … }rtype:返回值。symbolName:原函数地址。args...:参数。示例FILE *fopen(const char *path, const char *mode);%hookf(FILE *, fopen, const char *path, const char *mode) {NSLog(@"Hey, we're hooking fopen to deny relative paths!");if (path[0] != '/') {return NULL;}return %orig;}%ctor构造函数,用于确定加载那个组。和%init结合用。%dtor析构,做一些收尾工作。比如应用挂起的时候。

2.3、Function level
这一块的指令就放在方法中
%init
用来初始化某个组。
%class
%class Class;
%class已经废弃了,不建议使用。
%c
类似getClass函数,获得一个类对象。一般用于调用类方法。
//只是为了声明编译通过
@interfaceMainViewController+ (void)HP_classMethod;@end%hook MainViewController%new- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {//方式一// [self.class HP_classMethod];//方式二// [NSClassFromString(@"MainViewController") HP_classMethod];//方式三[%c(MainViewController) HP_classMethod];}%new+ (void)HP_classMethod {NSLog(@"HP_classMethod");}%end
%c 中没有引号。
%orig
保持原有的方法实现,如果原来的方法有返回值和参数,
那么可以传递参数和接收返回值。
%hook RichTextView- (_Bool)setPrefixContent:(id)arg1 TargetContent:(NSString *)arg2 TargetParserString:(id)arg3 SuffixContent:(id)arg4 {//传递参数&接收返回值。BOOL result1 = %orig(arg1,arg2,arg3,arg4);BOOL result2 = %orig;return %orig;}%end

-
%orig可以接收返回值。
-
可以传递参数,不传就是传递该方法的默认参数。
%log
能够输出日志,输出方法调用的详细信息 。
%hook RichTextView- (_Bool)setPrefixContent:(id)arg1 TargetContent:(NSString *)arg2 TargetParserString:(id)arg3 SuffixContent:(id)arg4 {%log;return %orig;}%end

能够输出详细的日志信息,包含类、方法、参数、以及控件信息等详细信息。
总结
-
logos语法其实是CydiaSubstruct框架提供的一组宏定义。
-
语法
-
%hook,%end勾住某个类,在一个代码块中直接写需要勾住的方法。
-
%group,%end用于分组。
-
每一组都需要%ctor()函数构造。
-
通过%init(组名称)进行初始化。
-
%log输出方法的详细信息(调用者、方法名、方法参数)
-
%orig调用原始方法。可以传递参数,接收返回值。
-
%c类似getClass函数,获取一个类对象。
-
%new添加某个方法。
-
.xm文件代表该文件支持OC、C/C++语法。
-
编译该文件时需要导入头文件以便编译通过。.xm文件不参与代码的执行,编译后生成的.mm文件参与代码的执行。




夜雨聆风