链接--库打桩

什么是打桩

简单的来说就是用自己的函数来替换共享库的函数,比如用自己写的mymalloc()来替换系统库中的malloc()

怎么实现打桩

编译时进行打桩

原理

在生成重定向文件时将目标函数进行替换调用

example

#include 
#include 
int main()
{
    int *p=malloc(32);
    free(p);
    return 0;
}


int.c

#define malloc(size) mymalloc(size)
#define free(ptr) myfree(ptr)

void *mymalloc(size_t size);
void myfree(void *ptr);

malloc.h

#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

mymalloc.c

$ gcc -DCOMPILERIME -c mymalloc.c//进行编译
$ gcc -I. -o intc int.c mymalloc.c//-I是打桩的关键
$ ./intc

链接时进行打桩

原理

当我们进行链接的时候,我们将函数调用替换

#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

mymalloc.c

$gcc -DLINKTIME -c mymalloc.c
$gcc -c int.c
$gcc -Wl,--wrap,malloc -Wl,--wrap,free -o intl int.o mymalloc.o
//-Wl,option 标志把option 传递给链接器,option中将每个逗号替换成空格

运行时进行打桩

原理:

在动态链接器中有一个LD_PRELOAD变量,当我们把它设置为一个共享库路径名的列表时,它的优先级将置为最高,也就是,当你加载和执行一个程序的时候,需要解析未定义的引用时,动态链接器会县 搜索,LD_PRELOAD库,然后才搜索其他库

example

$ gcc -DRUNTIME -shared -fpic -o mymalloc.so mymalloc.c -ldl

$ gcc -o intr int.c

#indef RUNTIME
#define _GNU_SOURCE
#include 
#include 
#include 

void *malloc(size_t size)
{
    void *(*mallocp)(size_t size);
    char *error;
    
    mallocp=dlsm(RTLD_NEXT,"malloc");
    if(error=dlerror!=NULL){
        fputs(error,stderr);
        exit(1);
     }
    char *ptr =mallocp(size);
    printf("malloc(&d)=%p\n",(int)size.ptr);
    return ptr;
}


void free(void *ptr){
    void (*freep)(void *)=NULL;
    char *error;
    if(!ptr)return ;
    freep=dlsm(RTLD_TEXT,"free");
    if((error=delerror())!=NULL){
            fputs(error,stderr);
       		exit(0);
			}
    freep(ptr);
    printf("free(%p)\n",ptr);
    
}
#endif;

$LD_PRELOAD="./mymalloc.so" ./intr

打桩的用途

*可以追踪某个库函数的使用次数,就比如上面的函数里面,我可以再加一个计数器

*验证,追踪它的输入和输出值

你可能感兴趣的:(链接--库打桩)