库打桩
更新于:2022-05-09
系统调时,用自定义函数取代共享库函数。
作用
- 追踪某个特殊库函数的调用次数
- 验证和追踪它的输入输出值
- 替换函数实现
流程
创建一个和目标函数原型一样的包装函数,
使用打桩机制让系统调用包装函数,包装函数内再调用目标函数。
编译时打桩
对目标函数进程一层封装,在封装函数内调用目标函数。
通过对malloc和free的打桩进行说明
| C |
|---|
| //main.c
#include <stdio.h>
#include <malloc.h>
int main()
{
int *p = malloc(32);
free(p);
return 0;
}
|
重写malloc.h,如下
| C |
|---|
| //malloc.h
#define malloc(size) Malloc(size)
#define free(ptr) Free(ptr)
|
实现自定义的malloc和free
| C |
|---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | //Malloc.c
#include <stdio.h>
#include <malloc.h>
void* Malloc(size_t size)
{
void * ptr = malloc(ptr);
printf("malloc:%s %d\n", ptr, size);
return ptr;
}
void Free(void* ptr)
{
free(ptr);
printf("free:%p\n", ptr);
}
|
| Bash |
|---|
| #先编译自行封装的malloc和free
gcc -c Malloc.c
#通过只用 -I. 编译时,将有限搜索当前目录,即使用./malloc.h,而不是/usr/include/malloc.h
gcc -I. -o a.out main.c Malloc.o
|
链接时打桩
使用linux静态链接器的--wrap fun标志。
该标志告诉连接器把对f的引用解析成__warp_fun,
对符号__real_fun的引用解析成fun。
| C |
|---|
| //main.c
#include <stdio.h>
#include <malloc.h>
int main()
{
int *p = malloc(32);
free(p);
return 0;
}
|
| C |
|---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | //Malloc.c
#include <stdio.h>
void *__real_malloc(size_t size);
void __real_free(void* ptr);
void *__wrap_malloc(size_t size)
{
void * ptr = __real_malloc(ptr);
printf("malloc:%s %d\n", ptr, size);
return ptr;
}
void __wrap_free(void* ptr)
{
__real_free(ptr);
printf("free:%p\n", ptr);
}
|
| Bash |
|---|
| #正常编译Mallic和main
gcc -c Malloc.c
gcc -c main.c
#通过-Wl,----warp,fun向链接器传递参数
gcc -Wl,--wrap,malloc -Wl,--wrap,free -0 a.out Malloc.o main.o
|
运行时打桩
设置环境变量LD_LIBRARY_PATH
指定运行时依赖动态库路径
使用调试库