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");
|