![867d47818ff08e732fe0db9b8f12c029.png](https://img-blog.csdnimg.cn/img_convert/867d47818ff08e732fe0db9b8f12c029.png)
看雪论坛作者ID:麦麦2020
目录
需求&最终效果
1. bfinject对正在运行的APP脱壳打包成.ipa
2. 注入自己的动态framework
3. cycript的使用
环境要求与即将使用的工具
工具介绍
实现过程
1. bfinject对正在运行的APP脱壳打包成.ipa
安装bfinject
手机使用bfinject
打包
2. 注入自己的动态framework
提取头文件
编写注入代码
代码讲解
编译
注入
3. cycript的使用
本篇文章是继上一篇文章:2020年 iOS 逆向 反编译 注入修改游戏或 APP 的调用参数新手系列教程——按键精灵脚本来模拟合成灯笼后本继续分享的教程。
网上很多教程讲了一大堆话,最终翻来翻去不知道是想实现什么功能和效果,我觉得一开始把需求&最终效果展示能让读者了解个大概和引起兴趣,不会不知所以然。
后面我会按这种文章思路来分享,先把结果呈现,再详叙过程,我想是个不错的分享思路。
需求&最终效果bfinject 对正在运行的 APP 脱壳打包成 .ipa
注入自己的动态 framework
cycript 的使用
之前我的 MacOSX 版本是 10.10,只能安装 xcode7 以下的版本,xcode7以下的版本没有真机调试功能,于是升级了版本到 MacOSX Catalina 10.15.4 也安装了最新版 xcode,但是这个版本太卡而且有些问题,很多软件兼容不了了,想以后降级。
![1853c045f5daed2fcfdb0ac86fab3493.png](https://img-blog.csdnimg.cn/img_convert/1853c045f5daed2fcfdb0ac86fab3493.png)
工具介绍
bfinject 是一款注入工具,安装后坑挺多。可以注入 xcode 开发的framework,也可以注入 iOS10 以前人们用的 cycript 工具,因为 iOS11 已经不支持 cycript 的使用了,只能通过这个工具来执行 cycript 的全部命令,然后用电脑的 cycript 连接手机 cycript 提供出来的端口来操作。
电脑上的 cycript 安装教程参考这篇文章:https://www.jianshu.com/p/d93e9fccef4b,这玩意安装后坑很多一一填坑吧,而且官网打开好慢。
cycript 是一款动态注入工具,可以动态执行 cy 代码,常用来打印 ui 界面和调试。
iOS11 的 ssh 本人用不了,从 cydia 安装了 openssh,但是用命令行执行ssh 报无法打开二进制文件的英文错误,不知道为何,谁能在 iOS11 运行 ssh并且电脑连接手机 ssh 的麻烦告知我一下谢谢。
实现过程bfinject 对正在运行的 APP 脱壳打包成 .ipa
安装 bfinject
首先电脑下载 bfinject,然后用手机助手等工具把二进制文件 bfinject 拷贝到iPhone 手机的随意位置下,我是放在 /User/Media/ 目录下。bfinject 下载和安装教程参考 github。
这个 bfinject 的坑还是很多的,安装后执行会出现很多报错。比如 electra 和bootstrap 目录问题的坑;还有 md5: command not found 的报错,我的做法是把 md5sum 这个命令复制一个改成 md5 执行就不报错,网上有填坑例子,遇到的可以看看。
另外说明,这个 bfinject 的执行需要关闭 Tweaks 才能运行成功:打开越狱工具 Electra,把 Tweaks 选项禁用,然后重新启动。
这个 bfinject 的执行需要关闭 Tweaks 才能运行成功:打开越狱工具 Electra,把 Tweaks 选项禁用,然后重新启动。
这个 bfinject 的执行需要关闭Tweaks才能运行成功:打开越狱工具Electra,把Tweaks选项禁用,然后重新启动。
手机使用 bfinject
以下及下文所有手机命令都是用 root 用户来操作。
打开 terminal 到 /User/Media/ 目录下执行:
bash bfinject -P test1.app -L test
上图界面的 app 是我自己随便写的一个 demo app ,安装在了 iPhone 里,我调试用的,这个 app 叫 test1.app,这里拿来演示,-L test 是指调用bfinject 内置的 framework 来注入,用来确定 bfinject 是否安装成功和生效,成功界面如下:
打包
接下来用这个命令来导出 ipa
bash bfinject -P test1.app -L decrypt
回到app界面
打包完毕!我们选择 No 它会把包存储到 App 的文档目录。
我们把包找出来:
find /var/mobile/Containers/Data/Application/ -name decrypted-app.ipafind /var/mobile/Containers/Data/Application/ -name decrypted-app.ipa
注入自己的动态framework
提取头文件
class-dump 安装比较简单我就不说了,是用来提取 match-o 格式文件的工具,可以把 iOS 开发的 app 的头文件导出来,就能知道 app 里面的类和方法、变量名。以此来注入指定方法。
电脑命令:
class-dump -H test1 -o test1Headers
test1 是我把 decrypted-app.ipa 解压后里面的 match-o 文件,test1Headers 是指输出所有头文件到这个文件夹。
好了,我打开其中一个头文件。
因为这个 app 是我自己写的,我知道 down 是其中一个 Button 按钮是点击后输出一个弹窗的功能,我就拿这个方法来演示注入把,就是实现点击 Button 按钮后再注入一个弹窗。当然其他 app 就要靠经验分析啦,可以用hooper 等反编译工具分析。
编写注入代码
打开xcode,新建工程选择 iOS 中的 Framework & Library 中的Framework。
Product Name 等信息你们自己填,我的命名是 snakeGameHacker。
创建好工程目录后,snakeGameHacker.h 就是头文件,我的这样写:
#import //! Project version number for snakeGameHacker.FOUNDATION_EXPORT double snakeGameHackerVersionNumber; //! Project version string for snakeGameHacker.FOUNDATION_EXPORT const unsigned char snakeGameHackerVersionString[]; // In this header, you should import all the public headers of your framework using statements like #import#import #import
然后再创建Cocoa Touch class 文件,HackerLoader,会自动生成HackerLoader.h 和 HackerLoader.m 文件。
HackerLoader.h
#import
#import
@interface HackerLoader : NSObject
@end
HackerLoader.m
#import "HackerLoader.h"
#import "NSObject+Hacker.h"
#import
@implementation HackerLoader
static void __attribute__((constructor)) entry(void) {
NSLog(@">>>>> Code Injected 哈哈哈3哈<<<<);
NSObject *obj = [[NSObject alloc] init];
[obj hack];
}
@end
再创建 objective-c File 文件,类型选择 Category,名字 Hacker
最终产生:NSObject+Hacker.h和NSObject+Hacker.m
NSObject+Hacker.h
#import
#import
@interface NSObject (Hacker)
- (void)hack;
@end
NSObject+Hacker.m
这就是我们的核心文件了
#import "NSObject+Hacker.h"
#import
@implementation NSObject (Hacker)
- (void)hack {
NSLog(@">>>>> Code Injected powerby maimai <<<<);
NSString *className = @"ViewController";
[self hookMethod:@"down" ofClass:className hookMethodName:@"down2"];
}
// 封装方法挂载函数
- (void)hookMethod:(NSString *)oriMethodName ofClass:(NSString *)ClassName hookMethodName:(NSString *)hookMethodName {
NSLog(@"挂载方法。。。。");
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class oriMethodClass = NSClassFromString(ClassName);
Class class = [self class];
SEL originalSelector = NSSelectorFromString([oriMethodName stringByAppendingString:@":"]);
SEL swizzledSelector = NSSelectorFromString([hookMethodName stringByAppendingString:@":"]);
Method originalMethod = class_getInstanceMethod(oriMethodClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(oriMethodClass,originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {// 判断是否已经有这个方法了
class_replaceMethod(oriMethodClass,swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
// 按钮按下
- (void)down2:(id)sender{
NSLog(@"----down2----weirui3----");
[self showError:@"我在app的方法里注入自己的代码啦!"];
return [self down2:sender];
}
- (UIViewController *)_topViewController:(UIViewController *)vc {
if ([vc isKindOfClass:[UINavigationController class]]) {
return [self _topViewController:[(UINavigationController *)vc topViewController]];
} else if ([vc isKindOfClass:[UITabBarController class]]) {
return [self _topViewController:[(UITabBarController *)vc selectedViewController]];
} else {
return vc;
}
return nil;
}
- (UIViewController *)topViewController {
UIViewController *resultVC;
resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]];
while (resultVC.presentedViewController) {
resultVC = [self _topViewController:resultVC.presentedViewController];
}
return resultVC;
}
- (void)showError:(NSString *)errorMsg {
UIViewController *uvc = [self topViewController];
NSLog(@"----weirui3----当前vc%@", NSStringFromClass([uvc class]));
// 1.弹框提醒
// 初始化对话框
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:errorMsg preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];
// 弹出对话框
[uvc presentViewController:alert animated:true completion:nil];
NSLog(@"uvc show");
}
@end
代码讲解
static void attribute((constructor)) entry(void) {}
这个方法会被进程注入的时候执行到这里。我们实例化一个 NSObject 执行NSObject+Hacker.m.hack() 方法,hack 方法里面有一段:
NSString *className = @"ViewController";
[self hookMethod:@"down" ofClass:className hookMethodName:@"down2"];
hookMethod是我封装的函数调用 hook 方法,是利用 OC 语言中swizzledMethod 实现方法替换和注入,theos 中 tweak 的 %orig 原理就是用了 swizzledMethod 实现 hook。
后面我会分享 tweak 注入的教程,我觉得比 bfinject 稳定靠谱。
意思是 ViewController 类下面的 down() 方法挂载一个我们指定的方法down2()
接下来我们编写 down2 方法。
// 按钮按下
- (void)down2:(id)sender{
NSLog(@"----down2----weirui3----");
[self showError:@"我在app的方法里注入自己的代码啦!"];
return [self down2:sender];
}
拦截了 down 的执行,插入了一段代码 [self showError:@"我在app的方法里注入自己的代码啦!";
就是弹窗代码,在本页面弹窗的实现,具体你们自己看弹窗实现代码吧,这个网上很多类似代码。然后再 return [self down2:sender];
就是真正的 %orig 那段代码了,看似是递归调用,实际不会。
编译
我们先测试一下报错没有吧。 如果要用单例测试要让编译目标改为 iOS Simulators,我选 iOS8,然后按 command+U,运行,证实不报错跑通到hack()方法里面:当然 down2 方法是不会被执行的,因为 down2 是动态执行,需要利用bfinject 注入后启动对应 app 触发 down 那个方法才会被执行。
我们编译代码。
注意,编译目标切换为 Generic iOS Device。
其他证书相关配置改为 None,目标版本改为你手机能执行的版本,等一些手续。
然后按下 Command+B 编译。
Products/ 目录下产生 snakeGameHacker.framework 目录,用 finder 打开进入找到里面的 snakeGameHacker 的 Unix 可执行文件,就是我们注入的对象了。
注入
把 snakeGameHacker 上传到手机目录。
手机里执行
bash bfinject -P test1.app -l snakeGameHacker
注意这里的 -l 和上面不同,这里的是小写的。
执行后回到app按一下Button按钮(down方法的执行触发)
结果注入成功:
至此,framework 注入讲解完毕。
cycript的使用
手机执行:
bash bfinject -P test1.app -L cycript
cycript -r 192.168.0.101:1337
不过我经常连接好久或失败,感觉不好用。多试几次才能成功。
本来想写几个命令的,现在连接不上,算了~
![208f3b4d2a333ae48a45bcbe8d50683c.gif](https://img-blog.csdnimg.cn/img_convert/208f3b4d2a333ae48a45bcbe8d50683c.gif)
看雪ID:麦麦2020
https://bbs.pediy.com/user-895501.htm
*本文由看雪论坛 麦麦2020 原创,转载请注明来自看雪社区。推荐文章++++
![ff97019796d7842c5fc80a3dce7069e7.png](https://img-blog.csdnimg.cn/img_convert/ff97019796d7842c5fc80a3dce7069e7.png)
* CVE-2020-0674漏洞分析笔记
* 安卓逆向入门学习的一些总结、自我审视及规划
* 2020网鼎杯青龙组_re_signal
* 一个神秘URL酿大祸,差点让我背锅!
* 恶意代码分析之APC进程注入学习
进击安全圈必看![78c1acb46fd02c1196725889b01293e5.png](https://img-blog.csdnimg.cn/img_convert/78c1acb46fd02c1196725889b01293e5.png)
![94cc43b3198353a6fcd829aeaa498b97.gif](https://img-blog.csdnimg.cn/img_convert/94cc43b3198353a6fcd829aeaa498b97.gif)