抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

llvm 创建外部调用函数方法

2023-02-12 15:26:19

sizaif
img

[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*, 但GlobalStringValue类型,

所以通过构建全局变量的形式: 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);

外部函数

外部函数同法一中所指

评论吧



本站总访问量为 访客数为

鲁 ICP 备 20018157 号-1
Copyright 2021 - 2022 sizaif. All Rights Reserved