Skip to content

Releases: weaiken/ArmorOllvm

v1.0.0-Android-ArmorOllvm-toolschain

09 Apr 09:51
6efd811

Choose a tag to compare

ArmorComp 中文文档

基于 LLVM 17 的 out-of-tree pass plugin 代码混淆框架,主要面向 Android NDK(arm64-v8a / armeabi-v7a)和 iOS。
无需修改 LLVM 源码 —— 构建后通过 -fpass-plugin 加载即可。

33 个混淆 Pass | 支持 arm64(完整 33 个) 和 arm32(IR 级 pass;6 个 AArch64 专属自动跳过)


目录


Pass 一览

Pass 标注 说明
CFFPass cff 控制流平坦化 —— dispatch-switch 循环
BCFPass bcf 虚假控制流 —— 不透明谓词死分支
OpaquePredicatePass op 不透明谓词 —— 6 种公式(P0-P2 恒真 / P3-P5 恒假)
SubPass sub 指令替换 —— 13 种 ADD/SUB/AND/OR/XOR 等价模式
MBAPass mba 混合布尔算术重写 —— 10 种公式
SplitPass split 基本块拆分 —— 膨胀 CFG
StrEncPass strenc 字符串加密 —— XOR 密文 + 构造函数解密
GlobalEncPass genc 全局整数变量加密 —— XOR 加密初始值 + ctor 解密
IndirectCallPass icall 间接调用 —— 不透明指针隐藏调用目标
IndirectBranchPass ibr 间接跳转 —— indirectbr 隐藏跳转目标
IndirectGlobalVariablePass igv 间接全局变量 —— 代理指针隐藏全局变量引用
SPOPass spo 栈指针混淆 —— TPIDR_EL0 双读 XOR 破坏 IDA sp_delta (AArch64)
ConstObfPass co 整数常量混淆 —— XOR-key 分裂隐藏所有数字字面量
FuncWrapPass fw 函数包装混淆 —— 内部转发函数隐藏真实调用者
RetAddrObfPass rao 返回地址混淆 —— TPIDR_EL0 双读 XOR sub/add SP (AArch64)
OutlinePass outline 基本块外提 —— 每个非入口 BB 提取为 __armorcomp_outline_N
FlattenDataFlowPass df 数据流平坦化 —— 所有 alloca 合并到单一 [N x i8]
DataEncodingPass denc 局部变量内存编码 —— 每次 store/load 使用 XOR 编解码
FuncSigObfPass fsig 函数签名混淆 —— 伪造参数读取 + 返回值写入 (AArch64)
DwarfPoisonPass dpoison DWARF CFI 表投毒 —— 破坏 IDA .eh_frame 分析 (AArch64)
ConditionObfPass cob 条件比较混淆 —— ICmpInst 操作数加噪
NeonTypeConfusionPass ntc NEON/FP 类型混淆 —— fmov GPR↔SIMD 误导类型推断 (AArch64)
ReturnValueObfPass rvo 返回值混淆 —— eor x0, x0, volatile_zero(跨平台)
LRObfPass lro 链接寄存器混淆 —— eor x30, x30, volatile_zero (AArch64)
GEPObfPass gepo GEP 索引混淆 —— 破坏 IDA 结构体 / 数组识别
SwitchObfPass sob Switch 混淆 —— 密集跳转表 + indirectbr
JunkCodePass jci 垃圾代码注入 —— 每个 BB 注入不可消除的算术链
ArithmeticStatePass asp CFF 状态变量 XOR 编码 —— 防止 IDA 解析状态机
PointerXorPass pxor 指针 alloca XOR —— ptrtoint/xor/inttoptr 包装
FakeAPICallPass fapi 伪 API 调用注入 —— getpid/getpagesize 噪声
GlobalPointerObfPass gpo 全局函数指针加密 —— ctor 双重 XOR 解密
LoopObfuscationPass lob 循环混淆 —— 循环入口注入垃圾计算链
VMPPass vmp 虚拟机保护 —— 128 寄存器字节码 VM + XTEA 加密 + 完整性校验 + 多态 handler

Android Studio 集成指南

前置要求

