Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
zyrox — Zyrox:基于 LLVM 的编译时混淆器插件。 | Kitploit
工具/GitHubGitHub/peterhackz/zyrox
静态分析代码分析逆向工程二进制分析论文与研究学习与教育学习路径与课程
GitHubpeterhackz/zyrox

zyrox

Zyrox:基于 LLVM 的编译时混淆器插件。

查看仓库
9411167个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
网站

Zyrox LLVM 混淆器

用于混淆原生代码的 llvm 编译时和链接时插件

为什么

为什么不呢 ¯\_(ツ)_/¯

这是我最大的项目之一,我在其中学到了很多关于 LLVM 内部机制、二进制格式、汇编和混淆技术的知识。

我相信通过构建来学习是最好的学习方式,因此我构建了这个项目来更深入地了解这些主题。

研究

我写了 4 篇博客来解释 Zyrox 背后的概念:

  • 第一部分:构建 Zyrox:自定义 LLVM 混淆器
  • 第二部分:控制流平坦化
  • 第三部分:加密跳转表
  • 第四部分:终章

这些部分比本 readme 更深入,如果你对这个主题感兴趣,绝对值得一读。

构建

使用模板(快速开始,推荐)

这适合想要 快速测试 Zyrox,或学习如何将其集成到 cmake 项目中的人。

按照 Zyrox Template 仓库中的步骤操作。

从源码构建

安装 llvm:

sudo apt update
sudo apt install llvm-18 llvm-18-dev clang-18

克隆并编译 zyrox:

git clone --recurse-submodules https://github.com/PeterHackz/zyrox.git
cd zyrox
cmake -S . -B build -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++
cmake --build build --parallel 4

Python(编译后)插件设置

确保你已安装 python3 和 pip。

设置环境(推荐)

# Create a virtual environment
python3 -m venv .venv

# Activate the env
source .venv/bin/activate

pip install -r requirements.txt

全局安装

pip install -r requirements.txt

使用

快速使用

clang -O0 -flto=full -c main.c -o out/main.o
clang -flto=full -fuse-ld=lld -Wl,--load-pass-plugin=./build/libzyrox.so out/main.o -o out/main

混淆完成后,运行 PyPlugin.py 来加密跳转表:

# if you installed dependencies in a virtual environment, activate it first:
source .venv/bin/activate
#  then run with:
python PyPlugin.py --in=<input_file> [--out=<output_file>] [--tables=<zyrox_tables_file>] [--android]

使用 CMake

请查看 Zyrox Template 仓库,获取 CMake 集成示例。

联系方式

我明白这是一个复杂的话题,这个项目主要是为了教育目的,同时也服务于 BSD Brawl。 如果你有任何问题,或者只是想聊天,欢迎联系我:

  • Discord:@s.b
  • 邮箱:[email protected] 或 [email protected]
  • Discord 服务器

任何形式的帮助,无论是通过 pull request 还是 issue,都非常感谢!

工作原理

ZyroxPlugin.cpp 注册 pass,然后链接 siphash(稍后详细介绍)并调用 StringEncryption 来加密字符串。

我们提前加密字符串的原因是,这样解密逻辑之后也会被混淆。

然后它调用 ModuleUtils::ExpandCustomAnnotations 和 QuickConfig::RegisterPasses 来解析所有 __attribute__((annotate("..."))) 表达式,并运行 QuickJs 配置(位于 ZyroxConfig.js)。

每个函数都通过调用位于 ZyroxCore.cpp 中的 Zyrox::RunOnFunction 进行混淆, 未来会提供更多相关文档。

额外工具

switch 会创建跳转表,而 PHI 节点处理起来很烦人,因此我们分别使用 FunctionUtils 和 BasicBlockUtils 将其扁平化(转换为 if 语句)和降级。

Passes

哦天哪,我该从哪里开始呢

  • Basic Block Splitter
  • Control Flow Flattening
  • Indirect Branching
  • Simple Indirect Branching
  • Mixed Boolean Arithmetic

所有 js-plugin 参数都在 index.d.ts 中,因此本文档中不再讨论。

关于注解的文档,点击这里

Basic Block Splitter

此 pass 将一个基本块拆分并打乱为多个更小的基本块。假设我们有以下代码:

int __test_fn(int x)
{
    if (x == 2) {
        printf("x is 2\n");
    } else {
        printf("x is not 2!, x is: %d\n", x);
    }
    return x + 4 * x - 2 / 4;
}

它会被编译成:

