logos语法以及简单的应用

2018-05-24  本文已影响55人  立志成为卓越逆向工程师的小仙女

上一篇文章介绍到了logos在逆向中的原理,今天来简单介绍一下logos的语法。

我们以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语法还会更新

/**********************分割线**********************/

/********************* 分割线*************************/

下面讲一下分析

%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执行的方法 weixin界面调试.png

可以看到那个方法是哪个类调用的哪个方法,但是通过层级关系图我们也没有看到这个类,那就只能上内存中找了

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

最后运行,界面左边会有一个自定义的按钮(抱歉有点丑),点击左边菜单栏也会显示哟。

上一篇 下一篇

猜你喜欢

热点阅读