移动安全 ollvm基础 llvm
字数 1639 2025-08-22 12:23:30

LLVM与OLLVM基础教学文档

一、环境准备与LLVM编译

1.1 基础环境配置

使用Ubuntu 18.04系统,需要安装以下基础工具:

su root
apt update
apt install net-tools openssh-server vim build-essential cmake ninja-build

1.2 编译工具说明

  • CMake:跨平台构建工具,管理源文件编译顺序,处理不同OS和编译器的差异
  • Ninja:专注于快速构建的构建系统,比传统构建工具更快
  • build-essential:包含C++编译器等一系列基本构建工具

1.3 LLVM编译步骤

  1. 下载LLVM 10.0.1源码:

    mkdir LLVM
    cd LLVM
    tar -Jxvf llvm-project-10.0.1.tar.xz
    
  2. 配置和编译:

    cd llvm-project-10.0.1
    mkdir build
    cd build
    cmake -G Ninja -DCMAKE_BUILD_TYPE="Release" \
          -DLLVM_ENABLE_PROJECTS="clang" \
          -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" ../llvm
    ninja && ninja install -j4
    

参数说明:

  • -G Ninja:生成Ninja构建文件
  • -DCMAKE_BUILD_TYPE="Release":生产环境构建
  • -DLLVM_ENABLE_PROJECTS="clang":同时构建clang
  • -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi":启用运行时库

二、LLVM基本概念

2.1 编译器架构

LLVM采用三段式设计:

  1. 前端(Frontend)

    • 词法分析
    • 语法分析
    • 语义分析
    • 构建抽象语法树(AST)
  2. 优化器(Optimizer)

    • 代码优化
    • 消除冗余
  3. 后端(Backend)

    • 生成目标机器指令
    • 指令选择
    • 寄存器分配
    • 指令调度

2.2 中间表示(IR)

LLVM IR有两种表示形式:

格式 类型 特点
.ll 文本格式 人类可读,类似汇编
.bc 二进制格式 紧凑高效,用于工具链内部

转换命令:

llvm-as file.ll -o file.bc  # 汇编到二进制
llvm-dis file.bc -o file.ll # 二进制到汇编

2.3 LLVM工具集

工具 功能
bugpoint 调试优化遍数或代码生成后端
llvm-ar 生成包含LLVM位码的归档文件
llvm-as 将LLVM汇编转换为位码
llvm-dis 将位码转换为LLVM汇编
llvm-link 链接多个LLVM模块
lli LLVM解释器/JIT编译器
llc LLVM后端编译器,生成本地代码
opt 应用LLVM到LLVM的转换

三、LLVM Pass开发

3.1 LLVM Pass概念

LLVM Pass是对IR进行特定操作的组件,可用于:

  • 代码优化(提高性能、减小体积)
  • 代码分析(检查问题、验证规则)

工作方式:IR代码流经Pass时被处理

3.2 项目内Pass开发

  1. llvm/lib/Transforms下创建Pass目录

  2. 创建CMakeLists.txt

    add_llvm_library(LLVMPrintName MODULE PrintName.cpp PLUGIN_TOOL opt)
    
  3. 编写Pass代码示例:

    #include "llvm/IR/Function.h"
    #include "llvm/IR/Module.h"
    #include "llvm/Pass.h"
    #include "llvm/Support/raw_ostream.h"
    
    using namespace llvm;
    
    namespace {
    struct PrintFunctionNamePass : public ModulePass {
      static char ID;
      PrintFunctionNamePass() : ModulePass(ID) {}
    
      bool runOnModule(Module &M) override {
        for (auto &F : M) {
          errs() << "函数名: " << F.getName() << "\n";
        }
        return false;
      }
    };
    
    char PrintFunctionNamePass::ID = 0;
    static RegisterPass<PrintFunctionNamePass> X(
      "printname",                  // 命令行标识符
      "打印函数名LLVM Pass",        // 简短描述
      false,                       // 不修改IR
      false                        // 不是分析Pass
    );
    }
    
  4. 编译和使用:

    ninja LLVMPrintName
    opt -load /path/to/LLVMPrintName.so -printname hello.ll -o hello.bc
    

3.3 项目外Pass开发

目录结构:

项目根目录/
├── CMakeLists.txt
└── llvmpass/
    ├── CMakeLists.txt
    └── PrintName.cpp

根目录CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
SET(CMAKE_CXX_FLAGS "-Wall -fno-rtti")
find_package(LLVM REQUIRED CONFIG)
add_definitions(${LLVM_DEFINITIONS})
include_directories(${LLVM_INCLUDE_DIRS})
link_directories(${LLVM_LIBRARY_DIRS})
add_subdirectory(llvmpass)