define internal i32 @__test_fn(i32 noundef %0) #0 !zyrox !8 !obfuscated !11 {
  %2 = alloca i32, align 4
  store i32 %0, ptr %2, align 4
  %3 = load i32, ptr %2, align 4
  %4 = icmp eq i32 %3, 2
  br i1 %4, label %5, label %7

5:                                                ; preds = %1
  %6 = call i32 (ptr, ...) @printf(ptr noundef @.str.1)
  br label %10

7:                                                ; preds = %1
  %8 = load i32, ptr %2, align 4
  %9 = call i32 (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef %8)
  br label %10

10:                                               ; preds = %7, %5
  %11 = load i32, ptr %2, align 4
  %12 = load i32, ptr %2, align 4
  %13 = mul nsw i32 4, %12
  %14 = add nsw i32 %11, %13
  %15 = sub nsw i32 %14, 0
  ret i32 %15
}

当使用 Basic Block Splitter 并使用以下配置时:

z.RegisterPass(ObfuscationType.BasicBlockSplitter, {
    PassIterations: 1,
    "BasicBlockSplitter.SplitBlockChance": 100,
    "BasicBlockSplitter.SplitBlockMinSize": 2,
    "BasicBlockSplitter.SplitBlockMaxSize": 5,
});

它会变成:

define internal i32 @__test_fn(i32 noundef %0) #0 !zyrox !8 !obfuscated !11 {
  %2 = alloca i32, align 4
  store i32 %0, ptr %2, align 4
  %3 = load i32, ptr %2, align 4
  %4 = icmp eq i32 %3, 2
  br i1 %4, label %5, label %14

5:                                                ; preds = %1
  %6 = call i32 (ptr, ...) @printf(ptr noundef @.str.1)
  br label %7

7:                                                ; preds = %14, %5
  %8 = load i32, ptr %2, align 4
  %9 = load i32, ptr %2, align 4
  %10 = mul nsw i32 4, %9
  %11 = add nsw i32 %8, %10
  br label %12

12:                                               ; preds = %7
  %13 = sub nsw i32 %11, 0
  ret i32 %13

14:                                               ; preds = %1
  %15 = load i32, ptr %2, align 4
  %16 = call i32 (ptr, ...) @printf(ptr noundef @.str.2, i32 noundef %15)
  br label %7
}

现在对于这么小的函数来说,差别不会太大,但注意它是如何拆分一个基本块的?这与其他 pass 结合使用时很有帮助,例如 Control Flow Flattening。

Control Flow Flattening

哦天哪,这个 pass 的功能是所有 pass 中最多的,哈哈。 我先解释它的工作原理,然后再介绍它的配置。 假设我们有以下代码:

LABEL_A: bool b = x == 2;
         IF EQ: goto LABEL_B
         goto LABEL_C
LABEL_B  do_stuff()
LABEL_C  do_other_stuff()
         goto LABEL_A

每个基本块(A、B 和 C)都会被分配一个唯一的分发器状态,例如:(简化版)

states = {
    1: LABEL_A,
    2: LABEL_B,
    3: LABEL_C,
};

然后我们注入一个控制所有内容的分发器块,代码变成:

         int state = 0;
LABEL_D  goto LABEL_CA // dispatcher label jumps to first condition block, label condition A
LABEL_CA if state == 1: goto LABEL_A
         // if not 1, go to check if it is label B (fallback)
LABEL_CB if state == 2: goto LABEL_B
LABEL_CC if state == 3: goto LABEL_CC
         // unreachable
         goto LABEL_D
LABEL_A: bool b = x == 2;
         // IF EQ: goto LABEL_B
         // goto LABEL_C
         state = 2 if b else 3 // update state for the block we want and back to dispatcher
         goto LABEL_D
LABEL_B  do_stuff()
LABEL_C  do_other_stuff()
         state = 1
         goto LABEL_D

这个方案有一些缺陷,混淆器会修复这些缺陷。如你所见,由于我们只有一个分发器变量,很容易进行反混淆,因为我们知道一个块在设置状态后会跳转到哪里。很容易修复!

z.RegisterPass(ObfuscationType.ControlFlowFlattening, {
    PassIterations: 1,
    "ControlFlowFlattening.UseFunctionResolverChance": 60,
    "ControlFlowFlattening.UseGlobalStateVariablesChance": 60,
    "ControlFlowFlattening.UseOpaqueTransformationChance": 40,
    "ControlFlowFlattening.UseGlobalVariableOpaquesChance": 80,
    "ControlFlowFlattening.UseSipHashedStateChance": 40,
    "ControlFlowFlattening.CloneSipHashChance": 80,
});

让我们逐一介绍这些选项:

下载工具