需求最终效果bfinject对正在运行的APP脱壳打包成.ipa
创始人
2025-09-10 21:07:34
0

网上很多教程都讲了很多,但最终不知道他们想要达到什么功能和疗效。 我想,一开始就把要求和最终的疗效展示出来,让读者了解大概情况,引起兴趣,不至于不知其所以然。

我会按照这些文章的思路来分享,先呈现结果,然后详细描述过程。 我认为分享是个好主意。

要求和最终效果

bfinject 将正在运行的APP解压成.ipa

教程脱壳电脑软件免费_电脑软件脱壳工具_电脑脱壳软件教程

注入你自己的动态框架

电脑软件脱壳工具_电脑脱壳软件教程_教程脱壳电脑软件免费

脚本的使用

电脑脱壳软件教程_教程脱壳电脑软件免费_电脑软件脱壳工具

环境要求和正式使用的工具

之前我的MacOSX版本是10.10,只能安装xcode7以下的版本。 xcode7以下的版本没有真机调试功能,所以我将版本升级到MacOSXCatalina10.15.4并安装了最新版本的xcode。 不过这个版本太卡了,存在一些问题。 很多软件不兼容,后来想降级。

电脑脱壳软件教程_教程脱壳电脑软件免费_电脑软件脱壳工具

工具介绍

bfinject是一个注入工具,安装后有很多陷阱。 可以注入到xcode开发的框架中,也可以注入到iOS10中人们使用的cycript工具中。 由于iOS11已经不支持使用cycript,所以所有的cycript命令都只能通过这个工具执行,然后使用笔记本的cycript连接手机。 端口进行操作。

笔记本上的cycript安装教程可以参考这篇文章:安装完这个东西,有很多坑要一一填,但是官网打不开很慢。

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:commandnotfound的错误报告。 我的做法是复制md5sum命令,改成md5执行,不报错。 网上有填坑的例子。 如果你遇到它,你就能看到它。

另外,这个bfinject的实现需要关闭Tweaks才能成功运行:打开越狱工具Electra,禁用Tweaks选项,然后重启。

这个bfinject的执行需要关闭Tweaks才能成功运行:打开越狱工具Electra,禁用Tweaks选项,然后重新启动。

这个bfinject的执行需要关闭Tweaks才能成功运行:打开越狱工具Electra,禁用Tweaks选项,然后重新启动。

使用 bfinject 的手机

以下所有手机命令均由root用户操作。

打开终端,进入/User/Media/目录执行:

portant;overflow-wrap: break-word !important;">bash bfinject -P test1.app -L test

上面界面中的应用程序是我随意编写的一个演示应用程序,安装在iPhone中,我用它来调试。 该应用程序称为 test1.app,此处用于演示。 -Ltest是指调用bfinject外部框架进行注入。 用于判断bfinject是否安装成功并生效。 成功界面如下:

电脑脱壳软件教程_教程脱壳电脑软件免费_电脑软件脱壳工具

电脑脱壳软件教程_电脑软件脱壳工具_教程脱壳电脑软件免费

拿出来用这个命令导入ipa

portant;overflow-wrap: break-word !important;">bash bfinject -P test1.app -L decrypt

返回应用界面

教程脱壳电脑软件免费_电脑软件脱壳工具_电脑脱壳软件教程

打包! 我们选择否,它会将包保存到应用程序的文档目录中。

我们找到这个包:

portant;overflow-wrap: break-word !important;">find /var/mobile/Containers/Data/Application/ -name decrypted-app.ipafind /var/mobile/Containers/Data/Application/ -name decrypted-app.ipa

电脑脱壳软件教程_教程脱壳电脑软件免费_电脑软件脱壳工具

其中decrypted-app.ipa就是我们打包的路径。 将这个包放到/User/Media/目录下,然后使用笔记本手机助手工具获取。 下一步是提取头文件。

注入你自己的动态框架

提取头文件

class-dump的安装比较简单,我就不讲了,它是一个提取match-o格式文件的工具,它可以导入iOS开发的app的头文件,可以知道类、技能、以及应用程序上的变量名称。 使用它来注入指定的方法。

笔记本命令:

portant;overflow-wrap: break-word !important;">class-dump -H test1 -o test1Headers

test1就是上面我解压decrypted-app.ipa后的match-o文件,test1Headers指的是输出所有头文件到这个文件夹。

好吧,我打开其中一个头文件。

