這邊是聽jserv 的線上講座你所不知道的 C 語言:動態連結器篇 才知道的方式
爲了怕忘記做些測試候的記錄
這邊用的範例也是base on jserv的範例做修改測試
LD_PRELOAD
透過在執行檔案之前加上 LD_PRELOAD=xxx.so 可以將後面執行程式所呼叫的function取代成xxx.so內的function
也就是我們可以做到替換libc內的函式 改成我們自己的 當程式執行時
github 上面也有人寫相關資料
測試
目標是將malloc and free 替換成自己的library 當執行測試檔時,code 的內容如下
malloc_count.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <stddef.h> #include <dlfcn.h> void *malloc(size_t size) { char buf[32]; static void *(*real_malloc)(size_t) = NULL; if (real_malloc == NULL) { real_malloc = dlsym(RTLD_NEXT, "malloc"); } sprintf(buf, "malloc called, size = %zu\n", size); write(2, buf, strlen(buf)); return real_malloc(size); } void *free(void *ptr) { char buf[32]; static void *(*real_free)(void *ptr) = NULL; if (real_free == NULL) { real_free = dlsym(RTLD_NEXT, "free"); } sprintf(buf, "free called, ptr address = %x\n", ptr); write(2, buf, strlen(buf)); real_free(ptr); }
|
test.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <stdio.h> #include <stdlib.h> #include <string.h> void main(void) { char *buffer; buffer = malloc(sizeof(char)*10); memset(buffer, 0x41, 10); puts(buffer); free(buffer); buffer = NULL; free(buffer); }
|
編譯command :
原本用的command 跟講座上面是一樣的
1
| gcc -D_GNU_SOURCE -Wall -shared -ldl -fPIC -o libmcount.so malloc_count.c
|
編譯之後透過ls測試也是可以跑的
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| memory_test$ LD_PRELOAD=libmcount.so ls malloc called, size = 568 malloc called, size = 120 free called, ptr address = 136a250 free called, ptr address = 136a010 free called, ptr address = 0 malloc called, size = 5 free called, ptr address = 136a010 malloc called, size = 120 malloc called, size = 12 malloc called, size = 784 malloc called, size = 112 malloc called, size = 952 malloc called, size = 216
|
但是跑test 測試程式會出現library 找不到的問題
1 2 3
| gcc -o test test.c memory_test$ LD_PRELOAD=libmcount.so ./test ./test: symbol lookup error: libmcount.so: undefined symbol: dlsym
|
透過ldd 發現缺少dl library

檢查ls and test 執行檔 可以發現ls有linker ld library但是test沒有, 這也是爲何ls可以跑

猜測因該是compiler最佳化之後將librar去除掉了 查看網路上有人說-ldl
拉到最後面就可以
修改後做測試確定test可以跑了
1
| gcc -D_GNU_SOURCE -Wall -shared -fPIC -o libmcount.so malloc_count.c -ldl
|


<注意>
- lbrary compiler時需要加上
-D_GNU_SOURCE
是因爲library有用到RTLD_NEXT
- free pointer 之後需要將pointer 設爲null 這樣在後面如果不小心再free 到時才不會有double free message
double free or corruption
C手冊上面有這一段
