美文网首页
logos语法以及简单的应用

logos语法以及简单的应用

作者: 立志成为卓越逆向工程师的小仙女 | 来源:发表于2018-05-24 17:27 被阅读55次

    上一篇文章介绍到了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执行的方法 weixin界面调试.png

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

    • 通过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
    

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

    相关文章

      网友评论

          本文标题:logos语法以及简单的应用

          本文链接:https://www.haomeiwen.com/subject/ibjsjftx.html