逆向编程 Logos基本使用

使用 Cycript 的时候,安装了 Monkey Dev, 用 Monkey Dev 新建的工程后,文件夹 xxxDylib 下有一个 Logos 的文件夹,该文件夹下有一个后缀为 .xm 的文件,.xm 文件中所使用的就是 Logos 语法。
如果点击 .xm 文件无法显示其中代码,Xcode 做如下更改即可。

image

1、什么是 Logos?

Logos 是一种语法,该语法其实是CydiaSubstruct 框架提供的一组宏定义。便于开发者使用宏进行 HOOK 操作。语法简单,功能强大且稳定。

2、Logos 语法说明

Logos的官网

文件后缀名为 .xm 代表支持 Logos 语法、CC++,如果后缀名为 .x 代表支持 Logos 语法和 C

1、%hook

你要 Hook 哪个类。 %hook 后面接类名:%hook ViewController%end 结束,中间放的是需要 Hook 的方法

%hook ViewController

- (void)hookMethod {

} 

%end

2、%group

用于分组,比如在不同 iOS 系统版本上使用不同分组的代码,兼容性就会更好。

%group group1

%hook ViewController

- (void)hookMethod {
   NSLog(@"第一组Hook");
}

%end

%end

%group group2

%hook ViewController

- (void)hookMethod {
   NSLog(@"第二组Hook");
}

%end

%end

3、%init

初始化一个组。

%init(group1)
%init(group2)

4、%ctor

构造函数,如果有上述分组可以在这个方法里面去判断。

%ctor{
    NSString *version = [UIDevice currentDevice].systemVersion;
    if (version.floatValue >= 8.0) {
        %init(group1)
    } else {
        %init(group2)
    }
}

5、%dtor

析构函数。

%dtor {
    //释放一些东西...
}

6、%log

输出方法的一些详细信息,就类似于 LLDBframe variable

7、%orig

Hook到一个方法后,保持原来的方法的调用,如果该方法有返回值,也能接收返回值。

8、%new

动态添加方法

%new
- (void)addMethod {
    //一些方法实现...
}

%new
+ (void)classMethod {
    //一些方法实现...
}

9、%c

如果是添加了一个类方法,就需要使用类对象是调用,%c(类名) 就可以获取类对象。

3、Logos 语法使用

Xcode 新建一个普通工程命名为 LogosLoginText ,然后在 ViewController.m 中写入如下代码:

//
//  ViewController.m
//  LogosLoginText
//
//  Created by ABC on 2019/11/9.
//  Copyright © 2019 ABC. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self postWithUID:@"ABC" pwd:@"123456"];
}

- (void) postWithUID:(NSString *)uid pwd:(NSString *)pwd {

    if ([uid isEqualToString:@"ABC"] && [pwd isEqualToString:@"123456"]) {

        //登录成功
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"登录成功" message:nil preferredStyle:(UIAlertControllerStyleAlert)];

        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:nil];
        [alertController addAction:okAction];

        [self presentViewController:alertController animated:YES completion:nil];

    } else {

        //登录失败
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"登录失败" message:nil preferredStyle:(UIAlertControllerStyleAlert)];

        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:nil];
        [alertController addAction:okAction];

        [self presentViewController:alertController animated:YES completion:nil];
    }
}

@end

上方代码就是简单的一个判断,目的是在使用 Logos 语法 Hook 的时候,改变了相应的值,会提示错误,以便于知道 Hook 到改方法并修改值成功了。

添加完了上述代码,真机编译一下就可以了,这里只是为了拿到生成的 LogosLoginText.app 包,以便于使用 Monkey Dev 重签而已,就相当于模拟其他 App

编译成功后找到 Xcode 工程里 Products 文件下的 LogosLoginText.appShow in Finder 拷贝出来。

新建 Monkey 工程,然后重签 LogosLoginText.app 成功后,使用 class-dump 导出LogosLoginText.MachO 的头文件,这样准备工作就完成了。

打开 LogosLoginText 的头文件,就是假装打开了其他 App 的头文件,然后分析一下:

image

假装看到了登录方法 - (void)postWithUID:(id)arg1 pwd:(id)arg2; 然后我们对这个方法进行 Hook,然后在注入库 MonkeyLoginDylib.libMonkeyLoginDylib.xm 中写要注入的代码。