组件 版本要求 安装方式
Android Studio 任意版本(已测试 Hedgehog / Iguana / Jellyfish) 官网下载
Android NDK r25+ (推荐 r26b) Android Studio SDK Manager
LLVM 17 Homebrew clang@17 (macOS) 或 clang-17 (Linux) 见下文
CMake >= 3.22 Android Studio SDK Manager
Ninja 任意版本 Android Studio 自带

安装 LLVM 17

macOS (Homebrew):

brew install llvm@17
# 验证安装
/opt/homebrew/opt/llvm@17/bin/clang --version

Linux (apt):

sudo apt install clang-17 libclang-17-dev

为什么需要 brew clang@17?

NDK 自带的 clang 是静态链接 LLVM 的,无法 dlopen 加载 pass plugin。
ArmorComp 需要动态链接的 clang@17 来加载 libArmorComp.dylib
toolchain 中的 launcher 脚本会自动拦截 NDK clang 调用,替换为 brew clang@17 + plugin,
同时保留 NDK 的 --sysroot--target-resource-dir 等交叉编译参数。


方案一:CMake 工具链文件(推荐)

这是最简单的集成方式,适用于使用 CMake 构建 native 代码的 Android 项目。

步骤 1:复制 toolchain 目录

将 ArmorComp 的 toolchain/ 目录复制到你的 Android 项目中:

your-app/
├── app/
│   ├── src/
│   │   ├── main/
│   │   │   ├── cpp/
│   │   │   │   ├── CMakeLists.txt
│   │   │   │   └── native-lib.cpp
│   │   │   └── java/
│   │   └── ...
│   └── build.gradle
├── armorcomp/
│   └── toolchain/            ← 复制到这里
│       ├── bin/
│       ├── lib/
│       │   └── darwin-arm64/libArmorComp.dylib
│       ├── android.cmake     ← 核心工具链文件
│       └── ...
└── build.gradle

步骤 2:修改 app/build.gradle

android {
    // ...

    defaultConfig {
        // ...
        externalNativeBuild {
            cmake {
                // 指向 ArmorComp 的 android.cmake 工具链文件
                arguments "-DCMAKE_TOOLCHAIN_FILE=${rootDir}/armorcomp/toolchain/android.cmake"

                // arm64-v8a: 完整支持全部 33 个 pass
                // armeabi-v7a: 支持 IR 级 pass(6 个 AArch64 专属自动跳过)
                abiFilters "arm64-v8a"
            }
        }
    }

    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.22.1"
        }
    }
}

Kotlin DSL (build.gradle.kts):

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments(
                    "-DCMAKE_TOOLCHAIN_FILE=${rootDir}/armorcomp/toolchain/android.cmake"
                )
                abiFilters("arm64-v8a")
            }
        }
    }
    externalNativeBuild {
        cmake {
            path = file("src/main/cpp/CMakeLists.txt")
            version = "3.22.1"
        }
    }
}

步骤 3:在 C/C++ 源码中添加标注

// native-lib.c

#include <jni.h>
#include <string.h>

// 对核心算法启用 CFF + BCF + VMP 保护
__attribute__((annotate("cff")))
__attribute__((annotate("bcf")))
__attribute__((annotate("vmp")))
JNIEXPORT jint JNICALL
Java_com_example_myapp_MainActivity_verifyLicense(
    JNIEnv *env, jobject thiz, jstring key) {

    const char *nativeKey = (*env)->GetStringUTFChars(env, key, NULL);
    int result = 0;

    // 你的核心验证逻辑...
    if (strcmp(nativeKey, "VALID_KEY") == 0) {
        result = 1;
    }

    (*env)->ReleaseStringUTFChars(env, key, nativeKey);
    return result;
}

// 对字符串加密
__attribute__((annotate("strenc")))
JNIEXPORT jstring JNICALL
Java_com_example_myapp_MainActivity_getApiKey(
    JNIEnv *env, jobject thiz) {

    const char *secret = "sk-AbCdEfGh123456";  // 编译后此字符串会被加密
    return (*env)->NewStringUTF(env, secret);
}

步骤 4:构建运行

在 Android Studio 中直接点击 RunBuild > Make Project

构建日志(Build Output)中会看到 ArmorComp 的输出:

