OLLVM-Windows环境上编译安装-移植到llvm18-移植到android studio


OLLVM-Windows环境上编译安装-移植到llvm18-移植到android-studio使用

0x0 参考文章

编译LLVM源码

https://cyrus-studio.github.io/blog/posts/%E7%BC%96%E8%AF%91-llvm-%E6%BA%90%E7%A0%81%E4%BD%BF%E7%94%A8-clion-%E8%B0%83%E8%AF%95-clang/

移植OLLVM到LLVM18

https://cyrus-studio.github.io/blog/posts/%E7%A7%BB%E6%A4%8D-ollvm-%E5%88%B0-llvm-18cc++%E4%BB%A3%E7%A0%81%E6%B7%B7%E6%B7%86/

移植OLLVM到Android NDK Android Studio

https://juejin.cn/post/7451580780750995495

LLVM安装与编译

编译链环境下载

Android Studio中下载NDK

Tools->SDK manager

image-20250208203009489

Visual Studio 安装环境

搜索x64 Native Tools Command Prompt for VS

image-20250208203156583

python 安装依赖

pip install pygments pyyaml

下载LLVM

https://releases.llvm.org/

下载18.1.8版本

git clone --depth 1 --branch llvmorg-18.1.8 https://github.com/llvm/llvm-project.git

用visual studio的x64 Native Tools Command Prompt for VS 启动控制台

编译命令

cd F:\llvm\llvm-project  \\你自己存放的路径

mkdir build   \\新建一个文件夹存放编译后的文件

cd build

cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="/utf-8" -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_EH=ON -DLLVM_ENABLE_PROJECTS="llvm;clang;lld" ../llvm

我是117个g,注意硬盘空间

image-20250208203549288

OLLVM安装

下载Obfuscation

https://github.com/DreamSoule/ollvm17/tree/main/llvm-project/llvm/lib/Passes

然后复制Obfuscation到 LLVM 工程 llvm/lib/Passes/

image-20250208203817126

编辑CMakeLists.txt

复制进去

Obfuscation/Utils.cpp
Obfuscation/CryptoUtils.cpp
Obfuscation/ObfuscationOptions.cpp
Obfuscation/BogusControlFlow.cpp
Obfuscation/IPObfuscationContext.cpp
Obfuscation/Flattening.cpp
Obfuscation/StringEncryption.cpp
Obfuscation/SplitBasicBlock.cpp
Obfuscation/Substitution.cpp
Obfuscation/IndirectBranch.cpp
Obfuscation/IndirectCall.cpp
Obfuscation/IndirectGlobalVariable.cpp

image-20250208203903061

编辑PassBuilder.cpp

// 导入 Obfuscation 相关头文件
#include "Obfuscation/BogusControlFlow.h" // 虚假控制流
#include "Obfuscation/Flattening.h"  // 控制流平坦化
#include "Obfuscation/SplitBasicBlock.h" // 基本块分割
#include "Obfuscation/Substitution.h" // 指令替换
#include "Obfuscation/StringEncryption.h" // 字符串加密
#include "Obfuscation/IndirectGlobalVariable.h" // 间接全局变量
#include "Obfuscation/IndirectBranch.h" // 间接跳转
#include "Obfuscation/IndirectCall.h" // 间接调用
#include "Obfuscation/Utils.h" // 为了控制函数名混淆开关 (bool obf_function_name_cmd;)


// 添加命令行支持
static cl::opt<bool> s_obf_split("split", cl::init(false), cl::desc("SplitBasicBlock: split_num=3(init)"));
static cl::opt<bool> s_obf_sobf("sobf", cl::init(false), cl::desc("String Obfuscation"));
static cl::opt<bool> s_obf_fla("fla", cl::init(false), cl::desc("Flattening"));
static cl::opt<bool> s_obf_sub("sub", cl::init(false), cl::desc("Substitution: sub_loop"));
static cl::opt<bool> s_obf_bcf("bcf", cl::init(false), cl::desc("BogusControlFlow: application number -bcf_loop=x must be x > 0"));
static cl::opt<bool> s_obf_ibr("ibr", cl::init(false), cl::desc("Indirect Branch"));
static cl::opt<bool> s_obf_igv("igv", cl::init(false), cl::desc("Indirect Global Variable"));
static cl::opt<bool> s_obf_icall("icall", cl::init(false), cl::desc("Indirect Call"));
static cl::opt<bool> s_obf_fn_name_cmd("fncmd", cl::init(false), cl::desc("use function name control obfuscation(_ + command + _ | example: function_fla_bcf_)"));


