1 添加pass
在目录 lib\Transforms\Obfuscation 新建MySub.cpp
2 何为指令替换
简单来说就是把一些操作指令 替换为同等但是复杂一些的指令集
比如 1+2
我们可以替换为 1-(-2)
也可以替换为
-(-1 + (-2))
这种混淆相对于之前提到的 fla(平坦流) 和 bcf(虚假流) 要简单一些
3 编写测试demo
int myadd(int a ,int b)
{
return a+b;
}
4 pass 编写
bool MySub::substitute(Function *f)
{
Function *tmp = f;
//遍历函数的基本块
for (Function::iterator bb = tmp->begin(); bb != tmp->end(); ++bb) {
遍历基本块的指令
for (BasicBlock::iterator inst = bb->begin(); inst != bb->end(); ++inst)
{
if (inst->isBinaryOp()) {
switch (inst->getOpcode())
{
//如果遇到add 指令 开始替换
case BinaryOperator::Add:
// 随机替换 add指令
(this->*funcAdd[llvm::cryptoutils->get_range(NUMBER_ADD_SUBST)])(
cast<BinaryOperator>(inst));
++Add;
break;
}
}
}
}
return false;
}
// Implementation of a = b - (-c)
void MySub::addNeg(BinaryOperator *bo) {
BinaryOperator *op = NULL;
// Create sub
if (bo->getOpcode() == Instruction::Add) {
//指将c变成-c
op = BinaryOperator::CreateNeg(bo->getOperand(1), "", bo);
//指b-(-c)
op = BinaryOperator::Create(Instruction::Sub, bo->getOperand(0), op, "", bo);
// Check signed wrap
//op->setHasNoSignedWrap(bo->hasNoSignedWrap());
//op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
//更新老的操作数
bo->replaceAllUsesWith(op);
}
}
// Implementation of a = -(-b + (-c))
void MySub::addDoubleNeg(BinaryOperator *bo) {
BinaryOperator *op, *op2 = NULL;
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);
// Check signed wrap
//op->setHasNoSignedWrap(bo->hasNoSignedWrap());
//op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
} else {
op = BinaryOperator::CreateFNeg(bo->getOperand(0), "", bo);
op2 = BinaryOperator::CreateFNeg(bo->getOperand(1), "", bo);
op = BinaryOperator::Create(Instruction::FAdd, op, op2, "", bo);
op = BinaryOperator::CreateFNeg(op, "", bo);
}
bo->replaceAllUsesWith(op);
}
// Implementation of r = rand (); a = b + r; a = a + c; a = a - r
void MySub::addRand(BinaryOperator *bo) {
BinaryOperator *op = NULL;
if (bo->getOpcode() == Instruction::Add) {
Type *ty = bo->getType();
ConstantInt *co =
(ConstantInt *)ConstantInt::get(ty, llvm::cryptoutils->get_uint64_t());
op = BinaryOperator::Create(Instruction::Add, bo->getOperand(0), co, "", bo);
op = BinaryOperator::Create(Instruction::Add, op, bo->getOperand(1), "", bo);
op = BinaryOperator::Create(Instruction::Sub, op, co, "", bo);
// Check signed wrap
//op->setHasNoSignedWrap(bo->hasNoSignedWrap());
//op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
bo->replaceAllUsesWith(op);
}
}
// Implementation of r = rand (); a = b - r; a = a + b; a = a + r
void MySub::addRand2(BinaryOperator *bo) {
BinaryOperator *op = NULL;
if (bo->getOpcode() == Instruction::Add) {
Type *ty = bo->getType();
ConstantInt *co =
(ConstantInt *)ConstantInt::get(ty, llvm::cryptoutils->get_uint64_t());
op = BinaryOperator::Create(Instruction::Sub, bo->getOperand(0), co, "", bo);
op = BinaryOperator::Create(Instruction::Add, op, bo->getOperand(1), "", bo);
op = BinaryOperator::Create(Instruction::Add, op, co, "", bo);
// Check signed wrap
//op->setHasNoSignedWrap(bo->hasNoSignedWrap());
//op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
bo->replaceAllUsesWith(op);
}
}
5 代码解释
1 遍历基本块的指令 opcode
2 如果遇到 add 加指令直接替换 add 替换又4种混淆模式 每次随机一个模式进行替换
// 随机替换 add指令
(this->*funcAdd[llvm::cryptoutils->get_range(NUMBER_ADD_SUBST)])(
cast<BinaryOperator>(inst));
4种混淆模式分别是
//将函数添加到随机list里面
funcAdd[0] = &MySub::addNeg;
funcAdd[1] = &MySub::addDoubleNeg;
funcAdd[2] = &MySub::addRand;
funcAdd[3] = &MySub::addRand2;
6 效果对比
没有指令替换的代码
可以看到划线部分 参数是直接相加的
指令替换后的代码
看到这个RSB 就应该懂了
RSB指令称为逆向减法指令 即 0 减去参数(R1)1
此时 的add 指令已经替换为 1 - (-2)这种模式了