2026-06-09

方案一:ios-class-guard

  原理

  解析 ObjC 的 __DATA,__objc_classlist 和 __DATA,__objc_methnames 段,生成一份映射表,在编译期通过 -D

  宏把类名/方法名替换成随机短字符串。

  接入方式

  # Build Phase 脚本

  ios-class-guard --sdk-root "$SDKROOT" \

    --symbols-map "$SRCROOT/symbols.json" \

    "$TARGET_BUILD_DIR/$EXECUTABLE_PATH"

  优点

  - 开箱即用,成本最低

  - 支持黑白名单,可以排除第三方库

  缺点

  - 项目已停止维护(最后更新 2015 年)

  - Swift 代码无效,只针对 ObjC

  - 偶发与 Category、Protocol 冲突导致崩溃

  - 映射表文件泄露后等于白做

  适合场景: 纯 ObjC 老项目,快速接入

  ---

  方案二:手写混淆脚本

  原理

  Build Phase 里跑 Python/Shell

  脚本,用正则扫描源文件,把类名/方法名批量改写为无意义字符串,同时维护一份映射表用于还原崩溃日志。

  典型实现

  # 扫描所有 .h/.m,把 CX 前缀的类名替换

  # CXOrderViewController → Bx7kQm3ViewController

  # 维护 symbols_map.json 用于 dSYM 还原

  优点

  - 完全可控,针对自己业务代码定制

  - 可以同时处理 ObjC + Swift

  - 崩溃日志可通过映射表还原,不影响排查问题

  - 不依赖第三方工具

  缺点

  - 需要自己开发和维护脚本

  - 正则替换容易误伤(注释、字符串里的类名)

  - 需要处理好 Storyboard/XIB 里的类名引用

  适合场景: ObjC/Swift 混编项目,想要长期维护的方案

  ---

  方案三:obfuscator-llvm(OLLVM)

  原理

  在编译器层面对 IR(中间表示)做变换,包括:

  - 控制流平坦化:把 if/else/for 变成一个巨大的 switch-case 状态机

  - 虚假控制流:插入永远不会执行的分支迷惑分析

  - 指令替换:把 a+b 替换成等价但更复杂的位运算

  // 原始逻辑

  if (x > 0) { doA(); } else { doB(); }

  // 平坦化后

  int state = 0x3F2A;

  while(1) {

      switch(state) {

          case 0x3F2A: state = (x>0) ? 0x1B4C : 0x7E9D; break;

          case 0x1B4C: doA(); state = 0xFFFF; break;

          case 0x7E9D: doB(); state = 0xFFFF; break;

          case 0xFFFF: goto end;

      }

  }

  优点

  - 混淆强度最高,对抗 IDA Pro 等逆向工具效果好

  - 作用于所有语言(ObjC/Swift/C/C++)

  缺点

  - 需要替换 Xcode 的 Clang 编译器,接入复杂

  - 包体积增大 20%~50%

  - 编译时间大幅增加

  - 控制流平坦化可能引入性能问题

  - Apple 审核也可能因为异常的控制流结构触发人工审查

  适合场景: 对安全要求极高的场合(金融/支付核心模块),不适合全量使用

  ---

  横向对比

  ┌────────────┬─────────────────┬──────────┬─────────┐

  │            │ ios-class-guard │ 手写脚本 │  OLLVM  │

  ├────────────┼─────────────────┼──────────┼─────────┤

  │ 接入难度  │ 低              │ 中      │ 高      │

  ├────────────┼─────────────────┼──────────┼─────────┤

  │ 维护成本  │ 低(但已废弃)  │ 中      │ 高      │

  ├────────────┼─────────────────┼──────────┼─────────┤

  │ 混淆强度  │ 低              │ 中      │ 高      │

  ├────────────┼─────────────────┼──────────┼─────────┤

  │ 包体积影响 │ 无              │ 无      │ +20~50% │

  ├────────────┼─────────────────┼──────────┼─────────┤

  │ Swift 支持 │ 否              │ 是      │ 是      │

  ├────────────┼─────────────────┼──────────┼─────────┤

  │ 崩溃可还原 │ 是              │ 是      │ 较难    │

  └────────────┴─────────────────┴──────────┴─────────┘

  实际推荐组合:

  ▎ 字符串混淆(你已有)+ 手写脚本混淆类名/方法名 = 覆盖 90% 的静态分析场景,成本可控。OLLVM

  ▎ 只在核心支付/加密模块单独开启。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容