ITPub博客

首页 > 移动开发 > IOS > IPA 批量混淆怎么做?Ipa Guard 命令行的符号映射与自动化

IPA 批量混淆怎么做?Ipa Guard 命令行的符号映射与自动化

原创 IOS 作者:iOS调试笔记 时间:2026-10-27 11:13:52 0 删除 编辑

界面版和命令行版摆在一起,差别不在混淆能力,在操作方式:前者靠人勾选,后者先把符号导成文件,再让脚本批量跑。一个包还能忍,手上同时有三四个马甲包要发,界面版就有点顶不住了。后来换到 Ipa Guard 的命令行版,parse、改配置、protect 串起来,批量处理才算顺手。这篇就讲 IPA 批量混淆怎么做,按五步走一遍,重点说清楚 sym.json 怎么改,以及崩溃之后怎么用映射把堆栈查回去。

第一步:parse 导出符号文件

界面版是在列表里勾符号,命令行版反过来:先把 IPA 里的符号导出来,成了一个能编辑的文件,再决定改哪些。

1ipaguard_cli parse game.ipa -o sym.json

game.ipa 换成目标包, sym.json 是导出路径。 Ipa Guard 的 parse 子命令会扫描可执行文件,把类名、方法名、属性名这些列出来,每条记录带几个字段:

  • name:原始符号名
  • refactorName:混淆后要替换成的名字,默认和原名一样
  • confuse:这条要不要混淆, true 或 false
  • types:符号类型,比如 oc_method_name
  • fileReferences:哪些文件里引用了这个字符串
  • definedIns:定义在哪个二进制里

多 target 或者带扩展的包,靠 definedIns 能分清同一个名字到底属于哪个二进制。 types 这一列标的是符号类型,其实扫一眼就能知道这份文件里都有哪些东西。 fileReferences 这一项挺有用,它等于提前告诉你「这个名字在别处还有引用」,改之前心里能有个数。比如 addEventListener: 出现在 weexUniJs.js 和 PandoraApi.bundle\all.js 里,那它多半牵着 H5 或 Uni-app 的桥接,别随手改嘛。

一个包对应一份 sym.json。别拿上个版本的符号文件套新包,符号集合变了,映射会对不上。

第二步:改 sym.json,哪些能改、哪些别动

打开 sym.json,真正要动的主要是 refactorName 和 confuse 两个字段。想混淆的符号,把 refactorName 改成无意义的名字;不确定的,把 confuse 设成 false。

1{2  "confuse": false,3  "name": "addEventListener:",4  "refactorName": "addEventListener:",5  "fileReferences": ["weexUniJs.js", "PandoraApi.bundle\\all.js"]6}

文件展示

这里有两条硬要求,得记住: refactorName 的长度要和原名一致,而且不能和同文件里的其他名字重复。 长度变了,替换时容易把二进制里的偏移搞乱;名字重复,两个符号就分不开了。用脚本批量生成新名字时,最好加一道校验,长度和唯一性都过一遍。

哪些符号建议直接设成 false?按我的经验,反射和 KVC 用的名字、xib/storyboard 里的 outlet 和 action、JS 桥接方法、通知名、 NSClassFromString 这类动态查找的字符串,都得谨慎。举个常见的:某个类用了 KVC, setValue:forKey: 的 key 是字符串拼出来的,你把这个属性名改了,运行时找不到 key,直接崩;xib 里的 outlet 也一样,名字改过,连接就断了。命令行版会自动把一部分高风险符号标成不混淆,对 Uni-app 也有额外监测,但自动判断代替不了实际测试。风险等级只是参考,不能完全当标准。说实话,拿不准的符号先别动,混淆范围小一点,比装上去就崩强。

改完先存一份原始 sym.json。后面崩溃回查、重新混淆、排查某个符号有没有被动过,都得靠它。

第三步:protect 批量混淆

符号文件确认完,进入批量混淆这一步:

1ipaguard_cli protect game.ipa -c sym.json --email ipaguard@gmail.com --image --js -o confused.ipa

参数分几块: -c 指定符号文件; -o 指定输出包; --image 决定要不要改图片 MD5; --js 决定要不要混淆 JS; --email 是 Ipa Guard 的登录账号,命令行混淆需要 VIP1 及以上权限。 --image 改的是图片指纹,图片内容不变; --js 会处理 JS 相关文件,H5 或 Uni-app 项目最好先小范围试。两个开关都不是必开,看你的威胁模型和回归测试的承受能力。输出目录最好按版本分开,别和上一版的包混在一起,后面签名和归档都省事。

