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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
   | #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 "llvm/IR/IRBuilder.h" #include "Utils.h" #include <vector> #include <cstdlib> #include <ctime>  #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsX86.h" #include "RandomControlFlow.h" using namespace llvm; using std::vector; static cl::opt<int>obfuTimes("rcf_loop",cl::init(1),cl::desc("Obfuscate a function <bef_loop>time(s).")); namespace{     class RandomControlFlow: public FunctionPass{         public:             static char ID;             RandomControlFlow():FunctionPass(ID){                 srand(time(NULL));             }             Value* alterVal(Value *origVar,BasicBlock *insertAfter);                          bool runOnFunction(Function &F);             void insertRandomBranch(Value *randVar,BasicBlock *ifTrue,BasicBlock *ifFalse,BasicBlock *insertAfter);                          bool randcf(BasicBlock *entryBB);                  }; } bool RandomControlFlow::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){             randcf(BB);         }     }     return true;}
  bool RandomControlFlow::randcf(BasicBlock *entryBB){          BasicBlock *bodyBB=entryBB->splitBasicBlock(entryBB->getFirstNonPHI(),"bodyBB");          BasicBlock *endBB=bodyBB->splitBasicBlock(bodyBB->getTerminator(),"endBB");     
           BasicBlock *cloneBB=createCloneBasicBlock(bodyBB);     
           *entryBB->getTerminator()->eraseFromParent();          Function *randfunc=Intrinsic::getDeclaration(entryBB->getModule(),llvm::Intrinsic::x86_rdrand_32);           CallInst *callinst=CallInst::Create(randfunc->getFunctionType(),randfunc,"",entryBB);          Value *randVar=ExtractValueInst::Create(callinst,0,"",entryBB);          insertRandomBranch(randVar,bodyBB,cloneBB,entryBB);     
           bodyBB->getTerminator()->eraseFromParent();          cloneBB->getTerminator()->eraseFromParent();          insertRandomBranch(randVar,bodyBB,endBB,cloneBB);          insertRandomBranch(randVar,endBB,cloneBB,bodyBB);      }
 
  void RandomControlFlow::insertRandomBranch(Value *randVar,BasicBlock *ifTrue,BasicBlock *ifFalse,BasicBlock *insertAfter){     Value *alteredRandVar=alterVal(randVar,insertAfter);          Value *randMod2=BinaryOperator::CreateURem(alteredRandVar,CONST_I32(2),"",insertAfter);          CmpInst *cmp1=new ICmpInst(*insertAfter,ICmpInst::ICMP_EQ,randMod2,CONST_I32(0),"");          BranchInst *branch=BranchInst::Create(ifTrue,ifFalse,cmp1,insertAfter);      }
  Value* RandomControlFlow::alterVal(Value *startVar,BasicBlock *insertAfter){     uint32_t code = rand() % 3;   Value *result;   if (code == 0) {          BinaryOperator *op1 = BinaryOperator::Create(Instruction::Add, startVar,                                                  CONST_I32(1), "", insertAfter);     BinaryOperator *op2 = BinaryOperator::Create(Instruction::Mul, startVar,                                                  op1, "", insertAfter);     BinaryOperator *op3 = BinaryOperator::Create(Instruction::Mul, startVar,                                                  startVar, "", insertAfter);     BinaryOperator *op4 =         BinaryOperator::Create(Instruction::Sub, op2, op3, "", insertAfter);     result = op4;   } else if (code == 1) {          BinaryOperator *op1 = BinaryOperator::Create(Instruction::Mul, startVar,                                                  CONST_I32(3), "", insertAfter);     BinaryOperator *op2 = BinaryOperator::Create(Instruction::Sub, startVar,                                                  CONST_I32(2), "", insertAfter);     BinaryOperator *op3 =         BinaryOperator::Create(Instruction::Mul, op1, op2, "", insertAfter);     BinaryOperator *op4 = BinaryOperator::Create(Instruction::Mul, startVar,                                                  startVar, "", insertAfter);     BinaryOperator *op5 = BinaryOperator::Create(Instruction::Mul, op4,                                                  CONST_I32(3), "", insertAfter);     BinaryOperator *op6 = BinaryOperator::Create(Instruction::Mul, startVar,                                                  CONST_I32(7), "", insertAfter);     BinaryOperator *op7 =         BinaryOperator::Create(Instruction::Sub, op3, op5, "", insertAfter);     BinaryOperator *op8 =         BinaryOperator::Create(Instruction::Add, op6, op7, "", insertAfter);     result = op8;   } else if (code == 2) {          BinaryOperator *op1 = BinaryOperator::Create(Instruction::Sub, startVar,                                                  CONST_I32(1), "", insertAfter);     BinaryOperator *op2 = BinaryOperator::Create(Instruction::Add, startVar,                                                  CONST_I32(3), "", insertAfter);     BinaryOperator *op3 = BinaryOperator::Create(Instruction::Add, startVar,                                                  CONST_I32(4), "", insertAfter);     BinaryOperator *op4 = BinaryOperator::Create(Instruction::Sub, startVar,                                                  CONST_I32(3), "", insertAfter);     BinaryOperator *op5 =         BinaryOperator::Create(Instruction::Mul, op1, op2, "", insertAfter);     BinaryOperator *op6 =         BinaryOperator::Create(Instruction::Mul, op3, op4, "", insertAfter);     BinaryOperator *op7 =         BinaryOperator::Create(Instruction::Sub, op5, op6, "", insertAfter);     BinaryOperator *op8 = BinaryOperator::Create(Instruction::Sub, op7,                                                  CONST_I32(9), "", insertAfter);     result = op8;   }   return result; } FunctionPass *llvm::createRandomControlFlow() {   return new RandomControlFlow(); }
  char RandomControlFlow::ID = 0; static RegisterPass<RandomControlFlow> X("rcf","My Random control flow obfuscation");
   |