# ollvm源码分析之指令替换（1）

4 篇文章 1 订阅

### ollvm

ollvm总体框架与llvm一致，如下图所示。

• Module
• Function
• BasicBlock
• Instruction

OLLVM有三个Pass以实现混淆，分别为Substitution、BogusControlFlow、flattening。它们位于Transforms/Obfuscation/目录。

### Pass之Substitution

#### 1 替换

a=b+ca=b-(-c)
a=b+ca= -(-b + (-c))
a=b+cr = rand (); a = b + r; a = a + c;a = a – r
a=b+cr = rand (); a = b - r; a = a + b; a = a + r
##### 1.2 Sub

a=b-ca=b+(-c)
a=b-cr = rand (); a = b + r; a = a - c;a = a – r
a=b-cr = rand (); a = b - r; a = a -c;a = a + r
##### 1.3 And

a=b&ca=(b^~c)&b
a=a&b!(!a | !b) & (r | !r)
##### 1.4 Or

a=b|ca=(b&c)|(b^c)
a|b[(!a & r) | (a & !r) ^ (!b & r) |(b & !r) ] | [!(!a | !b) & (r |!r)]
##### 1.5 Xor

a=a^ba = (!a & b) | (a & !b)
a=a^b(a ^ r) ^ (b ^ r)或(!a & r | a & !r) ^ (!b & r | b & !r)
##### 1.6 命令

-mllvm -sub激活指令替换
-mllvm -sub_loop=3若已被激活，进行3次替换，默认为1

#### 2

-mllvm -sub激活指令替换
-mllvm -sub_loop若激活了指令替换，在函数中应用指令替换的次数

#### 3 代码分析

namespace {

struct Substitution : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
void (Substitution::*funcSub[NUMBER_SUB_SUBST])(BinaryOperator *bo);
void (Substitution::*funcAnd[NUMBER_AND_SUBST])(BinaryOperator *bo);
void (Substitution::*funcOr[NUMBER_OR_SUBST])(BinaryOperator *bo);
void (Substitution::*funcXor[NUMBER_XOR_SUBST])(BinaryOperator *bo);
bool flag;

Substitution() : FunctionPass(ID) {}

Substitution(bool flag) : FunctionPass(ID) {
this->flag = flag;

funcSub[0] = &Substitution::subNeg;
funcSub[1] = &Substitution::subRand;
funcSub[2] = &Substitution::subRand2;

funcAnd[0] = &Substitution::andSubstitution;
funcAnd[1] = &Substitution::andSubstitutionRand;

funcOr[0] = &Substitution::orSubstitution;
funcOr[1] = &Substitution::orSubstitutionRand;

funcXor[0] = &Substitution::xorSubstitution;
funcXor[1] = &Substitution::xorSubstitutionRand;
}

bool runOnFunction(Function &F);
bool substitute(Function *f);

void subNeg(BinaryOperator *bo);
void subRand(BinaryOperator *bo);
void subRand2(BinaryOperator *bo);

void andSubstitution(BinaryOperator *bo);
void andSubstitutionRand(BinaryOperator *bo);

void orSubstitution(BinaryOperator *bo);
void orSubstitutionRand(BinaryOperator *bo);

void xorSubstitution(BinaryOperator *bo);
void xorSubstitutionRand(BinaryOperator *bo);
};
}


##### 3.1 入口函数 runOnFunction

bool Substitution::runOnFunction(Function &F) {
// Check if the percentage is correct
if (ObfTimes <= 0) {
errs()<<"Substitution application number -sub_loop=x must be x > 0";
return false;
}

Function *tmp = &F;
// Do we obfuscate
if (toObfuscate(flag, tmp, "sub")) {
substitute(tmp);
return true;
}

return false;
}


##### 3.2 substitute函数
bool Substitution::substitute(Function *f) {
Function *tmp = f;

// Loop for the number of time we run the pass on the function
int times = ObfTimes;
do {
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()) {
// Substitute with random add operation
cast<BinaryOperator>(inst));
break;
case BinaryOperator::Sub:
// case BinaryOperator::FSub:
// Substitute with random sub operation
(this->*funcSub[llvm::cryptoutils->get_range(NUMBER_SUB_SUBST)])(
cast<BinaryOperator>(inst));
++Sub;
break;
case BinaryOperator::Mul:
case BinaryOperator::FMul:
//++Mul;
break;
case BinaryOperator::UDiv:
case BinaryOperator::SDiv:
case BinaryOperator::FDiv:
//++Div;
break;
case BinaryOperator::URem:
case BinaryOperator::SRem:
case BinaryOperator::FRem:
//++Rem;
break;
case Instruction::Shl:
//++Shi;
break;
case Instruction::LShr:
//++Shi;
break;
case Instruction::AShr:
//++Shi;
break;
case Instruction::And:
(this->*
funcAnd[llvm::cryptoutils->get_range(2)])(cast<BinaryOperator>(inst));
++And;
break;
case Instruction::Or:
(this->*
funcOr[llvm::cryptoutils->get_range(2)])(cast<BinaryOperator>(inst));
++Or;
break;
case Instruction::Xor:
(this->*
funcXor[llvm::cryptoutils->get_range(2)])(cast<BinaryOperator>(inst));
++Xor;
break;
default:
break;
}              // End switch
}                // End isBinaryOp
}                  // End for basickblock
}                    // End for Function
} while (--times > 0); // for times
return false;
}


// 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 =

// Check signed wrap
//op->setHasNoSignedWrap(bo->hasNoSignedWrap());
//op->setHasNoUnsignedWrap(bo->hasNoUnsignedWrap());
} else {
op = BinaryOperator::CreateFNeg(bo->getOperand(1), "", bo);
op = BinaryOperator::Create(Instruction::FAdd, bo->getOperand(0), op, "",bo);
}

bo->replaceAllUsesWith(op);
}


BinaryOperator::CreateNeg(bo->getOperand(1), “”, bo)指将c变成-c；BinaryOperator::Create(Instruction::Add, bo->getOperand(0), op, “”, bo)指b+(-c)；
bo->replaceAllUsesWith(op)指更新老的操作数。

• 1
点赞
• 3
收藏
觉得还不错? 一键收藏
• 0
评论
04-09 182
11-17 253
10-29 1万+
02-27 2419
04-09 902
04-12 1174
04-07 404
04-07 312

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。