Straw's B1og.

OLLVM-随机控制流

字数统计: 1.1k阅读时长: 5 min
2024/03/19

OLLVM-随机控制流

感觉跟虚假控制流差不多,就是badyBB和cloneBB的定向跳转转到了随机跳转

(建议结合代码食用)

小鸡走

第一步:基本块分割

与虚假控制流相同

第二步:基本块克隆

随机2

第三步:构造随机跳转,插入生成随机数指令,插入随即跳转,对随机数进行恒等变换

随机3

第四步:构造虚假随机数跳转

随机4

代码

RandomControlFlow.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Instructions.h"
#include "SplitBasicBlock.h"
#include "llvm/IR/IRBuilder.h"
#include "Utils.h"
#include <vector>
#include <cstdlib>
#include <ctime>
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "RandomControlFlow.h"
using namespace llvm;
using std::vector;
static cl::opt<int>obfuTimes("rcf_loop",cl::init(1),cl::desc("Obfuscate a function <bef_loop>time(s)."));
namespace{
class RandomControlFlow: public FunctionPass{
public:
static char ID;
RandomControlFlow():FunctionPass(ID){
srand(time(NULL));
}
Value* alterVal(Value *origVar,BasicBlock *insertAfter);
//对随机变量进行恒等变换
bool runOnFunction(Function &F);
void insertRandomBranch(Value *randVar,BasicBlock *ifTrue,BasicBlock *ifFalse,BasicBlock *insertAfter);
//插入随机跳转
bool randcf(BasicBlock *entryBB);
//对基本块进行混淆
};
}
bool RandomControlFlow::runOnFunction(Function &F){
INIT_CONTEXT(F);
FunctionPass *pass=createSplitBasicBlockPass();
pass->runOnFunction(F);
for(int i=0;i<obfuTimes;i++){
vector<BasicBlock*>origBB;
for(BasicBlock &BB:F){
origBB.push_back(&BB);
}
for(BasicBlock *BB:origBB){
randcf(BB);
}
}
return true;}
//以基本块为单位进行随机控制流混淆
bool RandomControlFlow::randcf(BasicBlock *entryBB){
//第一步 将基本块拆分
BasicBlock *bodyBB=entryBB->splitBasicBlock(entryBB->getFirstNonPHI(),"bodyBB");
//拆分出bodyBB
BasicBlock *endBB=bodyBB->splitBasicBlock(bodyBB->getTerminator(),"endBB");
//拆分出endBB

//第二步,对基本块进行克隆,并且修复逃逸变量
BasicBlock *cloneBB=createCloneBasicBlock(bodyBB);
//修复克隆产生的逃逸变量

//第三步,构建随机跳转
*entryBB->getTerminator()->eraseFromParent();
//移除entryBB的终结指令
Function *randfunc=Intrinsic::getDeclaration(entryBB->getModule(),llvm::Intrinsic::x86_rdrand_32);
//获取32位随机数
CallInst *callinst=CallInst::Create(randfunc->getFunctionType(),randfunc,"",entryBB);
//创建call指令插入entryBB的尾部
Value *randVar=ExtractValueInst::Create(callinst,0,"",entryBB);
//将生成的随机数插入到 entryBB的尾部
insertRandomBranch(randVar,bodyBB,cloneBB,entryBB);
//添加随机跳转

//第四步 bodyBB和cloneBB添加随机跳转
bodyBB->getTerminator()->eraseFromParent();
//移除bodyBB的终结指令
cloneBB->getTerminator()->eraseFromParent();
//移除cloneBB的终结指令
insertRandomBranch(randVar,bodyBB,endBB,cloneBB);
//添加cloneBB到endBB的指令,到bodyBB不执行
insertRandomBranch(randVar,endBB,cloneBB,bodyBB);
//添加bodyBB到endBB的指令,到cloneBB不执行
}
//插入随机跳转,随机数为randvar
//如果 randvar %2==1 就跳转到ifTrue ,否则跳转到ifFalse;
void RandomControlFlow::insertRandomBranch(Value *randVar,BasicBlock *ifTrue,BasicBlock *ifFalse,BasicBlock *insertAfter){
Value *alteredRandVar=alterVal(randVar,insertAfter);
//对随机变量进行恒等变换
Value *randMod2=BinaryOperator::CreateURem(alteredRandVar,CONST_I32(2),"",insertAfter);
//对随机变量进行%2
CmpInst *cmp1=new ICmpInst(*insertAfter,ICmpInst::ICMP_EQ,randMod2,CONST_I32(0),"");
//判断结果
BranchInst *branch=BranchInst::Create(ifTrue,ifFalse,cmp1,insertAfter);
//跳转
}
//对变量进行恒等变换
Value* RandomControlFlow::alterVal(Value *startVar,BasicBlock *insertAfter){
uint32_t code = rand() % 3;
Value *result;
if (code == 0) {
// x = x * (x + 1) - x^2
BinaryOperator *op1 = BinaryOperator::Create(Instruction::Add, startVar,
CONST_I32(1), "", insertAfter);
BinaryOperator *op2 = BinaryOperator::Create(Instruction::Mul, startVar,
op1, "", insertAfter);
BinaryOperator *op3 = BinaryOperator::Create(Instruction::Mul, startVar,
startVar, "", insertAfter);
BinaryOperator *op4 =
BinaryOperator::Create(Instruction::Sub, op2, op3, "", insertAfter);
result = op4;
} else if (code == 1) {
// x = 3 * x * (x - 2) - 3 * x^2 + 7 * x
BinaryOperator *op1 = BinaryOperator::Create(Instruction::Mul, startVar,
CONST_I32(3), "", insertAfter);
BinaryOperator *op2 = BinaryOperator::Create(Instruction::Sub, startVar,
CONST_I32(2), "", insertAfter);
BinaryOperator *op3 =
BinaryOperator::Create(Instruction::Mul, op1, op2, "", insertAfter);
BinaryOperator *op4 = BinaryOperator::Create(Instruction::Mul, startVar,
startVar, "", insertAfter);
BinaryOperator *op5 = BinaryOperator::Create(Instruction::Mul, op4,
CONST_I32(3), "", insertAfter);
BinaryOperator *op6 = BinaryOperator::Create(Instruction::Mul, startVar,
CONST_I32(7), "", insertAfter);
BinaryOperator *op7 =
BinaryOperator::Create(Instruction::Sub, op3, op5, "", insertAfter);
BinaryOperator *op8 =
BinaryOperator::Create(Instruction::Add, op6, op7, "", insertAfter);
result = op8;
} else if (code == 2) {
// x = (x - 1) * (x + 3) - (x + 4) * (x - 3) - 9
BinaryOperator *op1 = BinaryOperator::Create(Instruction::Sub, startVar,
CONST_I32(1), "", insertAfter);
BinaryOperator *op2 = BinaryOperator::Create(Instruction::Add, startVar,
CONST_I32(3), "", insertAfter);
BinaryOperator *op3 = BinaryOperator::Create(Instruction::Add, startVar,
CONST_I32(4), "", insertAfter);
BinaryOperator *op4 = BinaryOperator::Create(Instruction::Sub, startVar,
CONST_I32(3), "", insertAfter);
BinaryOperator *op5 =
BinaryOperator::Create(Instruction::Mul, op1, op2, "", insertAfter);
BinaryOperator *op6 =
BinaryOperator::Create(Instruction::Mul, op3, op4, "", insertAfter);
BinaryOperator *op7 =
BinaryOperator::Create(Instruction::Sub, op5, op6, "", insertAfter);
BinaryOperator *op8 = BinaryOperator::Create(Instruction::Sub, op7,
CONST_I32(9), "", insertAfter);
result = op8;
}
return result;
}
FunctionPass *llvm::createRandomControlFlow() {
return new RandomControlFlow();
}

char RandomControlFlow::ID = 0;
static RegisterPass<RandomControlFlow> X("rcf","My Random control flow obfuscation");

效果

效果

感觉混淆一次都已经很难看了,混淆两次更是一坨粑粑,强力混淆(๑•̀ㅂ•́)و✧

CATALOG
  1. 1. OLLVM-随机控制流
    1. 1.1. 第一步:基本块分割
    2. 1.2. 第二步:基本块克隆
    3. 1.3. 第三步:构造随机跳转,插入生成随机数指令,插入随即跳转,对随机数进行恒等变换
    4. 1.4. 第四步:构造虚假随机数跳转
    5. 1.5. 代码
    6. 1.6. 效果