一 集成流程
具体的编译NDK的LLVM的流程可参考文章:编译NDK特定的LLVM版本的流程记录https://bbs.kanxue.com/thread-277727.htm
add_subdirectory(Obfuscation)
Obfuscation
llvm-projectllvmlibTransformsIPOPassManagerBuilder.cpp
导入头文件:
#include "llvm/Transforms/Obfuscation/BogusControlFlow.h"
#include "llvm/Transforms/Obfuscation/Flattening.h"
#include "llvm/Transforms/Obfuscation/Split.h"
#include "llvm/Transforms/Obfuscation/Substitution.h"
#include "llvm/Transforms/Obfuscation/CryptoUtils.h"
#include "llvm/Transforms/Obfuscation/StringObfuscation.h"
// Flags for obfuscation
static cl::opt<std::string> Seed("seed", cl::init(""), cl::desc("seed for the random"));
static cl::opt<std::string> AesSeed("aesSeed", cl::init(""), cl::desc("seed for the AES-CTR PRNG"));
static cl::opt<bool> StringObf("sobf", cl::init(false), cl::desc("Enable the string obfuscation"));
static cl::opt<bool> Flattening("fla", cl::init(false), cl::desc("Enable the flattening pass"));
static cl::opt<bool> BogusControlFlow("bcf", cl::init(false), cl::desc("Enable bogus control flow"));
static cl::opt<bool> Substitution("sub", cl::init(false), cl::desc("Enable instruction substitutions"));
static cl::opt<bool> Split("split", cl::init(false), cl::desc("Enable basic block splitting"));
// Flags for obfuscation
//obfuscation related pass
MPM.add(createSplitBasicBlockPass(Split));
MPM.add(createBogusPass(BogusControlFlow));
MPM.add(createFlatteningPass(Flattening));
MPM.add(createStringObfuscationPass(StringObf));
MPM.add(createSubstitutionPass(Substitution));
llvm-projectllvmlibTransformsObfuscationStringObfuscation.cpp
文件:
#include "llvm/IR/Instructions.h"
LoadInst *ptr_19 = new LoadInst(gvar->getType()->getArrayElementType(),
gvar, "", false, label_for_body);
ptr_19->setAlignment(Align(8));
...
LoadInst* int8_20 = new LoadInst(ptr_arrayidx->getType()->getArrayElementType(), ptr_arrayidx, "", false, label_for_body);
int8_20->setAlignment(Align(1));
...
void_21->setAlignment(Align(1));
llvm-projectllvmlibTransformsObfuscationSubstitution.cpp
文件的第 215 行:
// Implementation of a = -(-b + (-c))
void Substitution::addDoubleNeg(BinaryOperator *bo) {
BinaryOperator *op, *op2 = NULL;
UnaryOperator *op3, *op4;
if (bo->getOpcode() == Instruction::Add) {
op = BinaryOperator::CreateNeg(bo->getOperand(0), "", bo);
op2 = BinaryOperator::CreateNeg(bo->getOperand(1), "", bo);
op = BinaryOperator::Create(Instruction::Add, op, op2, "", bo);
op = BinaryOperator::CreateNeg(op, "", bo);
bo->replaceAllUsesWith(op);
// Check signed wrap
//op->setHasNoSignedWrap(bo->hasNoSignedWrap());
//op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
} else {
op3 = UnaryOperator::CreateFNeg(bo->getOperand(0), "", bo);
op4 = UnaryOperator::CreateFNeg(bo->getOperand(1), "", bo);
op = BinaryOperator::Create(Instruction::FAdd, op3, op4, "", bo);
op3 = UnaryOperator::CreateFNeg(op, "", bo);
bo->replaceAllUsesWith(op3);
}
}
Substitution::subNeg
函数:
// Implementation of a = b + (-c)
void Substitution::subNeg(BinaryOperator *bo) {
BinaryOperator *op = NULL;
if (bo->getOpcode() == Instruction::Sub) {
op = BinaryOperator::CreateNeg(bo->getOperand(1), "", bo);
op = BinaryOperator::Create(Instruction::Add, bo->getOperand(0), op, "", bo);
// Check signed wrap
//op->setHasNoSignedWrap(bo->hasNoSignedWrap());
//op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
} else {
auto op1 = UnaryOperator::CreateFNeg(bo->getOperand(1), "", bo);
op = BinaryOperator::Create(Instruction::FAdd, bo->getOperand(0), op1, "", bo);
}
bo->replaceAllUsesWith(op);
}
llvm-projectllvmlibTransformsObfuscationBogusControlFlow.cpp
文件 380 添加:
UnaryOperator *op2;
case 1: op2 = UnaryOperator::CreateFNeg(i->getOperand(0),*var,&*i);
opX = new LoadInst (x->getType()->getElementType(), (Value *)x, "", (*i));
opY = new LoadInst (x->getType()->getElementType(), (Value *)y, "", (*i));
llvm-projectllvmincludellvmInitializePasses.h
的第 453 行添加:
void initializeFlatteningPass(PassRegistry&);
llvm-projectllvmlibTransformsObfuscationFlattening.cpp
的 17 行添加:
#include "llvm/InitializePasses.h"
load = new LoadInst(switchVar->getType()->getElementType(), switchVar, "switchVar", loopEntry);
二 混淆效果
Android.mk
的参数配置(全局):
LOCAL_CFLAGS += -mllvm -bcf -mllvm -bcf_loop=4 -mllvm -bcf_prob=100 -mllvm -sub -mllvm -sub_loop=2 -mllvm -fla -mllvm -sobf -mllvm -split
int binaryInsertionSort() __attribute((__annotate__(("bcf"))));
CMakeLists.txt
的参数配置(全局):
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mllvm -sub -mllvm -sobf -mllvm -fla ") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mllvm -sub -mllvm -sobf -mllvm -fla") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -mllvm -sub -mllvm -sobf -mllvm -fla" ) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -mllvm -sub -mllvm -sobf -mllvm -fla" )
__attribute((__annotate__("bcf"))) __attribute((__annotate__("fla"))) __attribute((__annotate__("sub"))) __attribute((__annotate__("split"))) __attribute((__annotate__("sobf"))) void binaryInsertionSort(int arr[], int n) {}
三 总结
参考资料
看雪ID:blx2024
https://bbs.kanxue.com/user-home-928718.htm
原文始发于微信公众号(看雪学苑):NDK集成OLLVM模块流程记录
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论