boolFlattening::runOnFunction(Function&F){Function*tmp=&F;// Do we obfuscate
if(toObfuscate(flag,tmp,"fla")){if(flatten(tmp)){++Flattened;}}returnfalse;}
// Save all original BB
for(Function::iteratori=f->begin();i!=f->end();++i){BasicBlock*tmp=&*i;origBB.push_back(tmp);BasicBlock*bb=&*i;//当某一个块的末尾是Invoke指令,即调用其他函数指令 则不进行保护
if(isa<InvokeInst>(bb->getTerminator())){returnfalse;}}//原始块太少,也不进行保护
if(origBB.size()<=1){returnfalse;}
//在保存的第一个基本块的列表中去除第一个基本块
origBB.erase(origBB.begin());//将insert指向第一个基本块
Function::iteratortmp=f->begin();//++tmp;
BasicBlock*insert=&*tmp;// If main begin with an if
BranchInst*br=NULL;//如果第一个基本块的最后一条指令是分支指令,则br指向这条分支指令
if(isa<BranchInst>(insert->getTerminator())){br=cast<BranchInst>(insert->getTerminator());}//如果br是一个有条件跳转,则会对这个基本块进行分割,将分支跳转指令连同前一条指令一起分割为一个新的基本块,并命名为first
if((br!=NULL&&br->isConditional())||insert->getTerminator()->getNumSuccessors()>1){BasicBlock::iteratori=insert->end();--i;if(insert->size()>1){--i;}BasicBlock*tmpBB=insert->splitBasicBlock(i,"first");origBB.insert(origBB.begin(),tmpBB);}
转换前后的IR指令对比图如下:
在第一个基本块的末尾添加switchVar变量并为其赋值
1
2
3
4
5
6
// Create switch variable and set as it
switchVar=newAllocaInst(Type::getInt32Ty(f->getContext()),0,"switchVar",insert);ConstantInt*first_num=ConstantInt::get(Type::getInt32Ty(f->getContext()),llvm::cryptoutils->scramble32(0,scrambling_key));newStoreInst(first_num,switchVar,insert);
// Create main loop
loopEntry=BasicBlock::Create(f->getContext(),"loopEntry",f,insert);loopEnd=BasicBlock::Create(f->getContext(),"loopEnd",f,insert);load=newLoadInst(switchVar,"switchVar",loopEntry);// Move first BB on top
insert->moveBefore(loopEntry);BranchInst::Create(loopEntry,insert);// loopEnd jump to loopEntry
BranchInst::Create(loopEntry,loopEnd);BasicBlock*swDefault=BasicBlock::Create(f->getContext(),"switchDefault",f,loopEnd);BranchInst::Create(loopEnd,swDefault);// Create switch instruction itself and set condition
switchI=SwitchInst::Create(&*f->begin(),swDefault,0,loopEntry);switchI->setCondition(load);// Remove branch jump from 1st BB and make a jump to the while
f->begin()->getTerminator()->eraseFromParent();BranchInst::Create(loopEntry,&*f->begin());
// Put all BB in the switch
for(vector<BasicBlock*>::iteratorb=origBB.begin();b!=origBB.end();++b){BasicBlock*i=*b;ConstantInt*numCase=NULL;// Move the BB inside the switch (only visual, no code logic)
i->moveBefore(loopEnd);// Add case to switch
numCase=cast<ConstantInt>(ConstantInt::get(switchI->getCondition()->getType(),llvm::cryptoutils->scramble32(switchI->getNumCases(),scrambling_key)));switchI->addCase(numCase,i);}
// Recalculate switchVar
for(vector<BasicBlock*>::iteratorb=origBB.begin();b!=origBB.end();++b){BasicBlock*i=*b;ConstantInt*numCase=NULL;//①如果该基本块无后继基本块,则不进行处理
// Ret BB
if(i->getTerminator()->getNumSuccessors()==0){continue;}//②如果该基本块最后一条指令为无条件跳转,即有1个后继基本块,找到后继基本块对应的case,更新switchVar值,然后无条件跳转到loopEnd
// If it's a non-conditional jump
if(i->getTerminator()->getNumSuccessors()==1){// Get successor and delete terminator
BasicBlock*succ=i->getTerminator()->getSuccessor(0);i->getTerminator()->eraseFromParent();// Get next case
numCase=switchI->findCaseDest(succ);// If next case == default case (switchDefault)
if(numCase==NULL){numCase=cast<ConstantInt>(ConstantInt::get(switchI->getCondition()->getType(),llvm::cryptoutils->scramble32(switchI->getNumCases()-1,scrambling_key)));}// Update switchVar and jump to the end of loop
newStoreInst(numCase,load->getPointerOperand(),i);BranchInst::Create(loopEnd,i);continue;}//③如果该基本块最后一条指令为有条件跳转,即有2个后继基本块,找到2个后继基本块对应的case,将其标记为numCaseTrue和numCaseFalse,然后创建1个select指令,计算出一个case值用来更新switchVar值,最后无条件跳转到loopEnd
// If it's a conditional jump
if(i->getTerminator()->getNumSuccessors()==2){// Get next cases
ConstantInt*numCaseTrue=switchI->findCaseDest(i->getTerminator()->getSuccessor(0));ConstantInt*numCaseFalse=switchI->findCaseDest(i->getTerminator()->getSuccessor(1));// Check if next case == default case (switchDefault)
if(numCaseTrue==NULL){numCaseTrue=cast<ConstantInt>(ConstantInt::get(switchI->getCondition()->getType(),llvm::cryptoutils->scramble32(switchI->getNumCases()-1,scrambling_key)));}if(numCaseFalse==NULL){numCaseFalse=cast<ConstantInt>(ConstantInt::get(switchI->getCondition()->getType(),llvm::cryptoutils->scramble32(switchI->getNumCases()-1,scrambling_key)));}// Create a SelectInst
BranchInst*br=cast<BranchInst>(i->getTerminator());SelectInst*sel=SelectInst::Create(br->getCondition(),numCaseTrue,numCaseFalse,"",i->getTerminator());// Erase terminator
i->getTerminator()->eraseFromParent();// Update switchVar and jump to the end of loop
newStoreInst(sel,load->getPointerOperand(),i);BranchInst::Create(loopEnd,i);continue;}}