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
   | #include "llvm/IR/Function.h" #include "llvm/Pass.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/CommandLine.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/IR/Module.h" #include "llvm/IR/Instructions.h" #include "SplitBasicBlock.h" #include "Utils.h" #include <vector> #include <cstdlib> #include <ctime>  using std::vector;  using namespace llvm;
  static cl::opt<int> obfuTimes("bcf_loop",cl::init(1),cl::desc("Obfucase a function <bcf_loop> time().")); namespace{     class BogusControlFlow : public FunctionPass{         public:             static char ID;             BogusControlFlow():FunctionPass(ID){                 srand(time(NULL));             }             bool runOnFunction(Function &F);             void bogus(BasicBlock *BB);             Value * createBogusCmp(BasicBlock *insertAfter);     }; }
  bool BogusControlFlow::runOnFunction(Function &F){     INIT_CONTEXT(F);     FunctionPass *pass =createSplitBasicBlockPass();     pass->runOnFunction(F);      for(int i=0;i<obfuTimes;i++){         vector<BasicBlock*> origBB;         for(BasicBlock& BB:F){             origBB.push_back(&BB);         }         for(BasicBlock *BB:origBB){             bogus(BB);         }      }      return true;
  } Value *BogusControlFlow::createBogusCmp(BasicBlock * insertAfter){          Module *M=insertAfter->getModule();     GlobalVariable *xptr= new GlobalVariable(*M,TYPE_I32,false,GlobalValue::CommonLinkage,CONST_I32(0),"x");            GlobalVariable *yptr= new GlobalVariable(*M,TYPE_I32,false,GlobalValue::CommonLinkage,CONST_I32(0),"y");            LoadInst *x=new LoadInst(TYPE_I32,xptr,"",insertAfter);           LoadInst *y=new LoadInst(TYPE_I32,yptr,"",insertAfter);      ICmpInst *cmp1=new ICmpInst(*insertAfter,CmpInst::ICMP_SLT,y,CONST_I32(10));     BinaryOperator *opt1=BinaryOperator::CreateAdd(x,CONST_I32(1),"",insertAfter);     BinaryOperator *opt2=BinaryOperator::CreateMul(x,opt1,"",insertAfter);      BinaryOperator *opt3=BinaryOperator::CreateSRem(opt2,CONST_I32(2),"",insertAfter);     ICmpInst *cmp2=new ICmpInst(*insertAfter,CmpInst::ICMP_EQ,opt3,CONST_I32(0));     return BinaryOperator::CreateOr(cmp1,cmp2,"",insertAfter);      } void BogusControlFlow::bogus(BasicBlock *entryBB){          BasicBlock *bodyBB=entryBB->splitBasicBlock(entryBB->getFirstNonPHI(),"BodyBB");     BasicBlock *endBB=bodyBB->splitBasicBlock(bodyBB->getTerminator(),"endBB");
           BasicBlock *cloneBB=createCloneBasicBlock(bodyBB);
                entryBB->getTerminator()->eraseFromParent();         bodyBB->getTerminator()->eraseFromParent();         cloneBB->getTerminator()->eraseFromParent();          Value *cond1 =createBogusCmp(entryBB);     Value *cond2 =createBogusCmp(bodyBB);           BranchInst::Create(bodyBB,cloneBB,cond1,entryBB);          BranchInst::Create(endBB,cloneBB,cond2,bodyBB);          BranchInst::Create(bodyBB,cloneBB);
  } char BogusControlFlow::ID=0; static RegisterPass<BogusControlFlow> X("bcf","My control bogus control flattening obfuscation");
 
   |