linux下hook memset函数
memset在libc.so中。hook可以帮助我们查找一些问题,比如hook memset可以根据某些memset参数特征记录一些信息,可以记录下调用栈信息。
hook的代码:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
typedef void *(*func_memset)(void *s, int c, size_t n);
func_memset f_memset = NULL;
void *memset(void *s, int c, size_t n)
{
if (!f_memset)
f_memset = (func_memset)dlsym(RTLD_NEXT, "memset"); // 这样就会从下一个链接库中查找memset函数,一般都是从libc.so中找到
printf("hello memset s %p, c %d, n %lu\n", s, c, n);
// backtrace();
return f_memset(s, c, n);
}
可以将这个代码编译成动态链接库,也可以直接编译到项目中。
gcc -shared -m64 -ldl -fPIC hook.c -o libhook.so
假设上面的代码保存到
hook.c
文件中。
比如编译成链接库libhook.so
,那么还可以设置环境变量LD_PRELOAD=libhook.so
的方式使用。注意编译时需要加-ldl
链接库。
使用LD_PRELOAD:
LD_PRELOAD=libhook.so exec
hook memset
函数与其它函数的不同点在tcmalloc这种内存分配优化库也会使用到。tcmalloc使用LD_PRELOAD方式加载时,会在进程启动时就会执行一些函数。
Linux下使用环境变量LD_PRELOAD加载链接库的方法可以网上搜索。
与tcmalloc不兼容
进程启动时,dl会先加载一些链接库,加载链接库的函数会分配内存,比如使用tcmalloc库分配内存,tcmalloc里面会使用memset。那么hook memset的话,会使用到dlsym
,dlsym
又会分配内存,又使用到memset
。这就会导致死循环。所以hook memset与tcmalloc是不兼容的。可以自己实现一个简单的memset函数。
参考链接