Linux平台下hook技术研究

    技术2022-07-11  104

    说明

    之前公司,C项目中为了程序检测内存泄漏问题,采用一个自己实现的库,能够记录内存分配和释放操作,程序结束或者通过信号可以生成dump信息来分析内存问题。

    技术分析

    内存分配和释放记录主要是通过hook(钩子)技术来获取的。

    hook技术

    通过预处理实现

    实现方式: 创建一个头文件,通过宏替换的方式替换掉内存分配(malloc,calloc,realloc)和释放函数(free)。创建一个源文件,定义替换函数,在替换函数中记录调用和调用真正的目标函数和做相应处理。 代码示例: * 头文件 MemHook.h #if defined(__cplusplus) extern "C" { #endif #define malloc(size) mmalloc(size , __FILE__, __LINE__) #define calloc(size) mcalloc(size, __FILE__, __LINE__) ..... #define free(p) mfree(p) #if defined(__cplusplus) } #endif * 源码 #include <stdio.h> #include <stdlib.h> //不能引入 MemHook.h void *mmalloc (unsigned long counts, const char* const file , const unsigned long line) { void *buf; printf("%s , %ld\n", file , line); if (NULL == (buf = malloc(counts))) { .... return NULL; } //记录内存分配 .... return buf; } ..... void mfree (void *p) { if (p) { //记录内存释放 ..... free(p); } } 方式优缺点: 需要手动引入该头文件,如果有源码未引入该头文件,会导致操作未记录。

    LD_PRELOAD 环境变量方式

    方式简介:LD_PRELOAD 是在所有动态库前加载该环境变量定义的动态库。方式说明: 实现一个动态库,通过LD_PRELOAD环境变量,在所有动态库前加载。动态库中定义标准的内存分配和释放函数,例如:malloc,calloc,free等;由于先加载,变量设置后运行的程序中调用的这些函数都会被指向该库中的实现。在该库中记录分配和释放记录,以及调用真正的malloc,calloc,free等函数。 代码示例: * 库源码 #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> static void *(*true_malloc)(size_t); static void (*true_free)(void *ptr); void *malloc(size_t size) { void *ptr; if (true_malloc == NULL) { true_malloc = dlsym(RTLD_NEXT, "malloc"); } printf(%d\n", size); ptr = true_malloc(size); //记录分配操作 .... return ptr; } ..... void free(void* ptr) { if (true_free == NULL) { true_free = dlsym(RTLD_NEXT, "free"); } //记录释放操作 .... printf("%p\n", ptr); return true_free(ptr); } * 注意: 1. 函数定义需要和标准的一样。 2. 生成动态库时需要链接 dl库。 * 编译生成动态库 * 设置环境变量 export LD_PRELOAD=./libxxxx.so * 执行其它程序 方式优缺点 替换方式简单,环境变量设置和取消非常方便。
    Processed: 0.011, SQL: 9