最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

当前快讯:一种inlineHook检测方案

来源:博客园


(相关资料图)

定义

inlinehook是修改内存中的机器码来实现hook的方式

我们用frida查看一个函数hook之前和hook之后的机器码,这里以open函数为例:

let bytes_count = 32let address = Module.getExportByName("libc.so","open")let before = ptr(address)console.log("")console.log("[*] before hook: ")console.log(hexdump(before, {    offset: 0,    length: bytes_count,    header: true,    ansi: true  }));let isOutput = falseInterceptor.attach(address, {onEnter:function(args){        if(isOutput) return;let after = ptr(address)        console.log("")console.log("[*] after hook: ")        console.log(hexdump(after, {            offset: 0,            length: bytes_count,            header: true,            ansi: true        }))        isOutput = true},onLeave:function(retv){}});

hook之前:

hook之后:

可见,hook之后,函数开头的字节被修改了

思考

inlinehook只修改了内存中的机器码,而内存中的机器码是从文件加载而来的,所以我们可以将函数在内存中字节和本地对应的字节进行比较,如果不一致,那么可以认为内存中的字节被修改了,即被inlinehook了。

实现

#ifdef __LP64__    const char *lib_path = "/system/lib64/libc.so";#else    const char *lib_path = "/system/lib/libc.so";#endif#define CMP_COUNT 8    const char *sym_name = "open";    struct local_dlfcn_handle *handle = static_cast(local_dlopen(lib_path));    off_t offset = local_dlsym(handle,sym_name);    FILE *fp = fopen(lib_path,"rb");    char file_bytes[CMP_COUNT] = {0};    if(fp != NULL){        fseek(fp,offset,SEEK_SET);        fread(file_bytes,1,CMP_COUNT,fp);        fclose(fp);    }    void *dl_handle = dlopen(lib_path,RTLD_NOW);    void *sym = dlsym(dl_handle,sym_name);    int is_hook = memcmp(file_bytes,sym,CMP_COUNT) != 0;    local_dlclose(handle);    dlclose(dl_handle);    char text[128] = {0};    snprintf(text,128,"Function \"%s\" is Hook: %s",sym_name,is_hook ? "true" : "false");

这里local_开头的函数是读取本地符号偏移库,库代码:https://github.com/luoyesiqiu/local_dlfcn

用frida hook测试demo:frida-trace -U -i "open" -f com.luoye.localdlfcn

关键词: 从文件加载