logos 使用
官网可参考:链接
Logos语法其实是CydiaSubstruct框架提供的一组宏定义。便于开发者使用宏进行HOOK操作。语法简单,功能强大且稳定。
现在我们就实际项目开始尝试
新建一个项目,输入账号密码 登录
Main.storyboardViewController.m文件
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *uid;
@property (weak, nonatomic) IBOutlet UITextField *pwd;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)loginBtnClick:(id)sender {
if ([self.uid.text isEqualToString:@"123"]
&&[self.pwd.text isEqualToString:@"123456"]) {
NSLog(@"登录成功!");
}else{
NSLog(@"登录失败!");
}
}
好了,现在我们在手机上跑一遍 ,从Products中拷贝出.app文件备用
1.新建MonkeyApp项目
新建2.把 .app文件粘贴,运行项目(重签名)
3.找到对应写logos语法的文件
.xm文件>>>>>>>>>>>>>>>>>>>%hook --hook方法 需和 %end配合>>>>>>>>>>>>>>>>>>>>>
首先我们要Hook ViewController的 loginBtnClick方法
%hook ViewController
- (void)loginBtnClick:(id)sender{
NSLog(@"group1-成功");
}
%end
>>>>>>>>>>>>>>>>>>>%new -- 添加方法>>>>>>>>>>>>>>>>>>>>>
为某个类增加方法
%new
+(void)Login_classMethod{
NSLog(@"这是一个类方法");
}
%new
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"点击了屏幕");
}
>>>>>>>>>>>>>>>>>>>%group -- 分组 需和 %end配合>>>>>>>>>>>>>>>>>>>>>
用来将代码分组。开发中hook代码会很多,这样方便管理Logos代码。
%group group0
%hook ViewController
- (void)loginBtnClick:(id)sender{
NSLog(@"group0-成功");
}
%end
%end
%group group2
%hook ViewController
- (void)loginBtnClick:(id)sender{
NSLog(@"group2-成功");
}
%end
%end
>>>>>>>>>>>>>>>>>>>%ctor--构造函数,和%init结合使用>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>%init--用来初始化某个组>>>>>>>>>>>>>>>>>>>>>
上面这么写,我们会发现编译失败,因为还未对group进行初始化
%ctor{
%init(group1)%init(group2)
}
打印会发现点击按钮 ,只会打印group2的方法,因为先走的1,后来2把1给覆盖了
所以ctor内部一般多为判断,决定初始化哪个,但务必都写全。下面的就是根据系统进行初始化哪个
%ctor{
if([[UIDevice currentDevice].systemVersion floatValue] > 11.0){
%init(group1)
}else{
%init(group2)
}
}
>>>>>>>>>>>>>>>>>>>%log--输出日志!! 输出方法调用的详细信息 >>>>>>>>>>>>>>>>>>>
%log打印按钮点击>>>>>>>>>>>>>>>>>>>%orig--保持原方法>>>>>>>>>>>>>>>>>>>
%orig可以让走原来方法,比如你hook微信登录按钮事件,你拿到事件后,你获取到账号密码后,你还应该用%orig,保证不影响原始功能
>>>>>>>>>>>>>>>>>>>%c--获得一个类对象>>>>>>>>>>>>>>>>>>>
类似getClass函数,获得一个类对象。一般用于调用类方法。
如我们在新增方法 touchesBegan 调用类方法 Login_classMethod
%new
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"点击了屏幕");
[self.class Login_classMethod];
}
但是你试了会发现这么写在编译阶段是无法通过的,这时候我们需要在顶部添加声明
@interface ViewController : UIViewController
+(void)Login_classMethod;
@end
那么%c的作用就是相当于 self.class
所以上面也可以这么写 [%c(ViewController) Login_classMethod];效果是一样的
通过logos语法 ,我们在不需要懂runtime等情况下就能轻松完成代码的hook注入