电脑脱壳软件教程_教程脱壳电脑软件免费_电脑软件脱壳工具

因为这个app是我自己写的,所以我知道down是点击其中一个Button按钮后输出弹窗的功能。 我会用这个方法来演示注入,就是点击Button按钮后注入一个弹窗。 其实其他app需要凭经验来分析,可以用hooper等反编译工具来分析。

编译注入代码

打开xcode,新建一个项目,在iOS framework&Library中选择framework。

请您自行填写产品名称等信息。 我的名字是snakeGameHacker。

创建项目目录后,snakeGameHacker.h是头文件,我的这样写:

portant;overflow-wrap: break-word !important;">#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 

然后创建CocoaTouchclass文件HackerLoader,它将手动生成HackerLoader.h和HackerLoader.m文件。

黑客加载器.h

portant;overflow-wrap: break-word !important;">#import portant;overflow-wrap: break-word !important;">#import portant;overflow-wrap: break-word !important;">@interface HackerLoader : NSObjectportant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">@end

黑客加载器.m

portant;overflow-wrap: break-word !important;">#import "HackerLoader.h"portant;overflow-wrap: break-word !important;">#import "NSObject+Hacker.h"portant;overflow-wrap: break-word !important;">#import portant;overflow-wrap: break-word !important;">@implementation HackerLoaderportant;overflow-wrap: break-word !important;">static void __attribute__((constructor)) entry(void) {portant;overflow-wrap: break-word !important;"> NSLog(@">>>>> Code Injected 哈哈哈3哈<<<<<"); portant;overflow-wrap: break-word !important;"> NSObject *obj = [[NSObject alloc] init];portant;overflow-wrap: break-word !important;"> [obj hack];portant;overflow-wrap: break-word !important;">}portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">@end

然后创建一个objective-cFile文件,类型选择Category,命名为Hacker

最终形式:NSObject+Hacker.h 和 NSObject+Hacker.m

NSObject+Hacker.h

portant;overflow-wrap: break-word !important;">#import portant;overflow-wrap: break-word !important;">#import portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">@interface NSObject (Hacker)portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">- (void)hack;portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">@end

NSObject+Hacker.m

这是我们的核心文件

