我想通过重新排序一些指令或插入一个新的基本块来操作一个函数.
我的方法可以在下面看到.
我从LLVM IR读取一个模块,然后迭代其内容.
我该如何更改其内容?
克隆是否必要,如果是,我将如何插入新指令?
#include#include #include #include #include #include #include #include using namespace llvm; int main() { LLVMContext context; SMDiagnostic error; std::unique_ptr m = parseIRFile("test.ll", error, context); std::error_code EC; llvm::raw_fd_ostream OS("module", EC, llvm::sys::fs::F_None); WriteBitcodeToFile(m.get(), OS); OS.flush(); std::cout << "Successfully read Module:" << std::endl; std::cout << " Name: " << m->getName().str() << std::endl; std::cout << " Target triple: " << m->getTargetTriple() << std::endl; Module* mod = new Module("obfus", getGlobalContext()); for (auto iter1 = m->getFunctionList().begin(); iter1 != m->getFunctionList().end(); iter1++) { Function &f = *iter1; std::cout << " Function: " << f.getName().str() << std::endl; Function* duplicateFunction = CloneFunction(f, nullptr, /*ModuleLevelChanges=*/false); f.getParent()->getFunctionList().push_back(duplicateFunction); for (auto iter2 = f.getBasicBlockList().begin(); iter2 != f.getBasicBlockList().end(); iter2++) { BasicBlock &bb = *iter2; std::cout << " BasicBlock: " << bb.getName().str() << std::endl; for (auto iter3 = bb.begin(); iter3 != bb.end(); iter3++) { Instruction &inst = *iter3; std::cout << " Instruction " << &inst << " : " << inst.getOpcodeName(); unsigned int i = 0; unsigned int opnt_cnt = inst.getNumOperands(); for(; i < opnt_cnt; ++i) { Value *opnd = inst.getOperand(i); std::string o; // raw_string_ostream os(o); // opnd->print(os); //opnd->printAsOperand(os, true, m); if (opnd->hasName()) { o = opnd->getName(); std::cout << " " << o << "," ; } else { std::cout << " ptr" << opnd << ","; } } std:: cout << std::endl; } } } return 0; }
AlexDenisov.. 5
通常,除非要保留原始版本,否则不需要克隆或复制任何内容.
基本块和指令都有用于插入,移动和替换的API.
要操作块,您可以使用以下方法(注意,将来可能会更改):
void insertInto(Function *Parent, BasicBlock *InsertBefore = nullptr); void moveAfter(BasicBlock *MovePos); void moveBefore(BasicBlock *MovePos); SymbolTableList::iterator eraseFromParent(); void removeFromParent();
同样适用于指示:
void removeFromParent(); SymbolTableList::iterator eraseFromParent(); void insertBefore(Instruction *InsertPos); void insertAfter(Instruction *InsertPos); void moveBefore(Instruction *MovePos); void moveBefore(BasicBlock &BB, SymbolTableList ::iterator I);
我绝对可以推荐查看BasiBlock和Instruction接口,看看他们还有什么.
通常,除非要保留原始版本,否则不需要克隆或复制任何内容.
基本块和指令都有用于插入,移动和替换的API.
要操作块,您可以使用以下方法(注意,将来可能会更改):
void insertInto(Function *Parent, BasicBlock *InsertBefore = nullptr); void moveAfter(BasicBlock *MovePos); void moveBefore(BasicBlock *MovePos); SymbolTableList::iterator eraseFromParent(); void removeFromParent();
同样适用于指示:
void removeFromParent(); SymbolTableList::iterator eraseFromParent(); void insertBefore(Instruction *InsertPos); void insertAfter(Instruction *InsertPos); void moveBefore(Instruction *MovePos); void moveBefore(BasicBlock &BB, SymbolTableList ::iterator I);
我绝对可以推荐查看BasiBlock和Instruction接口,看看他们还有什么.