编译时打桩,编译命令
gcc -DCOMPILETIME -c my_malloc.c
gcc -I. -o main main.c my_malloc.o
//my_malloc.h
#define malloc(size) mymalloc(size)
#define free(ptr) myfree(ptr)
void *mymalloc(size_t size);
void myfree(void *ptr);
//my_malloc.c
#ifdef COMPILETIME
#include
#include
void *mymalloc(size_t size) {
void *ptr = malloc(size);
printf("malloc(%d)=%p\n", (int)size, ptr);
return ptr;
}
void myfree(void *ptr) {
free(ptr);
printf("free(%p)\n",ptr);
}
#endif
//main.c
#include
#include
int main() {
int *p = malloc(sizeof(int));
free(p);
return 0;
}
链接时打桩,编译命令
gcc -DLINKTIME -c my_malloc.c
gcc -c main.c
gcc -Wl,--wrap,malloc -Wl,--wrap,free -o main main.o my_malloc.o
//my_malloc.c
#ifdef LINKTIME
#include
void *__real_malloc(size_t size);
void __real_free(void *ptr);
void *__wrap_malloc(size_t size) {
void *ptr = __real_malloc(size);
printf("malloc(%d) = %p\n", (int)size, ptr);
return ptr;
}
void __wrap_free(void *ptr) {
__real_free(ptr);
printf("free(%p)\n", ptr);
}
#endif
//main.c
#include
#include
int main() {
int *p = malloc(sizeof(int));
free(p);
return 0;
}
运行结果
malloc(4) = 0x746010
free(0x746010)
运行时库打桩机制
对 malloc,free函数的包装
#define _GUN_SOURCE
#include
#include
#include
//#define NULL 0;
void *malloc(size_t size) {
void *(*malloc_func)(size_t size);
char *error;
/*
void *handle = dlopen("/lib64/libc.so.6", RTLD_LAZY);
if (!handle) {
fprintf (stderr, "%s ", dlerror());
exit(1);
}
*/
malloc_func = dlsym(RTLD_NEXT, "malloc");
if((error=dlerror()) != NULL) {
fputs(error,stderr);
exit(1);
}
char *ptr = malloc_func(size);
printf("malloc(%d) = %p\n", (int)size, ptr);
return ptr;
}
void free(void *ptr) {
void (*free_func) (void *) = NULL;
char *error;
if(!ptr) {
return;
}
free_func = dlsym(RTLD_NEXT, "free");
if((error=dlerror()) != NULL) {
fputs(error,stderr);
exit(1);
}
free_func(ptr);
printf("free (%p)\n",ptr);
}
编译命令
gcc -D_GNU_SOURCE -DRUNTIME -shared -fPIC -o mymalloc.so mymalloc.c -ldl
执行
LD_PRELOAD="./mymalloc.so" uptime
运行结果
malloc(37) = 0x2526040
。。。
free (0x2527020)
free (0x2526fe0)
malloc(12) = 0x2526fe0
malloc(12) = 0x2527020
free (0x25273e0)
free (0x2527110)
23:44:38 up 349 days, 6:35, 5 users, load average: 0.00, 0.01, 0.05
一些相关的命令
名称 | 含义 |
ar | 创建静态库,插入删除列出和提取成员 |
ldd | 列出一个可执行文件在运行时所需要的共享库 |
gcc | 强大的编译工具 |
nm | 列出一个目标文件的符号表中定义的符号 |
size | 列出目标文件中section的名字和大小 |
objdump | 所有二进制工具之母 能够显示一个目标文件中所有的信息 最大的作用是反汇编.text 片段中的二进制指令 |
readelf | 显示一个目标文件的完整结构 包括ELF头中编码的所有信息,包含size和nm的功能 |
strace | 跟踪调试工具 |
strip | 删除多余的段 |
参考
关于Linux静态库和动态库的分析
程序的编译链接过程
程序运行流程——链接、装载及执行
一些相关的命令
名称 | 含义 |
ar | 创建静态库,插入删除列出和提取成员 |
ldd | 列出一个可执行文件在运行时所需要的共享库 |
gcc | 强大的编译工具 |
nm | 列出一个目标文件的符号表中定义的符号 |
size | 列出目标文件中section的名字和大小 |
objdump | 所有二进制工具之母 能够显示一个目标文件中所有的信息 最大的作用是反汇编.text 片段中的二进制指令 |
readelf | 显示一个目标文件的完整结构 包括ELF头中编码的所有信息,包含size和nm的功能 |
strace | 跟踪调试工具 |
strip | 删除多余的段 |
参考
关于Linux静态库和动态库的分析
程序的编译链接过程
程序运行流程——链接、装载及执行