portant;overflow-wrap: break-word !important;">#import "NSObject+Hacker.h"portant;overflow-wrap: break-word !important;">#import portant;overflow-wrap: break-word !important;">@implementation NSObject (Hacker)portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">- (void)hack {portant;overflow-wrap: break-word !important;"> NSLog(@">>>>> Code Injected powerby maimai <<<<<");portant;overflow-wrap: break-word !important;"> NSString *className = @"ViewController";portant;overflow-wrap: break-word !important;"> [self hookMethod:@"down" ofClass:className hookMethodName:@"down2"];portant;overflow-wrap: break-word !important;">}portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">// 封装方法挂载函数portant;overflow-wrap: break-word !important;">- (void)hookMethod:(NSString *)oriMethodName ofClass:(NSString *)ClassName hookMethodName:(NSString *)hookMethodName {portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> NSLog(@"挂载方法。。。。");portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> static dispatch_once_t onceToken;portant;overflow-wrap: break-word !important;"> dispatch_once(&onceToken, ^{portant;overflow-wrap: break-word !important;"> Class oriMethodClass = NSClassFromString(ClassName);portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> Class class = [self class];portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> SEL originalSelector = NSSelectorFromString([oriMethodName stringByAppendingString:@":"]);portant;overflow-wrap: break-word !important;"> SEL swizzledSelector = NSSelectorFromString([hookMethodName stringByAppendingString:@":"]);portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> Method originalMethod = class_getInstanceMethod(oriMethodClass, originalSelector);portant;overflow-wrap: break-word !important;"> Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> BOOL didAddMethod = class_addMethod(oriMethodClass,originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod));portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> if (didAddMethod) {// 判断是否已经有这个方法了portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> class_replaceMethod(oriMethodClass,swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> } else {portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> method_exchangeImplementations(originalMethod, swizzledMethod);portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> }portant;overflow-wrap: break-word !important;"> });portant;overflow-wrap: break-word !important;">}portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">// 按钮按下portant;overflow-wrap: break-word !important;">- (void)down2:(id)sender{portant;overflow-wrap: break-word !important;"> NSLog(@"----down2----weirui3----");portant;overflow-wrap: break-word !important;"> [self showError:@"我在app的方法里注入自己的代码啦!"];portant;overflow-wrap: break-word !important;"> return [self down2:sender];portant;overflow-wrap: break-word !important;">}portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">- (UIViewController *)_topViewController:(UIViewController *)vc {portant;overflow-wrap: break-word !important;"> if ([vc isKindOfClass:[UINavigationController class]]) {portant;overflow-wrap: break-word !important;"> return [self _topViewController:[(UINavigationController *)vc topViewController]];portant;overflow-wrap: break-word !important;"> } else if ([vc isKindOfClass:[UITabBarController class]]) {portant;overflow-wrap: break-word !important;"> return [self _topViewController:[(UITabBarController *)vc selectedViewController]];portant;overflow-wrap: break-word !important;"> } else {portant;overflow-wrap: break-word !important;"> return vc;portant;overflow-wrap: break-word !important;"> }portant;overflow-wrap: break-word !important;"> return nil;portant;overflow-wrap: break-word !important;">}portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">- (UIViewController *)topViewController {portant;overflow-wrap: break-word !important;"> UIViewController *resultVC;portant;overflow-wrap: break-word !important;"> resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]];portant;overflow-wrap: break-word !important;"> while (resultVC.presentedViewController) {portant;overflow-wrap: break-word !important;"> resultVC = [self _topViewController:resultVC.presentedViewController];portant;overflow-wrap: break-word !important;"> }portant;overflow-wrap: break-word !important;"> return resultVC;portant;overflow-wrap: break-word !important;">}portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">- (void)showError:(NSString *)errorMsg {portant;overflow-wrap: break-word !important;"> UIViewController *uvc = [self topViewController];portant;overflow-wrap: break-word !important;"> NSLog(@"----weirui3----当前vc%@", NSStringFromClass([uvc class]));portant;overflow-wrap: break-word !important;"> // 1.弹框提醒portant;overflow-wrap: break-word !important;"> // 初始化对话框portant;overflow-wrap: break-word !important;"> UIalertController *alert = [UIalertController alertControllerWithTitle:@"提示" message:errorMsg preferredStyle:UIalertControllerStylealert];portant;overflow-wrap: break-word !important;"> [alert addAction:[UIalertAction actionWithTitle:@"确定" style:UIalertActionStyleDefault handler:nil]];portant;overflow-wrap: break-word !important;"> // 弹出对话框portant;overflow-wrap: break-word !important;"> [uvc presentViewController:alert animated:true completion:nil];portant;overflow-wrap: break-word !important;"> NSLog(@"uvc show");portant;overflow-wrap: break-word !important;">}portant;overflow-wrap: break-word !important;"> portant;overflow-wrap: break-word !important;">@end

代码解释

静态 voidattribute((构造函数))entry(void){}

当进程注入时,这个技巧将在这里执行。 我们实例化一个 NSObject 来执行 NSObject+Hacker.m.hack() 方法。 hack方法上面有一段:

portant;overflow-wrap: break-word !important;">NSString *className = @"ViewController";portant;overflow-wrap: break-word !important;"> [self hookMethod:@"down" ofClass:className hookMethodName:@"down2"];

HookMethod是我封装好的函数调用钩子方法,用OC语言中的swizzledMethod实现方法替换注入。 theos中tweak的%orig原理是使用swizzledMethod来实现hook。

前面我会分享tweak注入的教程,我认为它比bfinject更稳定可靠。

意思是ViewController类下的down()方法挂载了一个我们指定的down2()方法

然后我们编译down2技能。

portant;overflow-wrap: break-word !important;">// 按钮按下portant;overflow-wrap: break-word !important;">- (void)down2:(id)sender{portant;overflow-wrap: break-word !important;"> NSLog(@"----down2----weirui3----");portant;overflow-wrap: break-word !important;"> [self showError:@"我在app的方法里注入自己的代码啦!"];portant;overflow-wrap: break-word !important;"> return [self down2:sender];portant;overflow-wrap: break-word !important;">}

