llvm 创建外部调用函数方法
2023-02-12 15:26:19
sizaif
[TOC]
法一:
声名参数类型及函数类型
// Fun Ty
static FunctionType *_EntryStackFnTy;
static FunctionType *_TaintHandleTy;
// Fn
static Function *_EntryStackFn;
static Function *_TaintFn;
_TaintHandleTy = FunctionType::get(VoidTy, {Int32Ty, Int32Ty, Int32Ty}, true); // true可变参数
_EntryStackFnTy = FunctionType::get(VoidTy, {Int8PtrTy,Int64Ty}, false);
第三个参数
false
,表示此函数不是可变参数, 若为true
则表明函数是可变参数
在llvm IR中处理并调用函数:
map<StringRef ,GlobalVariable *> fnname2gv;
IRBuilder<> *builder;
....
void handle(Module *mod){
builder = new IRBuilder<>(mod->getContext()); // 声明builder
Int32Ty = IntegerType::getInt32Ty(mod->getContext());
std::vector<Value*>vec_arg;
StringRef fn_name = func->getName();
u64 fn_name_hash = hash64_char(fn_name.str().c_str(), fn_name.size());
// hash(fn_name)
if(!fnname2gv.count(fn_name)){
ArrayType *ty = ArrayType::get(Type::getInt8Ty(mod->getContext()), fn_name.size() + 1);
GlobalVariable *gv = new GlobalVariable(
*mod, ty, true, GlobalValue::InternalLinkage, nullptr,
(funcCount > 0 ? ".funcName." + to_string(funcCount) : ".funcName"));
++funcCount;
gv->setAlignment(MaybeAlign(1));
Constant *arrayValue = ConstantDataArray::getString(mod->getContext(), fn_name, true);
gv->setInitializer(arrayValue);
fnname2gv[fn_name] = gvfnname;
}
vector<Constant *> indices;
indices.push_back(ConstantInt::get(Int64Ty, 0));
indices.push_back(ConstantInt::get(Int64Ty, 0));
vec_arg.push_back(ConstantExpr::getGetElementPtr(fnname2gv[fn_name]->getValueType(),fnname2gv[fn_name],indices));
vec_arg.push_back(ConstantInt::get(Int64Ty,fn_name_hash));
builder->SetInsertPoint(inst);
builder->CreateCall(_EntryStackFn,vec_arg);
}
1.对于字符串类型,无法直接将
string
转换成Value*
, 但GlobalString
是Value
类型,所以通过构建全局变量的形式:
string
->StringRef
->globalString
->Value*
在llvm IR中传递参数应使用
Value*
``` 2.对于可变参数变量 只需要先填充`counts` (告知后面有几个参数,这个`counts`是不包含在可变参数里,需要显式声明的) ; 然后往`vector`里填充即可 例如: ```cpp std:vector<Value*>vec_arg; vec_arg.push_back(ConstantInt::get(Int32Ty,2)); // counts vec_arg.push_back(ConstantInt::get(Int32Ty,10000)); vec_arg.push_back(fnname2gv[fn_name]);
外部函数:
extern "C" void entrystackFunc(char *funcName, u64 fnamehash){
.....
}
extern "C" void _Taint_handle(int inst_type, int isOrNo, int counts, ...){
va_list args;
va_start(args, counts);
for (int idx = 0; idx < counts; idx++)
{
auto temps_va = va_arg(args, void *); // void * 类型接收
u64 tmp = (u64)(temps_va); // 转换到对应的类型
}
va_end(args);
}
法二
声明函数
string entryFuncName("entryFunc");
Function *insertentryFuncDecl(Module *mod)
{
Int64Ty = IntegerType::getInt64Ty(mod->getContext());
FunctionCallee c = mod->getOrInsertFunction(entryFuncName,
FunctionType::getVoidTy(mod->getContext()),
Type::getInt8PtrTy(mod->getContext()),
Int64Ty);
return static_cast<Function *>(c.getCallee());
}
在llvm IR中处理并函数调用
Function *entryFunc = insertentryFuncDecl(mod);
std::vector<Value *> Args;
....
Args.push_back(...)
....
Instruction *entryCall = CallInst::Create(
entryFunc->getFunctionType(),
entryFunc,
Args);
entryCall->insertBefore(inst);
外部函数
外部函数同法一中所指