Straw's B1og.

OLLVM-常量替代

字数统计: 1k阅读时长: 5 min
2024/03/20

OLLVM-常量替代

感觉跟指令替代类似,仅支持32位整数替代

(建议结合代码食用)

替换方案

替换方案

代码

ConstantSubstitution.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
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Transforms/Utils.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Utils/Local.h"
#include "SplitBasicBlock.h"
#include "Utils.h"
#include <vector>
#include <cstdlib>
#include <ctime>
#define MAX_RAND 32767
#define NUMBER_CONST_SUBST 2
using namespace llvm;
using std::vector;
static cl::opt<int> obfuTimes("csub_loop",cl::init(1),cl::desc("Obfucase a function <obfu_loop> time(s)."));
namespace{
class ConstantSubstitution :public FunctionPass{
public :
static char ID;

ConstantSubstitution():FunctionPass(ID){
srand(time(NULL));
}
bool runOnFunction(Function &F);
void substitute(BinaryOperator *BI);
void linearSubstitute(BinaryOperator *BI,int i);
void bitwiseSubstitute(BinaryOperator *BI,int i);
};
}
bool ConstantSubstitution::runOnFunction(Function &F){
INIT_CONTEXT(F);
for(int i=0;i<obfuTimes;i++){
for(BasicBlock &BB:F){
vector<Instruction*>origInst;
for(Instruction &I:BB){
origInst.push_back(&I);
}
for(Instruction *I:origInst){ //遍历所有指令
if(BinaryOperator *BI=dyn_cast<BinaryOperator>(I)){//判断是不是二元运算指令
if(BI->getType()->isIntegerTy(32)){//仅对整数进行替换
substitute(BI);
}
}
}
}
}
}
void ConstantSubstitution::substitute(BinaryOperator *BI){
int operandNum =BI ->getNumOperands();
for(int i=0;i<operandNum;i++){
if(isa<ConstantInt>(BI->getOperand(i))){
int choice =rand()%NUMBER_CONST_SUBST;
switch (choice)
{
case 0:
linearSubstitute(BI,i); // 线性替换
break;
case 1:
bitwiseSubstitute(BI,i);
// bitwiseSubstitute(BI,i); // 按位运算替换
break;
default:
break;
}
}
}

}
void ConstantSubstitution::linearSubstitute(BinaryOperator *BI,int i){
//线性替换 :Val -> ax+by+c
//其中 val 为原常量 a, b 为随机常量 x, y 为随机全局变量 c = val - (ax + by)
Module *M=BI->getModule();
//指定模块
ConstantInt *val=cast<ConstantInt>(BI->getOperand(i));
//获取原来的操作数
int randx=rand()%MAX_RAND,randy=rand()%MAX_RAND;
//创建随机数x,y
int randa=rand()%MAX_RAND,randb=rand()%MAX_RAND;
//创建随机数a,b
APInt c = val->getValue()-(randx*randa+randy*randb);
//c=val-(ax+by)
GlobalVariable *xptr=new GlobalVariable(*M,TYPE_I32,false,GlobalValue::PrivateLinkage,CONST_I32(randx),"x");
//创建x全局变量
//commonLinkage 是未初始化的全局变量,初始值只能为0,不能为其他值。这里我们设置的初始值x不能是0,所以不能设置成commonlinkage
GlobalVariable *yptr=new GlobalVariable(*M,TYPE_I32,false,GlobalValue::PrivateLinkage,CONST_I32(randy),"y");
//创建y全局变量
LoadInst *x=new LoadInst(TYPE_I32,xptr,"",BI);
//读取x
LoadInst *y=new LoadInst(TYPE_I32,yptr,"",BI);
//读取y
BinaryOperator *op1=BinaryOperator::CreateMul(CONST_I32(randa),x,"",BI);
//ax
BinaryOperator *op2=BinaryOperator::CreateMul(CONST_I32(randb),y,"",BI);
//by
BinaryOperator *op3=BinaryOperator::CreateAdd(op1,op2,"",BI);
//ax+by
BinaryOperator *op4=BinaryOperator::CreateAdd(op3,CONST_I32(c.getSExtValue()),"",BI);
//ax+by+c
BI->setOperand(i,op4);

}
void ConstantSubstitution::bitwiseSubstitute(BinaryOperator *BI,int i){
//按位运算替换:val -> (x << 5 | y >> 3) ^ c
//其中 val 为原常量x, y 为随机全局变量 c = val ^ (x << 5 | y >> 3)
Module *M=BI->getModule();
//指定模块
ConstantInt *val=cast<ConstantInt>(BI->getOperand(i));
//获取原来的操作数
int randx=rand()%MAX_RAND,randy=rand()%MAX_RAND;
//随机数
APInt c = val->getValue()^(randx<<5|randy>>3);
//c = val ^ (x << 5 | y >> 3)
GlobalVariable *xptr=new GlobalVariable(*M,TYPE_I32,false,GlobalValue::PrivateLinkage,CONST_I32(randx),"x");
//创建x全局变量
//commonLinkage 是未初始化的全局变量,初始值只能为0,不能为其他值。这里我们设置的初始值x不能是0,所以不能设置成commonlinkage
GlobalVariable *yptr=new GlobalVariable(*M,TYPE_I32,false,GlobalValue::PrivateLinkage,CONST_I32(randy),"y");
//创建y全局变量
LoadInst *x=new LoadInst(TYPE_I32,xptr,"",BI);
//加载x
LoadInst *y=new LoadInst(TYPE_I32,yptr,"",BI);
//加载y
BinaryOperator *op1=BinaryOperator::CreateShl(x,CONST_I32(5),"",BI);
//x<<5
BinaryOperator *op2=BinaryOperator::CreateLShr(y,CONST_I32(3),"",BI);
//y>>3
BinaryOperator *op3=BinaryOperator::CreateOr(op1,op2,"",BI);
//x<<5|y>>3
BinaryOperator *op4=BinaryOperator::CreateXor(op3,CONST_I32(c.getSExtValue()),"",BI);
//c^(x<<5|y>>3)
BI->setOperand(i,op4);
}
char ConstantSubstitution::ID=0;
static RegisterPass<ConstantSubstitution> X("csub","Replace a constant value with equivalent instructions");

效果

效果1

用自己的题目编译混淆了一次,效果还行,试试三次的

效果2

爽了,妈妈再也不用担心我的tea加密被一眼看出来了

令点头

CATALOG
  1. 1. OLLVM-常量替代
    1. 1.1. 替换方案
    2. 1.2. 代码
    3. 1.3. 效果