拦截了down的执行并插入了一段代码[selfshowError:@"我在app方法中注入了自己的代码!";

这是弹出窗口的代码。 本页面弹窗的实现请自行查看弹窗实现代码。 网上有很多类似的代码。 然后返回[selfdown2:sender];

是%orig的真实代码,看似是递归调用,其实不然。

编译

我们先测试一下是否有错误。

如果要使用单例测试,将编译目标改为iOSSimulators电脑脱壳软件教程,我选择iOS8,然后按command+U运行,拒绝不报错,运行到hack()方法:

教程脱壳电脑软件免费_电脑软件脱壳工具_电脑脱壳软件教程

其实down2方法不会被执行,因为down2是动态执行的,需要注入bfinject来启动对应的app来触发down方法执行。

我们编译代码。

请注意,编译目标已切换为 GenericiOSDevice。

将其他与证书相关的配置更改为“无”,将目标版本更改为您的手机可以执行的版本,然后等待一些过程。

然后按Command+B进行编译。

Products/目录下形成snakeGameHacker.framework目录电脑脱壳软件教程,用finder打开,进去找到上面snakeGameHacker的Unix可执行文件,就是我们注入的对象。

注射

将snakeGameHacker上传到手机目录。

在手机中执行

portant;overflow-wrap: break-word !important;">bash bfinject -P test1.app -l snakeGameHacker  

注意这里的-l和前面的不一样,这里是大写的。

执行完后,返回app,按下Button按钮(down模式下执行触发)

结果注入成功:

电脑软件脱壳工具_电脑脱壳软件教程_教程脱壳电脑软件免费

至此,框架注入就解释完了。

脚本的使用

手机执行:

portant;overflow-wrap: break-word !important;">bash bfinject -P test1.app -L cycript

电脑脱壳软件教程_电脑软件脱壳工具_教程脱壳电脑软件免费

之后笔记本打开终端,输入对应的地址:

portant;overflow-wrap: break-word !important;">cycript -r 192.168.0.101:1337

不过我经常连接很久或者失败,感觉不太好用。 需要几次尝试才能成功。

本来想写几个命令,现在连接不上,算了~

-结尾-

教程脱壳电脑软件免费_电脑脱壳软件教程_电脑软件脱壳工具

看学ID:麦麦2020

*本文由看学峰会脉脉2020原创,转载请注明来自看学社区。

相关内容

热门资讯

新... 在这特殊的龙年除夕之际,我为您准备了20句别开生面的祝福语,愿您以全新的方式感受节日的动人魅力:1....
社... 社交软件中添加附近的朋友功能的发展趋势随着智能手机的普及和移动互联网的快速发展,社交软件已经成为人们...
2... 大家有机会关注一波这个号分享超牛ipa文件更新内容更新经典影视app大师兄还有两个小说app不用巨魔...
必... 大家好,我是屋主~明天就是大年三十了,屋主祝大家新的一年身体健康,万事如意,想啥有啥~电子设备的屏幕...
i... 本文目录导航: inventor什么意思 inventor是什么? ...
创... 本文目录导航: 创维电视无线网络怎样设置 创维55寸电视怎样衔接wifi ...
a... 本文目录导航: Adobephotoshop.7.0.1该怎样学啊有谁能教我一下那外面的程...
思... 本文目录导航: 思讯超巿收银系统多少钱 大家说说,超市收银软件大略多少钱?...
中... 本文目录导航: 中国移动and和网络机顶盒怎样装置第三方 怎样在电视盒子上...
“买涨它跌,买跌它涨”,中国白...   上海华通白银国际交易中心有限公司与中国白银集团有限公司旗下的“中国白银”APP交易软件是否正规?...
电... 本文目录导航: 电视盒子装置第三方软件后显示装置完成然而在不到也不显示 ...
怎... 本文目录导航: 怎样在电视盒子上装置第三方软件 如何在网络机顶盒上装置运行...
有... 本文目录导航: 安卓平板电脑屏幕一半触摸坏了,有没有软件可以增加屏幕只玩另一半的软件? ...
怎... 本文目录导航: 怎样把android手机改成平板电脑形式 一台安卓平板,一...
有... 本文目录导航: 有谁知道思迅超市收银系统怎样样? 那个思迅天店收银软件是怎...
手... 本文目录导航: 手机玩游戏对手机有损伤吗 怎样把android手机改成平板...
用... 本文目录导航: 创维电视。怎样装置u盘\里的软件 创维电视用u盘怎样装置第...
机... 本文目录导航: 机顶盒第三方运行不可联网 我的机顶盒装了爱奇艺tv和沙发管...
i... 本文目录导航: autodesk inventor 有什么用 Invent...
如... 本文目录导航: 如何经常使用激光切割雕琢系统画图 激光切割机怎样编程 ...