库打桩技术

GUN binutils 工具包


readelf 显示目标文件的完整结构
LDD 列出一个可执行文件在运行时间所需要的共享库
ld -lUsefulFunctions --verbose 可以显示静态库的情况

Linux下的库打桩技术

/demo
+--- demo
   |
   +--- int.c   
   +--- malloc.h
   +--- mymalloc.c

int.c

#include <stdio.h>
#include <malloc.h>
int main()
  {
	int *p = malloc(32);
	free(p);
	printf("Done!\n");
	return 0;
  }

malloc.h

#define malloc(size) mymalloc(size)
#define free(ptr) myfree(ptr)
void *mymalloc(size_t size);
void myfree(void *ptr);

mymalloc.c

#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

#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

编译期打桩

gcc -DCOMPILETIME -c mymalloc.c
gcc -I . -o intc int.c mymalloc.o // 注意-I .不是-I.

链接期打桩

gcc -DLINKTIME -c mymalloc.c
gcc -c int.c
gcc -Wl,--wrap,malloc -Wl,--wrap,free -o int1 int.o mymalloc.o

-Wl,--wrap,malloc = 把--wrap malloc传递给链接器,相当于链接器
把对malloc的引用解析为__wrap_malloc
把对__real_malloc的引用解析为malloc

运行期间打桩

这个很厉害的机制基于动态链接器的LD_PRELOAD环境变量
先把下面代码编译成动态链接库gcc -DRUNTIME -shared -fpic -o mymalloc.so mymalloc.c -ldl

g++ -std=c++11 test.cpp -o intr                                           
g++ -std=c++11 -DRUNTIME -shared -fpic -o mymalloc.so mymalloc.cpp -ldl   //编译成动态库,其中的malloc采用特殊的解析方式
LD_PRELOAD="./mymalloc.so" ./intr                                         //单次有效,且并不影响./intr
#ifdef RUNTIME
//#define _GNU_SOURCE
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <iostream>
#include <fstream>
#include <string>
std::string GetTime(){
    using namespace std;
    time_t now = time(0);
    tm *ltm = localtime(&now);
    long long int tmp = 0;
    tmp += 1900 + ltm->tm_year;
    tmp *= 100;
    tmp += 1 + ltm->tm_mon;
    tmp *= 100;
    tmp += ltm->tm_mday;
    tmp *= 100;
    tmp += ltm->tm_hour;
    tmp *= 100;
    tmp += ltm->tm_min;
    tmp *= 100;
    tmp += ltm->tm_sec;
    string ret = to_string(tmp);
    ret.insert(12,":");
    ret.insert(10,":");
    ret.insert(8,"-");
    return ret; 
}
const char * const output = "/home/mzb/Project/MemoryLeak/Memory.log";
FILE* fout = NULL;
using std::endl;
using std::cout;
using std::cerr;
static int is_self_reference = 0;

void init(){
    static bool is_init = false;
    if (!is_init){
        is_init = true;
        ++is_self_reference;
        fout = fopen(output,"at+");
        --is_self_reference;
    }
}

void* Dlsym(const char* const func_name){
    auto ret = dlsym(RTLD_NEXT,func_name);
    auto error = dlerror();
    if (error != NULL){
        cerr << "dlsym(" << func_name << ") = " << ret << endl;
        cerr << "dlerror() = " << error << endl;
        exit(0);
    }
    else{
        return ret;
    }
}
void* malloc(size_t size){
    init();
    using func_type = void* (*)(size_t size);
    func_type mallocp = (func_type)Dlsym("malloc");

    if (is_self_reference){
        return mallocp(size);
    }
    else{
        ++is_self_reference;
        auto ret = mallocp(size);
        if (fout){
            auto time = GetTime();
            fprintf(fout,"%s malloc(%d) = %p\n",time.c_str(),(int)size,ret);
        }
        else{
            cerr << "fopen(" << output << ",at+) failed" << endl;
        }
        --is_self_reference;
        return ret;
   }
}

void free(void* ptr){
    using func_type =  void (*)(void *);
    func_type freep = (func_type)Dlsym("free");
    if (is_self_reference){
        freep(ptr);
    }
    else{
        ++is_self_reference;
        if (fout){
            auto time = GetTime();
            fprintf(fout,"%s free(%p)\n",time.c_str(),ptr);
        }    
        else{
            cerr << "fopen(" << output << ",at+) failed" << endl;
        }
        freep(ptr);
        --is_self_reference;
    }
}

#endif

posted @ 2022-02-27 20:32  XDU18清欢  阅读(124)  评论(0)    收藏  举报