MonkeyDev是一个极为方便的逆向调试平台,集众家所长
主要包含四个模块
Logos Tweak -- 使用theos提供的logify.pl工具将.xm文件转成.mm文件进行编译,集成了Cydia Substrate,它的主要作用是针对OC方法、C函数以及函数地址进行HOOK操作。
CaptainHook Tweak -- 使用CaptainHook提供的头文件进行OC函数的Hook以及属性的获取。
Command-line Tool -- 可以直接创建运行于越狱设备的命令行工具。
MonkeyApp -- 自动给第三方应用集成Reveal、Cycript和注入dylib的模块,支持调试dylib和第三方应用,只需要准备一个砸壳后的ipa或者app文件即可。
准备
使用
-
新建MonkeyDev项目,选择MonkeyApp,输入工程名,下一步即可
new project - 将砸壳后的ipa,拖入工程中
copy ipa
注:以前可以通过PP助手下载,越狱应用即可获得砸壳后的ipa,但是现在PP助手已不复存在!只有通过自己来砸壳了,获取砸壳ipa的方法:
frida砸壳
Clutch砸壳
dumpdecrypted砸壳
其中,frida砸壳成功率最高,但是它的环境配置比较麻烦;Clutch环境配置简单,砸壳成功率一般;dumpdecrypted最后导出的是decrypt文件,需要进行其他处理。 - run起来,就可以完成重签名,让他人之物变为自己的,然后进行态调试,动态调试需要使用LLDB的高级用法和Chisel
- 文件扩展名的意义,x代表这个文件支持 Logos 语法
.x 将由Logos处理,然后进行预处理并编译为objective-c。
.xm 将由Logos处理,然后进行预处理并编译为objective-c ++。
Logos语法
- %hook - 指定需要hook的类,必须以%end结尾
- %log - hook内部使用,将函数的类名及参数写入syslog中,可以追加打印内容%log[,.....]
- %orig - hook内部使用,执行被hook的函数的原始代码,可以使用%orig改变原始函数参数
- %group - 将%hook分组,便于代码管理,必须以%end结尾
- %init - 初始化某个%group,必须在%hook或%ctor中使用;如果带参数,则初始化指定的group,如果不带参数,则初始化_ungrouped;%group只有调用了%init后才会被初始化
- %ctor - Tweek的constructor,完成初始化工作;如果没有定义,Theos则会自动生成一个%ctor,并在其中调用%init(_ungrouped)
- %new - 在hook内部使用,给一个现有的class添加新函数
- %c - 根据类名获取一个类
小试牛刀-动态调试钉钉,并将帐号密码展示到页面上
- 将砸过壳的ipa的头文件导出
class_dump -H .app路径 -o DingTalkHeaders
通过工具打开头文件文件夹,以备后用
DingTalk 头文件
-
运行MonkeyDev Demo,进入帐号密码登录页
帐号密码登录页 -
点击Debug View Hierarchy
Debug View Hierarchy
进入Debug View
找到页面的类,以及当前对象的内存地址
-
通过类名DTAccountPasswordViewController,到头文件去搜索
DTAccountPasswordViewController
这里我们看到了想要hook的帐号和密码的view,下面以密码为例
-
先来看下密码输入框的类结构,在头文件中搜索DTLoginPasswordInputView
DTLoginPasswordInputView
DTPasswordTextField
这样一来密码框的继承关系就很明显了,我们在DTAccountPasswordViewController中找到passwordView,再在passwordView中找到passwordTextField,最后打印它的text即可,下面我们通过lldb来验证下
lldb验证
帐号的hook步骤与密码一样!
这里在点击登录时做一个展示帐号密码的操作,所以我们需要看下登录按钮的触发了什么方法,找到登录按钮的内存地址,并使用LLDB高级指令pactions,查看它的target和action
pactions
现在头文件中看下DTAccountPasswordViewController这个类的loginButtonPressed的方法
loginButtonPressed
接下来我们就可以hookloginButtonPressed
下面看下logos代码的实现
// See http://iphonedevwiki.net/index.php/Logos
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@interface DTAccountPasswordViewController:UIViewController
- (void)showPassword:(NSString *) msg;
@end
%hook DTAccountPasswordViewController
- (void)loginButtonPressed:(id)arg1 {
//获取帐号
NSString *phone = [[[self valueForKey:@"phoneView"] valueForKey:@"_mobileInputView"] valueForKey:@"text"];
//获取密码内容
NSString *pwd = [[[self valueForKey:@"passwordView"] valueForKey:@"passwordTextField"] valueForKey:@"text"];
[self showPassword:[NSString stringWithFormat:@"%@🐮🐮🐮%@",phone, pwd]];
//%orig;
}
%new
- (void)showPassword:(NSString *) msg{
UIView *bgView = [[UIView alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
bgView.backgroundColor = [UIColor clearColor];
[[[UIApplication sharedApplication] keyWindow] addSubview:bgView];
UILabel* lab = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 300, 40)];
lab.layer.cornerRadius = 4;
lab.backgroundColor = [UIColor orangeColor];
lab.text = msg;
lab.textColor = [UIColor whiteColor];
lab.textAlignment = NSTextAlignmentCenter;
lab.alpha = 0.8;
lab.center = bgView.center;
[bgView addSubview:lab];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(8 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[bgView removeFromSuperview];
});
}
%end
重新运行,看下效果
运行效果
至此,我们就完成了帐号密码的hook,真是牛批
生活如此美好,今天就点到为止。。。
网友评论