OLLVM虚假控制流源码分析

文章介绍了LLVM中用于函数混淆的BogusControlFlow技术,包括runOnFunction函数的逻辑,检查输入参数,以及bogus函数如何按照给定概率对基本块进行混淆。在混淆过程中,createAlteredBasicBlock函数用于克隆基本块并处理PHINode和操作数映射。混淆方法涉及向基本块添加无用指令、修改条件判断等,增加代码分析难度。

runOnFunction函数

if (ObfTimes <= 0) {
   
   
        errs()<<"BogusControlFlow application number -bcf_loop=x must be x > 0";
		return false;
      }
if ( !((ObfProbRate > 0) && (ObfProbRate <= 100)) ) {
   
   
        errs()<<"BogusControlFlow application basic blocks percentage -bcf_prob=x must be 0 < x <= 100";
		return false;
      }
const int defaultObfRate = 30, defaultObfTime = 1;

static cl::opt<int>
ObfProbRate("bcf_prob", cl::desc("Choose the probability [%] each basic blocks will be obfuscated by the -bcf pass"), cl::value_desc("probability rate"), cl::init(defaultObfRate), cl::Optional);

static cl::opt<int>
ObfTimes("bcf_loop", cl::desc("Choose how many time the -bcf pass loop on a function"), cl::value_desc("number of times"), cl::init(defaultObfTime), cl::Optional);

这里的ObfTimes对应过来的默认值就是1,对函数进行混淆的次数,ObfProbRate就是30,对基本块进行混淆的概率,分别是opt时传入的参数。

    // check for compatible
      for (BasicBlock &bb : F.getBasicBlockList()) {
   
   
        if (isa<InvokeInst>(bb.getTerminator())) {
   
   
          return false;
        }
      }

枚举这个函数的所有基本块,如果这个函数后面基本块中含有invoke(调用了某个函数),它就不执行了,就退出这个基本块。

if(toObfuscate(flag,&F,"bcf")) {
   
   
        bogus(F);
        doF(*F.getParent());
        return true;
      }

判断有没有bcf也就是虚假控制流,有的话就进入。

bogus函数

  if(ObfProbRate < 0 || ObfProbRate > 100){
   
   
        DEBUG_WITH_TYPE("opt", errs() << "bcf: Incorrect value,"
            << " probability rate set to default value: "
            << defaultObfRate <<" \n");
        ObfProbRate = defaultObfRate;
      }
 if(ObfTimes <= 0){
   
   
        DEBUG_WITH_TYPE("opt", errs() << "bcf: Incorrect value,"
            << " must be greater than 1. Set to default: "
            << defaultObfTime <<" \n");
        ObfTimes = defaultObfTime;
      }

首先进行判断这个次数和概率,是否符合条件,不符合的话会进行设置默认值。
紧接着就是一个大型的do while循环里面包含着的代码:

 		std::list<BasicBlock *> basicBlocks;
          for (Function::iterator i=F.begin();i!=F.end();++i) {
   
   
            basicBlocks.push_back(&*i);
          }

把所有的基本块放在basicblock list里面。
获取一个随机值,如果符合的话就进入

 if((int)llvm::cryptoutils->get_range(100) <= ObfProbRate){
   
   
              DEBUG_WITH_TYPE("opt", errs() << "bcf: Block "
                  << NumBasicBlocks <<" selected. \n");
              hasBeenModified = true;
              ++NumModifiedBasicBlocks;
              NumAddedBasicBlocks += 3;
              FinalNumBasicBlocks += 3;
              // Add bogus flow to the given Basic Block (see description)
              BasicBlock *basicBlock = basicBlocks.front();
              addBogusFlow(basicBlock, F);
            }else{
   
   
              DEBUG_WITH_TYPE("opt", errs() << "bcf: Block "
                  << NumBasicBlocks <<" not selected.\n");
            }

每个基本块都有ObfProbRate的概率被混淆,即基本块调用了addBogusFlow函数。
这个函数的作用就是对指定函数的每个基本块以ObfProbRate的概率去进行调用函数混淆。

目前源码:

define dso_local i32 @main(i32 %argc, i8** %argv) #0 {
   
   
entry:
  %retval = alloca i32, align 4
  %argc.addr = alloca i32, align 4
  %argv.addr = alloca i8**, align 8
  %a = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  store i32 %argc, i32* %argc.addr, align 4
  store i8** %argv, i8*** %argv.addr, align 8
  %0 = load i8**, i8*** %argv.addr, align 8
  %arrayidx = getelementptr inbounds i8*, i8** %0, i64 1
  %1 = load i8*, i8** %arrayidx, align 8
  %call = call i32 @atoi(i8* %1) #2
  store i32 %call, i32* %a, align 4
  %2 = load i32, i32* %a, align 4
  %cmp = icmp eq i32 %2, 0
  br i1 %cmp, label %if.then, label %if.else

if.then:                                          ; preds = %entry
  store i32 1, i32* %retval, align 4
  br label %return

if.else:                                          ; preds = %entry
  store i32 10, i32* %retval, align 4
  br label %return

return:                                           ; preds = %if.else, %if.then
  %3 = load i32, i32* %retval, align 4
  ret i32 %3
}

addBogusFlow函数1

 Instruction *i1 = &*basicBlock->begin()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寻梦&之璐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值