首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
iOS安全
发新帖
29
10
[原创]【iOS逆向与安全】iOS插件开发光速入门
发表于: 2022-12-5 14:48
33325
[原创]【iOS逆向与安全】iOS插件开发光速入门
witchan
2022-12-5 14:48
33325
# 前言 经过之前的学习,相信你已经能熟练的使用Frida-trace、IDA Pro等逆向工具。不过,仅仅到这肯定是不够的。接下来,学会把你逆向的结果打包成插件并运行,那iOS逆向,你也就真正的入门了。 --- # 一、目标 把逆向的结果制作成插件并运行 # 二、工具 - mac系统 - Xcode:插件开发工具 - 已越狱iOS设备:运行deb插件 - optool:动态库注入工具,下载地址:<mark class="encrypted">f37K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6S2L8r3g2^5P5X3W2W2L8r3g2F1M7$3E0A6i4K6u0r3L8%4m8@1L8$3!0D9</mark> - MonkeyDev:越狱插件开发集成神器,下载地址:<mark class="encrypted">060K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6m8L8r3!0F1k6f1#2G2L8X3E0W2P5g2)9J5c8V1#2G2L8X3E0W2P5f1c8W2N6R3`.`.</mark> # 三、流程 iOS端的插件按设备分为 - **越狱插件**:扩展名为.deb,类似于安卓的xposed插件 **优点**:独立于ipa文件,ipa可单独升级(前提是相关的 hook代码逻辑没变) **缺点**:必须要越狱设备 - **非越狱插件**:扩展名为.dylib或.framework,类似于安卓的so文件 **优点**:可在非越狱机上运行。由于非越狱机,App自然也就检测不到越狱状态,但仍然可以检测ipa包的完整性 **缺点**:ipa无法单独升级,必须要砸壳,动态库注入,重签名后,才能完成升级操作。 > 注:不管是deb格式、dylib格式还是framework格式,都支持使用c、c++和OC语言进行开发 MonkeyDev,原有iOSOpenDev的升级,非越狱插件开发集成神器! - 可以使用Xcode开发CaptainHook Tweak、Logos Tweak 和 Command-line Tool,在越狱机器开发插件,这是原来iOSOpenDev功能的迁移和改进。 - 只需拖入一个砸壳应用,自动集成class-dump、restore-symbol、Reveal、Cycript和注入的动态库并重签名安装到非越狱机器。 - 支持调试自己编写的动态库和第三方App - 支持通过CocoaPods第三方应用集成SDK以及非越狱插件,简单来说就是通过CocoaPods搭建了一个非越狱插件商店。 所以在本教程中,deb插件和dylib插件,主要使用MonkeyDev来完成,安装教程参考官方即可。而framework插件,则直接使用Xcode开发。 ## deb插件开发 ### 1. 创建插件工程 启动Xcode后,按如下流程依次点击:      至此,插件已经创建完毕:  ### 2. 编写插件代码 **创建完这是MonkeyDev作者写的使用步骤** // Objective-C runtime hooking using CaptainHook: // 1. declare class using CHDeclareClass() // 2. load class using CHLoadClass() or CHLoadLateClass() in CHConstructor // 3. hook method using CHOptimizedMethod() // 4. register hook using CHHook() in CHConstructor // 5. (optionally) call old method using CHSuper() **咱按以上步骤编写完的插件代码如下:** ``` #if TARGET_OS_SIMULATOR #error Do not support the simulator, please use the real iPhone Device. #endif // 导入常用的UI框架和Foundation框架 #import "AppHelper.h" // 注意,一定要导入这,因为这头文件里有Monkey dev定义的宏 #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> // 导入MonkeyDev提供的头文件,这头文件,后边我们创建framework插件时也可使用 #import "CaptainHook/CaptainHook.h" /* 定义你需要Hook的类及需要Hook的方法。 */ @interface DetailViewController : NSObject // 需要Hook的实例方法 - (void)loginButtonDidClick:(UIButton *)sender; // 以下两个方法并不存在,在这只是为了演示如何hook多个参数的方法和hook类方法 - (NSString *)loginWithPhone:(NSString *)phone password:(NSString *)pwd; + (id)factory:(id)arg1; @end CHDeclareClass(DetailViewController); // 步骤1、申明需要Hook的类 /* 步骤3、你的勾子函数,Hook函数被调用时,会执行到这 CHOptimizedMethod的参数说明 第一个参数:固定写死self即可 第二个参数:返回值类型,无返回值写void。c语言的类型,直接写对应的类型即可(int,float,double...)。其他类型,直接写id即可,如果你知道具体的类型,也可写具体的类型 第三个参数:类名 第四个参数:方法名 // 方法名有一个参数时 第五个参数:第一个入参的类型,和第二个参数写法类型 第六个参数:第一个入参的形参名 // 方法名有两个参数时 第七个参数:第二个入参的类型,和第二个参数写法类型 第八个参数:第二个入参的形参名 ... */ CHOptimizedMethod1(self, void, DetailViewController, loginButtonDidClick, UIButton*, sender) { CHSuper1(DetailViewController, loginButtonDidClick, sender); // 调用原方法 NSLog(@"witchan =该方法的入参为:%@", sender); } // Hook两个入参的实例方法 CHOptimizedMethod2(self, id, DetailViewController, loginWithPhone, NSString *, p, password, NSString*, pwd) { id result = CHSuper2(DetailViewController, loginWithPhone, p, password, pwd); // 调用原方法 NSLog(@"witchan =该方法的第一个入参为:%@", p); NSLog(@"witchan =该方法的第二个入参为:%@", pwd); NSLog(@"witchan =该方法的返回值为:%@", result); return result; } // Hook一个入参的类方法,相对于实例方法,只是在Method前多了个Class单词。其他操作完全一样 CHOptimizedClassMethod1(self, id, DetailViewController, factory, id, arg1) { id result = CHSuper1(DetailViewController, factory, arg1); // 调用原方法 NSLog(@"witchan =该方法的入参为:%@", arg1); NSLog(@"witchan =该方法的返回值为:%@", result); /* 由于deb格式、dylib格式还是framework格式,都支持使用c、c++和OC语言进行开发。 以下代码为oc语法的简单示例。 注意:整个插件的写法,和ios开发完全一致,你可以创建新类,也可以调用oc提供的类及相关方法 如果你不熟悉oc语法,请看我公众号的另一篇文章,iOS快速入门:https://mp.weixin.qq.com/s/g89Sdyqc4ONlyAWtXTCwRA */ NSMutableDictionary *params = [NSMutableDictionary dictionary]; params[@"微信公众号"] = @"移动端Android和iOS开发技术分享"; params[@"QQ群"] = @"812546729"; NSData *body = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:nil]; // 调用登录接口 NSURL *loginURL = [NSURL URLWithString:@"https://127.0.0.1:9080/login"]; // 接口 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:loginURL]; // 请求对象 request.HTTPMethod = @"POST"; // 请求方式 [request setValue:@"d83kd9d323" forHTTPHeaderField:@"x-sign"]; // 设置header request.HTTPBody = body; // 注意,HTTPBody是一个16进制数据,一般直接16进制输出,再转换成文本查看 NSURLSession *session = [NSURLSession sharedSession]; // 获取网络对象 NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // 请求结果会调到这 if (error != nil) { NSLog(@"witchan =网络请求出错了"); } else { NSLog(@"witchan =网络请求成功"); } }]; // 创建请求任务 [task resume]; // 发起网络请求 return result; } // 入口函数 CHConstructor { @autoreleasepool { NSLog(@"witchan =FirsDeb hook success!="); // 一般在入口函数输出一条日志,确定你的插件是否加载成功 CHLoadLateClass(DetailViewController); // 步骤2、加载需要Hook的类 CHHook1(DetailViewController, loginButtonDidClick); // 步骤4、注册你需要hook的实例方法 CHHook2(DetailViewController, loginWithPhone, password); CHClassHook1(DetailViewController, factory); // 注册需要hook的类方法 } } ``` **填写目标ipa的包名:**  **编辑插件扩展信息(可选):**  ### 3. 编译插件 **编译**:依次选择菜单栏的Product -> Build  编译后的结果是这样的:  打开目录,就能看到你需要的deb文件了   **安装方式1:**拿到deb文件后,你可以用爱思或ssh工具,把deb文件换过血到手机,再使用Filza工具找到对应的文件,安装即可:   **安装方式2:** 如果你是mac电脑,那你可使用隔空投送功能来把deb文件传输至手机并安装:    **安装方式3:**是不是觉得上边的安装方式有点麻烦,如果是自己真机调试,那你可以这样玩:  然后依次选择菜单栏的Product -> Build或快捷键command+b,这次编译完成后,没有报错。并且你的手机已自动注销了。打开cyida查看你最近安装的deb,就会发现刚编写的插件已经安装成功,简单吧。 在电脑端打开控制台工具:   这时启动被注入deb插件的App后,看到的日志如下:  **如果你编辑时,遇到这错误:** An empty identity is not valid when signing a binary for the product type 'Dynamic Library'.  解决办法:   ## 2.dylib插件使用 在deb插件开发教程中,我们已经同时得到了deb插件和dylib插件,所以在本教程中,则教大家如何把dylib插件注入到ipa,注入工具为optool,该工具主要有两条命令: - 注入:`optool install -c load -p "@executable_path/Frameworks/aaa.framework/aaa" -t demo.app/demo` - 卸载:`optool uninstall -p "@executable_path/Frameworks/aaa.framework/aaa" -t demo.app/demo` 把ipa文件的扩展名改为zip,解压后,得到Payload文件夹:   切换到Payload目录`cd Desktop/Payload`,然后执行注入命令`optool install -c load -p "@executable_path/Frameworks/FirstDeb.dylib" -t ExampleCode.app/ExampleCode`,至此,我们的dylib文件已经注入完成: ```bash witchan@witchandeMacBook-Air Payload % optool install -c load -p "@executable_path/Frameworks/FirstDeb.dylib" -t ExampleCode.app/ExampleCode Found thin header... Inserting a LC_LOAD_DYLIB command for architecture: arm64 Successfully inserted a LC_LOAD_DYLIB command for arm64 Writing executable to ExampleCode.app/ExampleCode... witchan@witchandeMacBook-Air Payload % ``` 接下来将Payload文件夹压缩成zip包,然后把扩展名改为ipa,然后用爱思,或其他重签名工具对该ipa进行签名后,即可在越狱或非越狱机上安装使用了。运行后的日志如下:  ### 3.Framework插件开发 --- ### 1. 创建插件工程 启动Xcode后,按如下流程依次点击:      ### 2. 编写插件代码 创建AppHelper类    创建完成后的目录结构如下:  在这。我们使用之前的deb插件编写方式来写。先把CaptainHook.h文件的所有内容复制到AppHelper.h:  复制整个头文件的内容到AppHelper.h即可。然后把deb插件.m文件的全部代码复制到AppHelper.m,再在.m文件的顶部引入AppHelper.h文件,然后剩下的代码编写方式就和deb的编写完全一样。 最终的AppHelper.h的完整代码如下: ```objc 由于该文件较大,在这进行删除,完整代码请看文末。 ``` AppHelper.m的完整代码如下(和deb相比,只多了`#import "AppHelper.h"`): ```objc #if TARGET_OS_SIMULATOR #error Do not support the simulator, please use the real iPhone Device. #endif // 导入常用的UI框架和Foundation框架 #import "AppHelper.h" // 注意,一定要导入这,因为这头文件里有Monkey dev定义的宏 #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> // 导入MonkeyDev提供的头文件,这头文件,后边我们创建framework插件时也可使用 #import "CaptainHook/CaptainHook.h" /* 定义你需要Hook的类及需要Hook的方法。 */ @interface DetailViewController : NSObject // 需要Hook的实例方法 - (void)loginButtonDidClick:(UIButton *)sender; // 以下两个方法并不存在,在这只是为了演示如何hook多个参数的方法和hook类方法 - (NSString *)loginWithPhone:(NSString *)phone password:(NSString *)pwd; + (id)factory:(id)arg1; @end CHDeclareClass(DetailViewController); // 步骤1、申明需要Hook的类 /* 步骤3、你的勾子函数,Hook函数被调用时,会执行到这 CHOptimizedMethod的参数说明 第一个参数:固定写死self即可 第二个参数:返回值类型,无返回值写void。c语言的类型,直接写对应的类型即可(int,float,double...)。其他类型,直接写id即可,如果你知道具体的类型,也可写具体的类型 第三个参数:类名 第四个参数:方法名 // 方法名有一个参数时 第五个参数:第一个入参的类型,和第二个参数写法类型 第六个参数:第一个入参的形参名 // 方法名有两个参数时 第七个参数:第二个入参的类型,和第二个参数写法类型 第八个参数:第二个入参的形参名 ... */ CHOptimizedMethod1(self, void, DetailViewController, loginButtonDidClick, UIButton*, sender) { CHSuper1(DetailViewController, loginButtonDidClick, sender); // 调用原方法 NSLog(@"witchan =该方法的入参为:%@", sender); } // Hook两个入参的实例方法 CHOptimizedMethod2(self, id, DetailViewController, loginWithPhone, NSString *, p, password, NSString*, pwd) { id result = CHSuper2(DetailViewController, loginWithPhone, p, password, pwd); // 调用原方法 NSLog(@"witchan =该方法的第一个入参为:%@", p); NSLog(@"witchan =该方法的第二个入参为:%@", pwd); NSLog(@"witchan =该方法的返回值为:%@", result); return result; } // Hook一个入参的类方法,相对于实例方法,只是在Method前多了个Class单词。其他操作完全一样 CHOptimizedClassMethod1(self, id, DetailViewController, factory, id, arg1) { id result = CHSuper1(DetailViewController, factory, arg1); // 调用原方法 NSLog(@"witchan =该方法的入参为:%@", arg1); NSLog(@"witchan =该方法的返回值为:%@", result); /* 由于deb格式、dylib格式还是framework格式,都支持使用c、c++和OC语言进行开发。 以下代码为oc语法的简单示例。 注意:整个插件的写法,和ios开发完全一致,你可以创建新类,也可以调用oc提供的类及相关方法 如果你不熟悉oc语法,请看我公众号的另一篇文章,iOS快速入门:https://mp.weixin.qq.com/s/g89Sdyqc4ONlyAWtXTCwRA */ NSMutableDictionary *params = [NSMutableDictionary dictionary]; params[@"微信公众号"] = @"移动端Android和iOS开发技术分享"; params[@"QQ群"] = @"812546729"; NSData *body = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:nil]; // 调用登录接口 NSURL *loginURL = [NSURL URLWithString:@"https://127.0.0.1:9080/login"]; // 接口 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:loginURL]; // 请求对象 request.HTTPMethod = @"POST"; // 请求方式 [request setValue:@"d83kd9d323" forHTTPHeaderField:@"x-sign"]; // 设置header request.HTTPBody = body; // 注意,HTTPBody是一个16进制数据,一般直接16进制输出,再转换成文本查看 NSURLSession *session = [NSURLSession sharedSession]; // 获取网络对象 NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // 请求结果会调到这 if (error != nil) { NSLog(@"witchan =网络请求出错了"); } else { NSLog(@"witchan =网络请求成功"); } }]; // 创建请求任务 [task resume]; // 发起网络请求 return result; } // 入口函数 CHConstructor { @autoreleasepool { NSLog(@"witchan =FirsFramework hook success!="); // 一般在入口函数输出一条日志,确定你的插件是否加载成功 CHLoadLateClass(DetailViewController); // 步骤2、加载需要Hook的类 CHHook1(DetailViewController, loginButtonDidClick); // 步骤4、注册你需要hook的实例方法 CHHook2(DetailViewController, loginWithPhone, password); CHClassHook1(DetailViewController, factory); // 注册需要hook的类方法 } } ``` ### 3.编译Framework 然后依次选择菜单栏的Product -> Build或快捷键command+b。再选择菜单栏的Product -> Show Build Folder in Finder   ## 4.framework插件使用 使用optool工具把framework插件注入到ipa,该工具主要有两条命令: - 注入:`optool install -c load -p "@executable_path/Frameworks/aaa.framework/aaa" -t demo.app/demo` - 卸载:`optool uninstall -p "@executable_path/Frameworks/aaa.framework/aaa" -t demo.app/demo` 把ipa文件的扩展名改为zip,解压后,得到Payload文件夹:   切换到Payload目录`cd Desktop/Payload`,然后执行注入命令`optool install -c load -p "@executable_path/Frameworks/FirstFramework.framework/FirstFramework" -t ExampleCode.app/ExampleCode`,至此,我们的framework文件已经注入完成: ```bash witchan@witchandeMacBook-Air Payload % optool install -c load -p "@executable_path/Frameworks/FirstFramework.framework/FirstFramework" -t ExampleCode.app/ExampleCode Found thin header... Inserting a LC_LOAD_DYLIB command for architecture: arm64 Successfully inserted a LC_LOAD_DYLIB command for arm64 Writing executable to ExampleCode.app/ExampleCode... witchan@witchandeMacBook-Air Payload % ``` 接下来将Payload文件夹压缩成zip包,然后把扩展名改为ipa,然后用爱思,或其他重签名工具对该ipa进行签名后,即可在越狱或非越狱机上安装使用了。运行后的日志如下:  # 总结 以上就是iOS插件相关的教程,希望该文章对你有所帮助。deb格式的叫插件,其实dylib和framework文件,在iOS里,叫动态库。就和安卓的so文件类似。在这之所以都叫插件,是因为市场需要。 本文所涉及到的源码下载链接: <mark class="encrypted">192K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4k6K6S2F1d9h3k6s2f1X3g2B7d9#2W2n7M7W2b7J5d9X3u0z5N6#2)9J5k6q4A6c8i4K6y4r3M7s2N6V1i4K6y4p5L8i4g2F1j5H3`.`.</mark> 提取码: munc > 提示:阅读此文档的过程中遇到任何问题,请关住工众好【*`移动端Android和iOS开发技术分享`*】或+99 君羊【*`812546729`*】 
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
#逆向分析
#基础理论
#漏洞相关
#程序开发
#HOOK注入
#系统相关
#源码分析
#工具脚本
收藏
・
29
点赞
・
10
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
wx_晨梦
感谢你的积极参与,期待更多精彩内容!
2026-7-16 09:46
miyuecao
感谢你分享这么好的资源!
2026-6-10 17:29
Xherlock
为你点赞!
2026-6-2 11:05
nice_
非常支持你的观点!
2025-7-24 00:50
Lazy.
谢谢你的细致分析,受益匪浅!
2025-2-28 17:16
初恒
+10
为你点赞!
2024-11-11 15:11
维克托
为你点赞~
2024-4-22 00:38
wx_funcrever
为你点赞~
2023-7-6 10:49
呼吸24K纯氧
为你点赞~
2023-1-16 11:44
伟叔叔
为你点赞~
2022-12-5 15:31
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
3
)
初恒
雪 币:
827
活跃值:
(2368)
能力值:
( LV3,RANK:20 )
在线值:
发帖
5
回帖
45
粉丝
15
关注
私信
初恒
2
楼
好贴
2024-11-11 15:11
0
Tony96
雪 币:
1312
活跃值:
(1281)
能力值:
( LV2,RANK:10 )
在线值:
发帖
0
回帖
5
粉丝
0
关注
私信
Tony96
3
楼
够详细的,给楼主点赞
2025-3-4 10:36
0
北乐游
雪 币:
0
活跃值:
(30)
能力值:
( LV2,RANK:10 )
在线值:
发帖
0
回帖
1
粉丝
0
关注
私信
北乐游
4
楼
谢谢
2026-5-1 14:30
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
witchan
25
发帖
29
回帖
10
RANK
关注
私信
他的文章
[原创]【iOS逆向与安全】让 Claude、Codex 控制 iPhone,iOS MCP 来了
3907
[原创]【iOS逆向与安全】在iOS状态栏中实现秒表功能的插件开发指南
1705
[分享]在 macOS Sequoia (macOS 15) 中无法运行 Xcode 15 的解决方案
3079
[分享]亲测IDA PRO 9.0.240807 Inter版报错解决方案
8233
【iOS逆向与安全】iOS远程大师:通过H5后台远程查看和协助iPhone设备
6384
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部