// See http://iphonedevwiki.net/index.php/Logos

#import <UIKit/UIKit.h>

%hook ViewController

%hook ViewController

- (void)postWithUID:(id)arg1 pwd:(id)arg2 {
   NSLog(@"Hook到了登录");
}

%end

然后点击屏幕,发现控制台打印了:Hook到了登录,并没有弹出 AlertView 证明该方法被 Hook 成功了。

如果需要版本判断,就需要分组了。使用 %group%init 和 % ctor 了。

%group group1

%hook ViewController

- (void)postWithUID:(id)arg1 pwd:(id)arg2 {
   NSLog(@"第一组Hook到了登录");
}

%end

%end

%group group2

%hook ViewController

- (void)postWithUID:(id)arg1 pwd:(id)arg2 {
   NSLog(@"第二组Hook到了登录");
}

%end

%end

%ctor{
    NSString *version = [UIDevice currentDevice].systemVersion;
    if (version.floatValue >= 8.0) {
        %init(group1)
    } else {
        %init(group2)
    }
}

注意:组一定会有的,如果没有写组,那么Logos 会默认生成一个组 _ungrouped 并自己调用构造函数和 init 方法创建。

尝试输出一下当前方法的详细信息 %log,添加后运行一下,查看结果发现,输出了参数详细的值和方法的指针地址。

%hook ViewController

- (void)postWithUID:(id)arg1 pwd:(id)arg2 {
    %log;
    NSLog(@"Hook到了登录");
}

%end

image

因为 Hook 了这个方法导致,该方法没有执行原有的,现在通过 %orig 保持原来的调用。添加完成后重新运行,点击屏幕显示了 AlertView

%hook ViewController

- (void)postWithUID:(id)arg1 pwd:(id)arg2 {
    %log;
    %orig;
    NSLog(@"Hook到了登录");
}

%end

因为 - (void)postWithUID:(id)arg1 pwd:(id)arg2 是有参数的,所以可以通过 %orig 更改值:%orig(@"AAA",@"111111"),再出重新运行就发现,AlertView 提示登录失败了。

%hook ViewController

- (void)postWithUID:(id)arg1 pwd:(id)arg2 {
    %log;
    %orig(@"AAA",@"11111");
    NSLog(@"Hook到了登录");
}

%end

image

现在给 - (void)postWithUID:(id)arg1 pwd:(id)arg2 需要调用一个动态添加的方法 testMethod 就需要用到 %new 了。

当使用 [self testMethod] 会提示找不到 ViewController ,在逆向中如果找不到这个类,只需要将这个类和新添加的方法声明一下就可以,仅仅是为了让编译器编译能通过。

如果使用原来类里方法过多,可以把 class-dump 导出的头文件直接拖入 Logos文件夹下,在这个头文件里声明一下动态添加的方法名称。

代码如下:

@interface ViewController

- (void)testMethod;

@end

%hook ViewController

%new
- (void)testMethod {
    NSLog(@"调用了我动态添加的方法");
}

- (void)postWithUID:(id)arg1 pwd:(id)arg2 {
    %log;
    %orig(@"AAA",@"11111");
    NSLog(@"Hook到了登录");
    [self testMethod];
}

%end

重启运行,点击屏幕,控制台就打印了刚才添加方法中的 NSLog

image

上方的代码使用的是实例方法,需要添加一个类方法,然后可以使用 %c(类名) 直接调用类方法。

@interface ViewController

- (void)testMethod;

@end

%hook ViewController

%new
- (void)testMethod {
    NSLog(@"调用了我动态添加的方法");
}

%new
+ (void)classMethod {
    NSLog(@"调用了我动态添加的类方法");
}

- (void)postWithUID:(id)arg1 pwd:(id)arg2 {
    %log;
    %orig(@"AAA",@"11111");
    NSLog(@"Hook到了登录");
    [self testMethod];
    [%c(ViewController) classMethod];
}

%end

以上就是 Logos 的介绍和基本用法了

来自:有梦想的程序员
链接:https://www.jianshu.com/p/8405693fea08

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352