llvm 创建外部调用函数方法
2023-02-12 15:26:19
sizaif
文章目录
- llvm 创建外部调用函数方法
 - 法一:
 - 声名参数类型及函数类型
 - 在llvm IR中处理并调用函数:
 - 外部函数:
 
- 法二
 - 声明函数
 - 在llvm IR中处理并函数调用
 - 外部函数
 
法一:
声名参数类型及函数类型
// 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里填充即可例如:
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);
 
外部函数
外部函数同法一中所指




















