原式子:
a=b+c
混淆后:
a = b - (-c)
a = -(-b + (-c))
r = rand (); a = b + r; a = a + c; a = a - r
r = rand (); a = b - r; a = a + b; a = a + r
原式子:
a = b-c
混淆后:
a = b + (-c)
r = rand (); a = b + r; a = a - c; a = a - r
r = rand (); a = b - r; a = a - c; a = a + r
原指令:
a = b & c
混淆后:
a = (b ^ ~c) & b
a = ~(~a | ~b) & (r | ~r)
原指令:
a = b | c
混淆后:
a = (b & c) | (b ^ c)
a = (((~a & r) | (a & ~r)) ^ ((~b & r) | (b & ~r))) | (~(~a | ~b) & (r | ~r))
原指令:
a = a ^ b
混淆后:
a = (~a & b) | (a & ~b)
a = ((~a & r) | (a & ~r)) ^ ((~b & r) | (b & ~r))
-mllvm -sub : activate instructions substitution
-mllvm -sub_loop=3 : if the pass is activated, applies it 3 times on a function. Default : 1
boolSubstitution::runOnFunction(Function&F){// Check if the percentage is correct
// 验证了 -mllvm -sub_loop=x 这个编译参数的正确性
if(ObfTimes<=0){errs()<<"Substitution application number -sub_loop=x must be x > 0";returnfalse;}Function*tmp=&F;// Do we obfuscate
if(toObfuscate(flag,tmp,"sub")){// 调用toObfuscate函数判断是否需要进行指令替换混淆
substitute(tmp);// 对函数执行指令替换混淆
returntrue;}returnfalse;}
boolSubstitution::substitute(Function*f){Function*tmp=f;// Loop for the number of time we run the pass on the function
inttimes=ObfTimes;// 混淆次数
do{// do-while循环根据传入的混淆次数参数对函数进行指定次数的混淆
for(Function::iteratorbb=tmp->begin();bb!=tmp->end();++bb){// 遍历函数中所有基本块
for(BasicBlock::iteratorinst=bb->begin();inst!=bb->end();++inst){// 遍历基本块中所有的指令
if(inst->isBinaryOp()){// 判断当前指令是否为二进制操作
switch(inst->getOpcode()){// 获取当前二进制操作指令 并根据指令类型进入对应的case分支
caseBinaryOperator::Add:(this->*funcAdd[llvm::cryptoutils->get_range(NUMBER_ADD_SUBST)])(// 用llvm::cryptoutils->get_range获取一个随机数,随机选取函数指针数组中的混淆函数
cast<BinaryOperator>(inst));++Add;break;caseBinaryOperator::Sub:(this->*funcSub[llvm::cryptoutils->get_range(NUMBER_SUB_SUBST)])(cast<BinaryOperator>(inst));++Sub;break;caseInstruction::And:(this->*funcAnd[llvm::cryptoutils->get_range(2)])(cast<BinaryOperator>(inst));++And;break;caseInstruction::Or:(this->*funcOr[llvm::cryptoutils->get_range(2)])(cast<BinaryOperator>(inst));++Or;break;caseInstruction::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
returnfalse;}