在“上百个 OLLVM 开源项目”里,为什么`lich4/ollvm-pass`值得关注 ?

7 阅读5分钟

GitHub - lich4/ollvm-pass: Independent hikari

如果你最近在找 OLLVM(Obfuscator-LLVM)相关项目,大概率会遇到一个现实:开源仓库一大堆,但真正“有新东西”的不多。很多项目的核心工作是把经典实现适配到更高版本 LLVM/Clang,能用,但对“工程落地”和“可控混淆”帮助有限。

lich4/ollvm-pass 的定位很明确:基于 LLVM NewPass,把原版 OLLVM + Hikari 等实现“Pass 化”,并补上工程实战中最缺的一块——策略系统与 Xcode 适配


1) 现有主流 OLLVM 项目:大多“版本兼容”,少有“工程增强”

目前主流开源OLLVM如下:

  • obfuscator-llvm/obfuscator:最早公开的 Obfuscator-LLVM,实现了 substitution / bogus control flow / flattening 等经典功能。

  • HikariObfuscator/Hikari:在 Obfuscator 基础上扩展了字符串加密、split basic block、函数包装/调用混淆等能力。

  • KomiMoe/Arkari(goron 系):更偏“间接调用/分支”思路,适配较新 LLVM。

  • za233/Polaris-Obfuscator:在 IR 之外,还加入部分 MIR-level 的混淆(例如 dirty bytes、MIR 指令替换等)。

  • open-obfuscator/o-mvll:强调“Python 驱动 + pass manager”,功能覆盖面广。

问题在于:大量衍生仓库的新增内容主要是“兼容 LLVM 高版本”,对于真实工程里“只混淆关键模块/关键函数”“别把编译时间搞爆”“别让 App 上架出风险”这些需求,往往并没有直接给出体系化解决方案。


2) 从“改 LLVM 源码”到“动态 Pass”:OLLVM 的更现代打开方式

早期(LLVM 3.x 时代)做 OLLVM 之所以常见“直接改 LLVM 源码”,一个重要背景是:生态与机制还不成熟;而今天,绝大多数 IR-level 混淆完全可以通过 Pass 插件实现

LLVM Pass 机制的大致演进(简化版)是:

  • LLVM 5–12:主要是 LegacyPassManager

  • LLVM 13–14:默认 Legacy,同时支持 NewPassManager

  • LLVM 15–至今:默认 NewPassManager

动态 Pass(Pass 插件)落地的工程优势

这也是 lich4/ollvm-pass 强调的核心价值之一:

  • 省掉编译 LLVM/Clang 的巨量成本:你可以直接使用系统里已有的 LLVM(Homebrew/apt 等),只要 Clang 大版本匹配即可。

  • 编译与迭代极快:最终产物通常就是一个几 MB 的动态库,而不是几百 MB 的 clang 或几个 GB 的 toolchain。

  • 开发体验好:写 Pass、调 Pass、验证 IR 输出,迭代速度和门槛都更友好。

同时也要诚实面对边界:Pass 很难覆盖 MIR/MC 级别的混淆(这也是为什么像 Polaris 会额外做 MIR-level 增强)。


3) lich4/ollvm-pass 做了什么:不是“又一个移植仓库”,而是“工程可用的 Pass 化方案”

项目介绍写得很直白:它基于 LLVM NewPass,把 original OLLVM + Hikari 变成独立 Pass,用来验证“IR 级混淆可以独立 Pass 实现”,并在 macOS 15 + LLVM 15–19 上测试。

更关键的是,它补齐了两项对落地特别重要的能力:


a) 支持“策略语法”:用 policy.json 精确控制到模块/函数粒度

现实工程里,很多团队并不是“不想全量混淆”,而是“不能全量混淆”:

  • 项目/依赖太大,混淆无关代码导致产物膨胀

  • 平坦化等重混淆导致编译变慢甚至卡死

  • 复杂算法被混淆后运行时开销明显上升(flattening 常见 +10% 级别)

  • 混淆过度可能影响 AppStore/GooglePlay 上架策略与合规风险

这些点在项目 README 里有明确描述。

因此,“可控混淆”比“能混淆”更重要。而开源 OLLVM 常见的控制方式要么粗(只到模块),要么侵入代码,要么语言受限(比如注解只对 C/C++ 友好)。

ollvm-pass 的做法:通过工作目录下的 policy.json 来声明规则,兼容大多数前端与语言,并区分模块级/函数级策略;同时支持“前向覆盖”、可选字段注释、IR dump 等工程特性。

你可以把它理解成:把“混淆开关”从编译命令行/代码侵入,升级成“可审计、可复用、可版本管理”的策略配置——这对大项目、多模块、多语言混编(尤其移动端)非常关键。


b) 适配 Xcode:给 iOS/macOS 工程一个现实可行的接入路径

很多人踩过同一个坑:开源 Clang ≠ Xcode 自带 Apple clang,动态 Pass 直接塞进 Xcode 往往不灵。ollvm-pass 在 README 里给了三条可选路线:

  1. Xcode 指定 CC 为开源 clang,并在 Other C Flags 里加 -fpass-plugin

  2. Xcode 指定 CC 为脚本:先 clang -emit-llvm 出 bitcode,再 opt 跑 Pass,最后 clang -c 产出 obj(仓库提供了作者自用脚本 xcode_cc.sh),并强调对 arm64e 兼容更友好

  3. 直接为 Apple clang 做动态 Pass(难度高,需要处理符号冲突,适合 LLVM 老手)

这部分的价值在于:它不是只告诉你“理论上可行”,而是把“工程接入的现实路径”摆出来,并给了可直接用的脚手架(脚本)。


适合谁用?

  • 你不想再为了一个 OLLVM 工程去编一套几 GB 的 toolchain,希望“几分钟编 Pass,马上验证效果

  • 你需要在真实项目里“只混淆关键模块/关键函数”,并且希望策略可版本管理、可审计

  • 你要面向 iOS/macOS(Xcode/Apple clang 生态),希望有可落地的接入方案

如果你把 OLLVM 当成“能跑 demo 就行”,那很多移植仓库都够用;但如果你把它当成“要进生产、要可控、要能维护”,那么 lich4/ollvm-pass 这种“Pass 化 + 策略化 + Xcode 适配”的方向,明显更接近工程答案。

参考

  1. GitHub - lich4/ollvm-pass: Independent hikari

  2. GitHub - lich4/awesome-ollvm: List of (truly) awesome Obfuscator-LLVMs and IDA deobfuscation plugins

  3. OLLVM学习 | 超哥的博客