上一篇文章介绍到了logos在逆向中的原理,今天来简单介绍一下logos的语法。
-
hook.x
代表支持logos语法和c语法 -
hhh.xm
代表支持logos语法,c,c++ ,oc语法 -
%group groupName -- %end
这个是分组,我们可能会做一些条件判断,不同的情况使用不同的分组 -
%ctor{} 、 %dtor{}
构造函数,析构函数 -
%init
初始化方法 ,如果定义了group 那么一定要写%init(group),这个构造方法还可以用来初始化摸个类%init(someClass = objc_getClass(someClass)) -
%hook className -- %end
这个代表你要hook哪个类,这一段可以写在group里面,在hook里直接实现那个方法,如果编译器报错,就直接写一个类的声明 -
%orig
执行原来的方法 ,
它也可以有返回值 id value = %orig;
也可以用来调用原来的方法 id value= %orig(arg1) -
%log
输出参数,我们可以用来看方法的参数 -
%new
新增一个方法 -
%c
获取某个类 %c(ViewController)
我们以Monkey的工程为例,假如我们需要hook一个类里的所有方法,
可以在MethodTraceConfig.plist 里 ,将ENABLE_METHODTRACE 字段改成YES,然后在TARGET_CLASS_LIST里新增一个子item,将类型改成string
#import <UIKit/UIKit.h>
@interface ViewController
+(void)zsh_classMethod;
@end
//代码分组
%group group1
%hook ViewController
- (void)viewDidLoad{
NSLog(@"🍺🍺🍺🍺🍺🍺🍺");
%orig;
}
%end
%end
%group group2
%hook ViewController
- (void)viewDidLoad{
NSLog(@"🍺🍺🍺🍺🍺🍺🍺");
[%c(ViewController) zsh_classMethod];
%orig;
}
%new
+(void)zsh_classMethod{
NSLog(@"🥜🥜🥜🥜🥜🥜🥜");
}
%end
%end
//创建了group就要写构造函数,后写的构造函数会覆盖一开始的构造函数
//构造函数
%ctor{
NSString * version = [UIDevice currentDevice].systemVersion;
if(version.doubleValue >= 11.3){
%init(group1)
}else{
%init(group2)
}
}
后续遇到logos语法还会更新
/**********************分割线**********************/
- FLEX
这个可以嵌入到工程里直接看层级,大家用cocoapod导入FIEX就好,然后在 CHConstructor 方法中加上[[FLEXManager sharedManager] showExplorer];
就好
/********************* 分割线*************************/
- 简单应用
目的: 在weixin首页导航栏左边也添加一个按钮,点击和右边点击一样
下面讲一下分析
-
步骤
1.首先通过mokeyDev运行起来工程,进入首页
2.我们需要在导航栏新增一个我们自己item
3.通过viewDebug查看界面,查看点击事件调用的方法
4.我们新增item调用上面查找出来的点击事件。 -
新增一个item,通过viewDebug可以看到当前的控制器,直接hook这个控制器里的
viewDidLoad
方法,在里面设置左边导航栏的item
%hook NewMainFrameViewController
- (void)viewDidLoad{
%orig;
UIButton * leftBtn = [UIButton buttonWithType:UIButtonTypeContactAdd];
[leftBtn addTarget:self action:@selector(zshClick) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithCustomView:leftBtn];
[self.navigationItem setLeftBarButtonItem:item];
}
%end
然而,然并卵。。。。。
我们猜想,viewDidLoad之后应该还有别的函数设置了leftItem,so,我们重写一个leftItem的get方法,同时根据生命周期,重写view展示的几个方法,大家可以通过打印判断最后调用的地方。
-(UINavigationItem *)navigationItem{
NSLog(@"🥜🥜🥜🥜🥜🥜🥜🥜");
return %orig;
}
通过查看log日志,我们发现,在- (void)viewDidAppear:(_Bool)arg1原方法结束后没有再获取leftItem。因此我们修改item的方法可以放在这个方法的最后
- (void)viewDidAppear:(_Bool)arg1{
%orig;
NSLog(@"=====viewDidAppear=======");
UIButton * leftBtn = [UIButton buttonWithType:UIButtonTypeContactAdd];
[leftBtn addTarget:self action:@selector(zshClick) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithCustomView:leftBtn];
[self.navigationItem setLeftBarButtonItem:item];
}
*查看点击导航栏右边Item执行的方法

可以看到那个方法是哪个类调用的哪个方法,但是通过层级关系图我们也没有看到这个类,那就只能上内存中找了
- 通过cycript动态查看内存。首先通过cycript 连接上应用,这一部分后续补个别人的连接
cy# UIApp
....
cy# choose(NewMainFrameRightTopMenuBtn)
可以看到一个对象输出。接下来根据我们的经验,这个按钮应该在导航栏上,先获取到当前的控制器
cy# var mainFrame = UIApp.keyWindow.rootViewController.selectedViewController.topViewController
查看当前控制器的rightItem
cy# mainFrame.navigationItem.rightBarButtonItem
结果是一个MMBarButtonItem,到头文件中查看一下这个类的定义(用class-dump导出头文件的方法之前的文章有提到)
看一下类的定义,好像并没有什么,接着看cycript中输出的信息,item里面又个view,我们输出一下view看看
cy# mainFrame.navigationItem.rightBarButtonItem.view
结果非常的感人,找到这个对象了!!!
接下来就是调用了,附上代码,之所以新定义几个类的声明是为了骗过编译器,不这样编译器小姐姐会报错的。
#import <UIKit/UIKit.h>
@interface zshView
-(void)showRightTopMenuBtn;
@end
@interface zshBar:UIBarButtonItem
@property(nonatomic,weak)zshView * view;
@end
@interface NewMainFrameViewController:UIViewController
@end
%hook NewMainFrameViewController
-(UINavigationItem *)navigationItem{
NSLog(@"🥜🥜🥜🥜🥜🥜🥜🥜");
return %orig;
}
- (void)viewDidAppear:(_Bool)arg1{
%orig;
NSLog(@"=====viewDidAppear=======");
UIButton * leftBtn = [UIButton buttonWithType:UIButtonTypeContactAdd];
[leftBtn addTarget:self action:@selector(zshClick) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithCustomView:leftBtn];
[self.navigationItem setLeftBarButtonItem:item];
}
%new
-(void)zshClick{
NSLog(@"hello world");
zshBar * btn =self.navigationItem.rightBarButtonItem;
[btn.view showRightTopMenuBtn];
}
%end
最后运行,界面左边会有一个自定义的按钮(抱歉有点丑),点击左边菜单栏也会显示哟。
网友评论