子目录CMakeLists.txt

add_library(LLVMPrintName MODULE PrintName.cpp)
target_link_libraries(LLVMPrintName PRIVATE ${LLVM_LIBRARY_DIRS})

四、OLLVM基础

OLLVM是基于LLVM的混淆工具,通过对代码结构进行转换增加逆向难度。理解OLLVM需要先掌握LLVM基础知识,特别是:

  1. LLVM IR结构
  2. Pass开发技术
  3. 编译器优化流程

OLLVM主要通过以下Pass实现混淆:

  • 控制流扁平化
  • 指令替换
  • 虚假控制流
  • 字符串加密等

五、常见问题解决

  1. apt锁冲突

    ps aux | grep apt
    sudo kill -9 <PID>
    
  2. 网卡丢失

    service NetworkManager restart
    
  3. 编译中断

    • 重新运行命令会继续之前进度
    • 建议增加内存和CPU核心数

六、参考资料

  1. LLVM官方文档:https://llvm.org/docs/GettingStarted.html
  2. Writing an LLVM Pass:https://releases.llvm.org/9.0.1/docs/WritingAnLLVMPass.html
  3. CMake构建参考:https://stackoverflow.com/questions/17225956/developing-an-llvm-pass-with-cmake-out-of-llvm-source-directory
LLVM与OLLVM基础教学文档 一、环境准备与LLVM编译 1.1 基础环境配置 使用Ubuntu 18.04系统,需要安装以下基础工具: 1.2 编译工具说明 CMake :跨平台构建工具,管理源文件编译顺序,处理不同OS和编译器的差异 Ninja :专注于快速构建的构建系统,比传统构建工具更快 build-essential :包含C++编译器等一系列基本构建工具 1.3 LLVM编译步骤 下载LLVM 10.0.1源码: 配置和编译: 参数说明: -G Ninja :生成Ninja构建文件 -DCMAKE_BUILD_TYPE="Release" :生产环境构建 -DLLVM_ENABLE_PROJECTS="clang" :同时构建clang -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" :启用运行时库 二、LLVM基本概念 2.1 编译器架构 LLVM采用三段式设计: 前端(Frontend) : 词法分析 语法分析 语义分析 构建抽象语法树(AST) 优化器(Optimizer) : 代码优化 消除冗余 后端(Backend) : 生成目标机器指令 指令选择 寄存器分配 指令调度 2.2 中间表示(IR) LLVM IR有两种表示形式: | 格式 | 类型 | 特点 | |------|------|------| | .ll | 文本格式 | 人类可读,类似汇编 | | .bc | 二进制格式 | 紧凑高效,用于工具链内部 | 转换命令: 2.3 LLVM工具集 | 工具 | 功能 | |------|------| | bugpoint | 调试优化遍数或代码生成后端 | | llvm-ar | 生成包含LLVM位码的归档文件 | | llvm-as | 将LLVM汇编转换为位码 | | llvm-dis | 将位码转换为LLVM汇编 | | llvm-link | 链接多个LLVM模块 | | lli | LLVM解释器/JIT编译器 | | llc | LLVM后端编译器,生成本地代码 | | opt | 应用LLVM到LLVM的转换 | 三、LLVM Pass开发 3.1 LLVM Pass概念 LLVM Pass是对IR进行特定操作的组件,可用于: 代码优化(提高性能、减小体积) 代码分析(检查问题、验证规则) 工作方式:IR代码流经Pass时被处理 3.2 项目内Pass开发 在 llvm/lib/Transforms 下创建Pass目录 创建 CMakeLists.txt : 编写Pass代码示例: 编译和使用: 3.3 项目外Pass开发 目录结构: 根目录 CMakeLists.txt : 子目录 CMakeLists.txt : 四、OLLVM基础 OLLVM是基于LLVM的混淆工具,通过对代码结构进行转换增加逆向难度。理解OLLVM需要先掌握LLVM基础知识,特别是: LLVM IR结构 Pass开发技术 编译器优化流程 OLLVM主要通过以下Pass实现混淆: 控制流扁平化 指令替换 虚假控制流 字符串加密等 五、常见问题解决 apt锁冲突 : 网卡丢失 : 编译中断 : 重新运行命令会继续之前进度 建议增加内存和CPU核心数 六、参考资料 LLVM官方文档:https://llvm.org/docs/GettingStarted.html Writing an LLVM Pass:https://releases.llvm.org/9.0.1/docs/WritingAnLLVMPass.html CMake构建参考:https://stackoverflow.com/questions/17225956/developing-an-llvm-pass-with-cmake-out-of-llvm-source-directory