批量处理可以用 shell 循环。先统一 parse,人工确认每份 sym.json,再统一 protect:

 1# 1. 批量导出符号 2for ipa in build/*.ipa; do 3  base=$(basename "$ipa" .ipa) 4  ipaguard_cli parse "$ipa" -o "sym/$base.json" 5done 6 7# 2. 逐份检查 sym.json 后,再批量混淆 8for ipa in build/*.ipa; do 9  base=$(basename "$ipa" .ipa)10  ipaguard_cli protect "$ipa" -c "sym/$base.json" --image --js -o "out/$base.ipa"11done

这个循环只是把重复动作交给脚本,审查那一步还在人这里。 sym.json 没看过就直接跑,批量出来的可能是一批会崩的包,返工更麻烦呢。批量跑的时候,建议把每份包的 parse 和 protect 输出都落到日志里,哪个包失败了一眼能看到,别等全部跑完再回头找。

第四步:kxsign 签名并安装测试

混淆后的包必须装机测试,别直接拿去提审。签名可以用 kxsign:

1kxsign sign my.ipa -c cert.p12 -p certpassword -m a.mobileprovision -z out.ipa -i

-c 是证书, -p 是证书密码, -m 是描述文件, -z 是签名后的输出路径, -i 表示装到当前连接的测试设备上。测试阶段用开发证书,装得上;上架时换成发布证书,并且不要带 -i。签名失败时先看证书类型和描述文件里的设备列表,别急着怀疑混淆。装上去别只看能不能启动,登录、支付、相机、推送这些容易踩到反射和权限的路径都走一遍;混淆出问题,十有八九是在这些分支上才暴露。

第一次跑签名,可能会卡在设备连接或者开发者镜像上(别问我怎么知道的),这点挺坑。先把 iPhone 解锁、信任电脑,确认驱动正常;镜像没下载完就等一会儿,工具会自己下。真签不过,也可以把重签名和安装测试都关掉,先生成未签名的 IPA,再拿到 Mac 上用 codesign 处理。安装测试跟着重签名模块走,两个都关掉,自然就装不了。

第五步:崩溃后用映射回查原函数

混淆之后最怕的不是崩溃,是崩溃了查不回去。堆栈里全是改过的名字, _a、 _b 这种,光看堆栈根本不知道对应哪个方法。

命令行版会保留符号映射关系, sym.json 里 name 和 refactorName 的对应就是回查的依据。线上崩溃时,拿堆栈里的混淆名去映射文件里反查原名,再结合 dSYM 还原行号,才能定位到具体代码。比如堆栈里出现 _a,在 sym.json 里搜 refactorName 等于 _a 的记录,读回 name,再拿 dSYM 对行号,手动查几次就熟了。映射文件、dSYM、原始 IPA,这三样按版本一起归档,少一样都难受,真出问题能省不少折腾。映射别只留在构建机上,传到团队共享目录或者制品库,换个人排查也能拿到。

版本号也得对上。多个包并行的时候,最容易把 A 版本的映射套到 B 版本的堆栈上,查半天发现方向错了。文件名里带上版本号和构建号,别嫌麻烦。

和界面版、Obfuscator-LLVM 怎么分工

印象里,界面版适合单个包、需要人盯着风险列表做取舍的场景,勾选、过滤、保存配置都直观。命令行版大概更适合批量、接 CI、需要精确控制符号样式的情况,还能拿到映射文件做崩溃回查。接 CI 的时候,把 parse、protect、kxsign 写成脚本,构建完自动出一版混淆包,产物和映射一起归档,省得每次发版手工点。两者用的是同一套混淆能力,差别在操作方式和可控粒度。

Obfuscator-LLVM 走编译期,能做控制流平坦化和指令替换,深度比 IPA 层更靠里,前提是有源码和完整工具链。命令行版不需要源码,直接处理编译后的包,适合手上只有 IPA 的场景。两者可以叠着用:编译期做控制流,IPA 层做符号、资源和调试信息,各补各的盲区。

IPA 批量混淆的流程可以记成五步:parse 导出符号,改 sym.json 并保住长度和唯一性,protect 批量处理,kxsign 签名装真机测试,崩溃后拿映射回查。第一次别拿正式包练手,先找一个测试包把五步跑顺,再扩到整批。

批量混淆省的是重复劳动,不是审查;映射文件留得住,后面才好查。 反正我现在每发一版,映射和 dSYM 都单独存一份,真要出事,起码有据可查。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70046796/viewspace-3186759/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2025-06-17

  • 博文量
    174
  • 访问量
    186016