PassBuilder::PassBuilder( ... ) : ... {
...
    // 注册 Obfuscation 相关 Pass
    this->registerPipelineStartEPCallback(
        [](llvm::ModulePassManager &MPM,
           llvm::OptimizationLevel Level) {
          outs() << "[OLLVM] run.PipelineStartEPCallback\n";
          obf_function_name_cmd = s_obf_fn_name_cmd;
          if (obf_function_name_cmd) {
            outs() << "[OLLVM] enable function name control obfuscation(_ + command + _ | example: function_fla_)\n";
          }
          MPM.addPass(StringEncryptionPass(s_obf_sobf)); // 先进行字符串加密 出现字符串加密基本块以后再进行基本块分割和其他混淆 加大解密难度
          llvm::FunctionPassManager FPM;
          FPM.addPass(IndirectCallPass(s_obf_icall)); // 间接调用
          FPM.addPass(SplitBasicBlockPass(s_obf_split)); // 优先进行基本块分割
          FPM.addPass(FlatteningPass(s_obf_fla)); // 对于控制流平坦化
          FPM.addPass(SubstitutionPass(s_obf_sub)); // 指令替换
          FPM.addPass(BogusControlFlowPass(s_obf_bcf)); // 虚假控制流
          MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
          MPM.addPass(IndirectBranchPass(s_obf_ibr)); // 间接指令 理论上间接指令应该放在最后
          MPM.addPass(IndirectGlobalVariablePass(s_obf_igv)); // 间接全局变量
          MPM.addPass(RewriteSymbolPass()); // 根据yaml信息 重命名特定symbols
        }
    );
}

下面的注册代码注意括回 一直复制到 ); 即可

image-20250208204053325

接下来就是解决报错 基本上原文章讲的都要做一遍,但是和文章中我的不同

error C2039: “getInt8PtrTy”: 不是 “llvm::Type” 的成员

文章中是

llvm::PointerType::get(llvm::Type::getInt8Ty(Context), 0);

我们更改的时候只需要 将Type::getInt8Ty() 替换成PointerType::get(,0)

image-20250208204400618

但是我还报了一个错 StringEncryption.cpp 引用了IRB.getInt8Ty()

直接改成

Value *OutBuf = IRB.CreateBitCast(
   Entry->DecGV, llvm::PointerType::get(llvm::Type::getInt8Ty(Ctx), 0));

就是文章中所说的修改方法,我是ctx 和 Context一样但是会报错显示 未标识ctx

llvm::LLVMContext Ctx; // 创建 LLVMContext 实例

创建一个即可

image-20250208204702155

2 error C3861: “valueEscapes”: 找不到标识符

直接把代码复制到Utils.cpp中即可

static bool valueEscapes(const Instruction &Inst) {
  if (!Inst.getType()->isSized())
    return false;

  const BasicBlock *BB = Inst.getParent();
  for (const User *U : Inst.users()) {
    const Instruction *UI = cast<Instruction>(U);
    if (UI->getParent() != BB || isa<PHINode>(UI))
      return true;
  }
  return false;
}

后续的报错看原文章即可,一摸一样操作即可 注意原文章改成参数是Inst 我们这个直接 I 即可

传参进来就是I

最后在bulid目录中 ninja编译即可,因为前面编译过llvm 所以这一次会比较快

测试

clang -mllvm -sub 是指令替换混淆
clang -mllvm -bcf 是虚假控制流
clang -mllvm -fla 是控制流平坦化

这里能编译出来即成功

移植到Android Studio中 混淆so文件

将llvm bulid目录下的bin、include、lib文件夹复制到ndk的SDK\ndk\27.1.12297006\toolchains\llvm\prebuilt\windows-x86_64目录下即可

image-20250208205403651

然后就是编译apk,so

image-20250208205439558

创建一个native开发项目,这里如果你只有一个sdk就不用设置

设置你的CMakeList ollvmtest 这里是我的so文件名使用你自己的 其他可以一样

image-20250208205535953

最终build即可

指令替换

image-20250208205706377

虚假控制流

image-20250208205649565

5行代码变成了500行

image-20250208205808793

程序正常运行

image-20250208205850785


文章作者: Blue
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Blue !
评论
  目录