hook malloc与free出现的问题
#define _gnu_source
#include
#include
#include
/*****************************hook******************************/
typedef void *(*malloc_t)(size_t);
malloc_t malloc_f;
typedef void (*free_t)(void *);
free_t free_f;
static int init_hook() {
malloc_f = dlsym(rtld_next, "malloc");
free_f = dlsym(rtld_next, "free");
}
void *malloc(size_t size) {
printf("in malloc\n");
return null;
}
void free(void *ptr) {
printf("in free\n");
}
/***************************************************************/
int main() {
init_hook();
void *p1 = malloc(10);
void *p2 = malloc(20);
free(p1);
}
出现段错误,gdb看一看
printf函数底层会调用malloc函数,如果程序陷入死循环,会不停的调用malloc。我们下面就要去破坏这个递归
让第一次进入函数的部分执行我们的流程,而递归进去的算第二次进入函数,返回即可。
#define _gnu_source
#include
#include
#include
/*****************************hook******************************/
typedef void *(*malloc_t)(size_t);
int enable_malloc_hook = 1;
malloc_t malloc_f;
typedef void (*free_t)(void *);
int enable_free_hook = 1;
free_t free_f;
static int init_hook() {
malloc_f = dlsym(rtld_next, "malloc");
free_f = dlsym(rtld_next, "free");
}
void *malloc(size_t size) {
if (enable_malloc_hook) {
enable_malloc_hook = 0;
void *p = malloc_f(size);
printf("malloc--->ptr:%p size:%zu\n", p, size);
enable_malloc_hook = 1;
return p;
}
else {
return null;
}
}
void free(void *ptr) {
if (enable_free_hook) {
enable_free_hook = 0;
printf("free --->ptr:%p\n", ptr);
free_f(ptr);
enable_free_hook = 1;
}
else {
return ;
}
}
/***************************************************************/
int main() {
init_hook();
void *p1 = malloc(10);
void *p2 = malloc(20);
free(p1);
}
builtin_return_address(n)
# 编译器提供的函数,返回第n层调用函数
1、gcc默认不支持__builtin_return_address(level)的参数为非0。好像只支持参数为0。
2、__builtin_return_address(0)的含义是,得到当前函数返回地址,即此函数被别的函数调用,然后此函数执行完毕后,返回,所谓返回地址就是那时候的地址。
3、__builtin_return_address(1)的含义是,得到当前函数的调用者的返回地址。注意是调用者的返回地址,而不是函数起始地址。
在__builtin_return_address函数外面套了一层converttovma。目的是把返回的内存地址转换成vma地址。
#define _gnu_source
#include
#include
#include
#include
#include
#include
#include
/*****************************hook******************************/
//
// created by 68725 on 2022/8/13.
//
#define _gnu_source
#include
#include
#include
#include
#include
typedef void *(*malloc_t)(size_t);
int enable_malloc_hook = 1;
malloc_t malloc_f;
typedef void (*free_t)(void *);
int enable_free_hook = 1;
free_t free_f;
static int init_hook() {
malloc_f = dlsym(rtld_next, "malloc");
free_f = dlsym(rtld_next, "free");
}
void *converttovma(void *addr) {
dl_info info;
struct link_map *link_map;
dladdr1((void *) addr, &info, (void **) &link_map, rtld_dl_linkmap);
return addr - link_map->l_addr;
}
void *malloc(size_t size) {
if (enable_malloc_hook) {
enable_malloc_hook = 0;
void *p = malloc_f(size);
void *caller = converttovma(__builtin_return_address(0));
printf("[ %p]--->ptr:%p size:%zu\n", caller, p, size);
char command[256];
dl_info info;
dladdr(malloc, &info);
snprintf(command, sizeof(command), "addr2line -f -e %s -a %p > ./mem/%p.mem", info.dli_fname, caller, p);
system(command);
enable_malloc_hook = 1;
return p;
}
else {
return malloc_f(size);
}
}
void free(void *ptr) {
if (enable_free_hook) {
enable_free_hook = 0;
void *caller = converttovma(__builtin_return_address(0));
printf("[-%p]--->ptr:%p\n", caller, ptr);
char buff[128] = {0};
sprintf(buff, "./mem/%p.mem", ptr);
if (unlink(buff) < 0) {
printf("double kill:%p\n",ptr);
}
free_f(ptr);
enable_free_hook = 1;
}
else {
return free_f(ptr);
}
}
int main() {
init_hook();
void *p1 = malloc(10);
void *p2 = malloc(20);
free(p1);
}