链接--库打桩

博客介绍了计算机系统中打桩的相关知识,打桩即用自己的函数替换共享库的函数。详细阐述了编译时、链接时和运行时三种打桩的实现原理及示例,还说明了打桩的用途,如追踪库函数使用次数、验证和追踪其输入输出值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是打桩

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

怎么实现打桩

编译时进行打桩

原理

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

example

#include <stdio.h>
#include <malloc.h>
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 <stdio.h>
#include <malloc.h>

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 <stdio.h>

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 <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

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

打桩的用途

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值