3
命令を並べ替えるか、新しい基本ブロックを挿入して関数を操作したい。LLVM:関数内の命令または基本ブロックを変更する
私のアプローチは以下のとおりです。
モジュールをLLVM IRから読み込み、その内容を繰り返し処理します。
どのようにコンテンツを変更しますか?
クローニングが必要な場合は、どうすれば新しい命令を挿入できますか?
#include <iostream>
#include <llvm/IR/Module.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Transforms/Utils/Cloning.h>
using namespace llvm;
int main()
{
LLVMContext context;
SMDiagnostic error;
std::unique_ptr<Module> 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;
}