乐于分享
好东西不私藏

[iOS逆向] deb插件Tweak开发 – Logos语法

[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后要处理的方式1 return %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文件参与代码的执行。