[ArmorComp] Plugin:   .../armorcomp/toolchain/lib/darwin-arm64/libArmorComp.dylib
[ArmorComp] Launcher: .../armorcomp/toolchain/bin/armorcomp-launcher
[ArmorComp] NDK:      .../Android/sdk/ndk/26.1.10909125

[ArmorComp][CFF] flattened: Java_com_example_myapp_MainActivity_verifyLicense
[ArmorComp][BCF] obfuscated: Java_com_example_myapp_MainActivity_verifyLicense
[ArmorComp][VMP] virtualized: Java_com_example_myapp_MainActivity_verifyLicense (N bytecode bytes, M virtual instrs)
[ArmorComp][StrEnc] encrypted 1 string(s) in module

工作原理

Android Studio
    ↓
Gradle → CMake (使用 android.cmake 工具链文件)
    ↓
CMake 发现 CMAKE_TOOLCHAIN_FILE → 加载 android.cmake
    ↓
android.cmake:
  1. 定位 NDK toolchain → include(android.toolchain.cmake)
  2. 定位 libArmorComp.dylib
  3. 设置 CMAKE_C_COMPILER_LAUNCHER = armorcomp-launcher
    ↓
编译时 CMake 调用: armorcomp-launcher <NDK_CLANG> <FLAGS>
    ↓
armorcomp-launcher:
  1. 从 NDK clang 路径推导 resource-dir
  2. 丢弃 NDK clang,替换为 brew clang@17
  3. 注入 -fpass-plugin=libArmorComp.dylib
  4. 保留全部 NDK 编译参数 (--target, --sysroot, ...)
    ↓
brew clang@17 -fpass-plugin=libArmorComp.dylib --target=aarch64-linux-android21 ...
    ↓
LLVM 17 加载 ArmorComp → 运行各 pass → 输出混淆后的 .o
    ↓
NDK linker 链接 → libmynativelib.so (混淆后的 native library)

方案二:ndk-build 集成

适用于仍在使用 Android.mk / ndk-build 的旧项目。

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE    := mynativelib
LOCAL_SRC_FILES := native-lib.cpp secure_logic.c

# 引入 ArmorComp 工具链
include $(LOCAL_PATH)/../../armorcomp/toolchain/armorcomp.mk

include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_ABI      := arm64-v8a
APP_PLATFORM := android-21

armorcomp.mk 会自动将 TARGET_CC / TARGET_CXX 替换为 ArmorComp 的 clang wrapper。


方案三:手动 clang wrapper

适用于不使用 CMake/ndk-build 的自定义构建系统,或需要精确控制编译参数的场景。

# 直接使用 armorcomp-clang 编译单个文件
./armorcomp/toolchain/bin/armorcomp-clang \
    --target=aarch64-linux-android21 \
    --sysroot=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot \
    -O0 \
    -c native-lib.c -o native-lib.o

# 链接(使用 NDK linker)
$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin/ld.lld \
    native-lib.o -o libmynativelib.so -shared \
    --sysroot=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot

函数标注方式

使用 __attribute__((annotate("pass_name"))) 标记需要保护的函数:

// 单个 pass
__attribute__((annotate("cff")))
int my_function(int x) { ... }

// 多个 pass —— 逐个叠加
__attribute__((annotate("cff")))
__attribute__((annotate("bcf")))
__attribute__((annotate("sub")))
__attribute__((annotate("mba")))
int highly_protected(int x) { ... }

// C++ 便捷宏
#define ARMORCOMP(...) __attribute__((annotate("cff"))) \
                       __attribute__((annotate("bcf"))) \
                       __attribute__((annotate("sub")))

ARMORCOMP()
int my_cpp_function(int x) { ... }

可用标注值:
cff bcf op sub mba cob split strenc genc denc jci fapi icall ibr igv spo co gepo fw rao outline df fsig dpoison ntc rvo lro sob asp pxor gpo lob vmp


YAML 配置文件(无需改源码)

适用于保护第三方库或不方便修改源码的场景。

激活方式

# 方式 1: 环境变量
export ARMORCOMP_CONFIG=/path/to/armorcomp.yaml

# 方式 2: 自动发现(工作目录下的 armorcomp.yaml)
# 在项目根目录放置 armorcomp.yaml 即可

在 Android Studio...

Read more