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 里给了三条可选路线:
-
Xcode 指定
CC为开源 clang,并在Other C Flags里加-fpass-plugin -
Xcode 指定
CC为脚本:先clang -emit-llvm出 bitcode,再opt跑 Pass,最后clang -c产出 obj(仓库提供了作者自用脚本xcode_cc.sh),并强调对 arm64e 兼容更友好 -
直接为 Apple clang 做动态 Pass(难度高,需要处理符号冲突,适合 LLVM 老手)
这部分的价值在于:它不是只告诉你“理论上可行”,而是把“工程接入的现实路径”摆出来,并给了可直接用的脚手架(脚本)。
适合谁用?
-
你不想再为了一个 OLLVM 工程去编一套几 GB 的 toolchain,希望“几分钟编 Pass,马上验证效果”
-
你需要在真实项目里“只混淆关键模块/关键函数”,并且希望策略可版本管理、可审计
-
你要面向 iOS/macOS(Xcode/Apple clang 生态),希望有可落地的接入方案
如果你把 OLLVM 当成“能跑 demo 就行”,那很多移植仓库都够用;但如果你把它当成“要进生产、要可控、要能维护”,那么 lich4/ollvm-pass 这种“Pass 化 + 策略化 + Xcode 适配”的方向,明显更接近工程答案。