有一次接手维护一个旧项目,开发团队已经解散,仓库权限也丢失,手里只剩下一个可以运行的 IPA。需求很明确,这个应用需要继续发布新版本,但同时要做一定程度的保护,避免被直接反编译分析。
没有源码意味着很多传统手段无法使用。例如源码层混淆、编译阶段宏处理、代码结构调整都不再可行。能操作的对象只剩下编译后的 IPA。本篇记录的是当时整理的一套流程,目标是在没有源码的前提下,对 IPA 做基本安全处理并重新发布。
整个过程会涉及几个工具:解包工具、签名工具、字符串分析工具,以及 Ipa Guard 这样的 IPA 混淆工具。
一、先分析 IPA 内部内容
拿到 IPA 之后不要急着处理,可以先观察包内部结构。
把 IPA 复制一份并改为 zip:
cp app.ipa app.zip
unzip app.zip
进入目录:
Payload/AppName.app
这里会看到:
- 可执行二进制
- 图片资源
- json / plist 配置
- html / js
- embedded.mobileprovision
如果想了解二进制中暴露的信息,可以运行:
strings AppBinary | head
或者搜索关键字:
strings AppBinary | grep Controller
很多旧项目没有做符号处理,这一步经常可以看到大量业务类名。
二、检查资源目录
资源目录往往比代码更容易暴露信息。
例如:
vip_banner.png
order_config.json
payment_success.html
这些名称已经能够说明功能结构。
如果没有源码,这些文件名称也无法在项目中统一修改。因此需要在 IPA 层进行处理。
三、在 IPA 层做符号混淆
没有源码时,修改类名和方法名需要直接操作二进制。
可以使用 Ipa Guard 对 IPA 执行混淆处理。它的方式是解析 Mach-O 文件并替换符号名称,不依赖项目源码。
加载 IPA 后,工具会列出可执行文件中的符号信息,包括:
- Objective-C 类
- Swift 类
- 方法名称
- 属性名称
在实际操作中,可以选择一些明显暴露业务逻辑的类,例如:
PaymentManager
VipController
UserProfileViewController
勾选后执行混淆,名称会被替换为无意义字符串。
例如:
PaymentManager → a92k3jv
处理后重新查看二进制字符串,会发现这些名称已经消失。
四、处理资源文件名称
资源文件同样可以在 IPA 中直接修改。
在 Ipa Guard 的资源模块中,可以选择需要处理的类型,例如:
- 图片
- json
- html
- js
- mp3
执行处理后,工具会:
- 修改资源名称
- 同步更新引用路径
例如:
vip_background.png
会被替换为:
b93kd2.png
再次解压处理后的 IPA,就可以看到资源目录已经发生变化。
五、对资源做额外保护
如果资源中包含前端页面,可以做两步处理。
第一步是压缩 JS 和 HTML。
可以使用:
terser
或
uglify-js
将脚本压缩后再重新打包到 IPA。
第二步是在 Ipa Guard 中开启图片 MD5 修改。
这样处理后,图片内容不变,但 MD5 值会不同,资源指纹会发生变化。
六、清理调试信息
旧项目打包时有时会留下调试信息。
可以检查二进制:
strings AppBinary | grep NSLog
如果输出很多日志字符串,可以在混淆阶段开启调试信息清理。
Ipa Guard 在处理 IPA 时可以删除部分调试信息,这样重新生成的二进制会更干净。
七、重新签名
混淆或修改资源之后,原有签名会失效。
因此必须重新签名。
可以使用签名工具,例如:
kxsign sign app.ipa \
-c cert.p12 \
-p password \
-m dev.mobileprovision \
-z test.ipa \
-i
参数 -i 会在签名完成后尝试安装到设备。
如果设备已经通过数据线连接,应用会自动安装。
八、安装设备测试
安装成功后,需要完整测试一次应用流程。
重点观察:
- 页面是否正常加载
- H5 页面是否可访问
- 登录流程是否正常
- 是否出现崩溃
如果某个模块异常,可以回到混淆配置中取消对应符号的处理,然后重新生成 IPA。
九、生成发布版本
测试通过后,可以使用发布证书重新签名。
命令与测试阶段类似,只需要更换证书与描述文件。
生成的 IPA 将用于提交 App Store。
需要注意的是,发布证书生成的 IPA 不能直接安装到设备,因此测试必须在开发证书阶段完成。
在只有 IPA 而没有源码的情况下,仍然可以对应用做一定程度的保护。通过分析包结构、混淆类名和方法名、处理资源文件名称、修改 MD5、清理调试信息,再重新签名测试,就能完成一次完整的安全处理流程。