文章目录
代码混淆壳
- 分为
- Java 级别的代码混淆
- 加密保护型的第一代壳
- 原生程序的代码混淆
- 代码混淆的第三代壳
- Java 级别的代码混淆
- 源于 LLVM 编译套件的编译器特性,通过编写 LLVM Pass 对编译原生程序时生成的 LLVM IR 进行操作,可实现类似 Windows 平台 VMProtect 等虚拟机软件壳的加密保护效果
- 目前 Android 平台最高级别的软件加密技术
LLVM 基础
-
LLVM 不是单一的编译器,是一个可重用的、与编译器相关的组件集合,包含:
- LLVM source code
- LLVM 源码,包含 LLVM 所有核心功能库
- Clang source code
- Clang 前端源码
- Compiler-rt source code
- 编译器运行时
- libc++ source code
- 开源的 C++ 标准库的实现
- libc++abi source code
- 开源的 C++ 标准库 ABI 的实现
- libunwind source code
- 异常展开库
- LLD source code
- 链接器
- LLDB source code
- 调试器
- OpenMP source code
- OpenMP 并行库的实现
- Polly source code
- Polly 库
- Clang-tools-extra
- Clang 前端的额外工具
- LLVM test suite
- LLVM 测试套件
- LLVM source code
-
传统的编译器采用三步设计法(Three Phase Design)设计,按照程序的生成步骤为编译器设计了前端(Frontend)、优化器(Optimizer)、后端(Backend)共三个功能模块
- 前端
- 负责解析代码,检查代码中的错误,生成与语言相关的抽象语法树(AST)
- 由前端生成的 AST 可选择性的生成供优化器处理的中间表示形式
- 优化器
- 负责对前端生成的中间结果优化处理
- 后端
- 将优化器的处理结果生成与处理器相关的平台指令集
- 前端
-
LLVM 沿用三步设计法
-
基于 LLVM 的编译器,由前端生成的 AST 首先会转换成 LLVM 的中间表示(LLVM IR),然后由 LLVM 提供的优化器优化处理,优化器会加载当前 LLVM IR 使用的 LLVM Pass,对 LLVM IR 层层优化,最后交给后端生成与平台相关的机器指令
-
LLVM 优化器的框架
-
以 LLVM 编译套件中的 Clang 编译器为例,其编译器前端实现是一个 clangFrontend 动态库模块,在代码中被抽象成 ASTFrontendAction 类,LLVM 的优化器是一个命令行程序 opt,它将传入的 LLVM Pass 用于 LLVM IR,LLVM Pass 可理解为“流程”,既可嵌入编译系统,也可以动态库形式单独存在(供 opt 命令行调用)
-
安装最新版本的 LLVM 套件(下载地址)
-
安装 graphviz
apt-get install graphviz
-
app6.c
#include <stdio.h> int nums[5] = { 1, 2, 3, 4, 5}; int for1(int n) { int i = 0; int s = 0; for (i = 0; i < n; i++) { s += i * 2; } return s; } int for2(int n) { int i = 0; int s = 0; for (i = 0; i < n; i++) { s += i * i + nums[n - 1]; } return s; } int dowhile(int n) { int i = 1; int s = 0; do { s += i; } while (i++ < n); return s; } int whiledo(int n) { int i = 1; int s = 0; while (i <= n) { s += i++; } return s; } void if1(int n) { if (n < 10) { printf("the number less than 10\n"); } else { printf("the number greater than or equal to 10\n"); } } void if2(int n) { if (n < 16) { printf("he is a boy\n"); } else if (n < 30) { printf("he is a young man\n"); } else if (n < 45) { printf("he is a strong man\n"); } else { printf("he is an old man\n"); } } int switch1(int a, int b, int i) { switch (i) { case 1: return a + b; break; case 2: return a - b; break; case 3: return a * b; break; case 4: return a / b; break