对 IPA 二进制文件直接做混淆与加固,无需源码。核心功能参照 ipaguard/iOS Guard 的能力设计,包含命令行版与 Electron GUI 版。
| 模块 | 能力 |
|---|---|
| 代码混淆 | OC 类名 / 方法名(selector)/ 类型编码扫描、重命名(长度不变,原地改写 Mach-O 字符串节),同时改写符号表 _OBJC_CLASS_$_、-[Class method:] 等入口 |
| 符号映射 | parse 导出符号映射文件(与 ipaguard 相同格式),崩溃时可凭 refactorName 反查原名 |
| 风险分级 | 低 / 中 / 高:被 JS 等资源文件引用、被 __cstring 字符串引用、类型编码、运行时关键 selector(dealloc/cxx_destruct/init 等)自动标记为高风险且默认不混淆 |
| 系统 selector 保护 | 仅"应用内定义"(方法表 name 指针 + selrefs 间接引用,兼容 chained-fixup 编码)的 selector 可改名;纯引用系统类(如 dictionaryWithObjects:forKeys:count:)的 selector 一律保留,避免运行时消息派发崩溃 |
| 文件混淆 | 资源文件名重命名(白名单 / 黑名单 / 风险过滤三种模式),自动跳过 Info.plist 引用、xib/storyboard/strings/framework/Assets.car 等 |
| 资源处理 | 修改图片 MD5(PNG tEXt 块 / JPEG COM 段 / GIF 注释扩展,规范内写法)、不可见水印、JS/CSS/HTML 压缩 |
| 指令替换 | --instr 对 __text 节做 ARM64 指令级等义改写(mov/add/uxtb/and 等 1:1 替换,不触碰标志位、内存与控制流),增加静态分析难度 |
| 垃圾代码 | junkcode 生成 OC / Swift 垃圾代码包(MVC 结构 + registerJunkCodes 注册入口,支持词库,输出 IPAGuardJCCodeSources/) |
| 调试信息 | 删除 Mach-O 调试符号(strip -S,macOS) |
| 重签名 | 提取原 entitlements 重签名(嵌套 framework/appex 各自取自己的 entitlements),支持 ad-hoc 与正式证书 |
| 跨平台 | macOS 可完整运行;Linux / Windows 支持除 strip/codesign 外的全部功能(去调试信息与重签名依赖 macOS 的 strip / codesign) |
make build # 构建 bin/iosguard
make e2e # 端到端测试(自动用 clang 生成测试 IPA 并验证)
make dist # 构建 macOS GUI 应用(zip + dmg)
# 命令行直接使用
./bin/iosguard parse game.ipa -o sym.json --files files.json
# 编辑 sym.json 中的 refactorName / confuse 后:
./bin/iosguard protect game.ipa -c sym.json --auto --strength 2 --image --js \
--rename-files --risk low --adhoc --strip -o guarded.ipaGUI 版:make app(开发模式)或 make dist(产物在 app/dist/)。
iosguard parse <input.ipa|macho> [-o sym.json] [--files files.json]
iosguard protect <input.ipa> -c sym.json [-o out.ipa]
[--auto] [--strength 0|1|2] [--gen random|prefix|suffix|wordlib]
[--prefix X] [--suffix X] [--wordlib lib.txt] [--map map.json]
[--js] [--minify] [--image] [--watermark] [--instr]
[--rename-files] [--mode skip|risk|whitelist|blacklist]
[--risk low,medium,high] [--file-list sel.json]
[--utf8] [--strip] [--identity "证书名"|--adhoc] [--no-sign]
iosguard junkcode -o dir [--oc N] [--swift M] [--wordlib lib.txt]
iosguard resign <input.ipa> [-o out.ipa] [--identity "证书名"|--adhoc]
iosguard inspect <macho>
iosguard version
protect 完成后会在输出 IPA 同目录生成 <out>.syms.json(回填了 refactorName 的完整映射),
崩溃堆栈中的混淆符号可凭此文件反查原名。
[{
"confuse": true,
"name": "_isPreTTS",
"refactorName": "_isPreTTS",
"swiftReferences": [],
"types": ["oc_method_name"],
"definedIns": ["HBuilder"],
"fileReferences": [],
"stringReferences": []
}]refactorName:混淆后的名字,长度必须与原名字节数相同,不能与包内其它字符串重复confuse: false:该符号不参与混淆fileReferences/stringReferences非空表示高风险(被 JS 资源或二进制字符串引用,混淆可能导致运行异常)--auto会自动为confuse: true且refactorName未修改的符号生成同名长随机名
- 解析:解压 IPA,识别 Payload 下所有 Mach-O(主可执行、Frameworks、appex,支持 FAT),用
debug/macho读取__TEXT.__objc_classname/__objc_methname/__objc_methtype/__cstring/__swift5_*各节。 - 混淆:对选中符号在字符串节内做同长原地改写(短于原名时以空格填充),不改变任何指针与节尺寸,
因此符号引用(selrefs / classrefs / 符号表 nlist)全部天然保持一致,无需修复 relocate;同时对符号表字符串
(
_OBJC_CLASS_$_Name、__OBJC_$_INSTANCE_METHODS_Name、-[Name sel:])做等长替换。 - 签名:修改二进制后原签名必然失效,重签名时逐层提取各 bundle 自身 entitlements 再
codesign --force。 - 打包:Go 原生 zip 写出,保留可执行位与符号链接,丢弃
._*/__MACOSX元数据。
- 被字符串引用的类(
NSClassFromString(@"Foo"))改名后会查找失败:这类符号已标记高风险,默认不混淆; 如确需混淆请充分测试。 - JS/H5 桥接类(weex/uni-app 等):JS 里硬编码的类名/方法名不会跟着改,符号映射里的
fileReferences已提示,默认不混淆。 - 改资源文件名同样可能破坏代码内路径引用;白名单模式只改你勾选的文件。
- 正式上架:请用发布证书重签名后再提交;ad-hoc 签名仅用于本机测试。
- 混淆后必须完整回归测试(登录、支付、推送、H5 页面、崩溃堆栈定位用
sym.json反查)。
make build-win 生成 bin/iosguard.exe。Windows 上不可用:--strip(调试信息删除)、签名(依赖
macOS codesign);其余功能(符号混淆、文件改名、MD5、压缩)均可用。GUI 版 make dist-win 打包 zip,
但签名步骤在 Windows 上会报错提示。
cmd/iosguard/ CLI 入口(parse / protect / resign / junkcode / inspect)
internal/macho/ Mach-O 解析(debug/macho + FAT 支持)
internal/syms/ 符号提取、风险分级、原地改名、名称生成器
internal/ipa/ IPA 解包 / 打包(zip)
internal/res/ 文件改名、图片 MD5 / 水印、JS/CSS/HTML 压缩、Info.plist 引用
internal/instr/ ARM64 指令等义替换(--instr)
internal/junk/ OC / Swift 垃圾代码生成(junkcode)
internal/sign/ strip + codesign 重签名(macOS)
app/ Electron GUI(main / preload / renderer)
tools/genicon/ 图标生成
scripts/e2e.sh 端到端测试
- Swift 符号(mangled name)仅做检测与风险标注,不做重命名(依赖 swift 节结构,需单独实现)
--instr仅覆盖 mov/add/uxtb/uxtw/nop 等少量等义规则,不做完整 IR 级混淆- 超大包(>200MB)解析较慢(主要为资源引用扫描)