版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ab6326795/article/details/81358247
.../llvm/lib/Transforms 中创建一个子文件夹,例如名字叫做MyPass。然后在此文件夹下创建如下三个文件:CMakeLists.txt、MyPass.exports、MyPass.cpp
CMakeLists.txt内容如下:
# If we don't need RTTI or EH, there's no reason to export anything
# from the hello plugin.
if( NOT LLVM_REQUIRES_RTTI )
if( NOT LLVM_REQUIRES_EH )
set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/MyPass.exports)
endif()
endif()
if(WIN32 OR CYGWIN)
set(LLVM_LINK_COMPONENTS Core Support)
endif()
add_llvm_loadable_module( LLVMMyPass
MyPass.cpp
DEPENDS
intrinsics_gen
PLUGIN_TOOL
opt
)
MyPass.cpp内容如下:
#include"llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
#define DEBUG_TAG "MyPass"
namespace{
struct MyPass : public FunctionPass{
static char ID;
MyPass():FunctionPass(ID){
}
bool runOnFunction(Function &F) override{
errs() << DEBUG_TAG<<": ";
errs() << F.getName() << "\n";
return false;
}
};
}
char MyPass::ID = 0;
static RegisterPass<MyPass> TTT("mypass", "this is mypass!");
MyPass.exports 暂时什么都不写。
在MyPass的上一级目录的CMakeLists.txt里增加 MyPass文件夹,完整内容如下:
好,这里一个超简单的pass我们已经写好了,那么准备一个.cpp文件做测试吧,我这里的Test.cpp内容如下:
#include<stdio.h>
#include<string.h>
int add(int a, int b) {
return a + b;
}
void dump() {
printf("dump entry ...");
}
char* getSoName() {
return strdup("xx.so");
}
然后使用 编译下llvm项目。进入build目录:
cmake -DCMAKE_BUILD_TYPE=Release ../obfuscator/
成功后
make -j7
然后使用clang编译下Test.cpp
llvm-obfuscator/build/bin/clang Test.cpp -O0 -S -emit-llvm -o Test.ll
调用下我们的MyPass
llvm-obfuscator/build/bin/opt' -load llvm-obfuscator/build/lib/LLVMMyPass.so -mypass Test.ll
成功打印了函数名!有人可能会问了,为什么函数名都加了_ZXX,那是因为我们的Test.cpp是C++文件,函数支持重载,C++避免函数冲突就会加前缀 和后缀参数缩写。 改成Test.c ,重新编译下,你会发现函数名就原原本本的打印出来了。