LD_PRELOAD

今天要介紹一個環境變數"LD_PRELOAD"。這是個危險的變數,可以讓程式執行時強制link某個dynamic library。

其文章內容參考、翻譯自:Dynamic linker tricks: Using LD_PRELOAD to cheat, inject features and investigate programs

sample code random_num.c:如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(){
    srand(time(NULL));
    int i = 10;
    while(i–) printf(“%d\n“,rand()%100);
    return 0;
}

compile:

gcc random_num.c -o random_num

執行結果:

ran1

現在我要hack rand() function 我可以這麼做:

unrandom.c:

int rand(){
    return 42; //the most random number in the universe
}

compile:

gcc -shared -fPIC unrandom.c -o unrandom.so

-share : 告訴compiler我要將此檔案編譯成shared library(dynamic lib)
-fPIC : 告訴compiler 編譯的過程中,沒有絕對位置,全部使用相對位置(因為我將來要之視為dynamic lib)

編譯完成後會產生shared lib “unrandom.so" 後執行:

LD_PRELOAD=$PWD/unrandom.so ./random_num

ran2

分析:

為了解釋該現象我們使用ldd指令來看看

ldd ./random_num

ran3

這個指令會show出執行random_num執行時會link那些lib。後方的address表示要load到哪個位置,因為是dynamic link所以每次執行的位置都會不一樣,不信的話讀者可自己試試看多下幾次ldd ./random_num。此外原本的rand()應該會在libc.so.6中(讀者可用nm(看註1) /lib64/libc.so.6 check 看看)。接下來,如果我改用自己hack過的lib呢?

 LD_PRELOAD=$PWD/unrandom.so ldd random_nums

ran4

可以看到我自己做的shared lib “unrandom.so" 被link進去了(而且是LD_PRELOAD是強制link)。此舉將造成call rand()時會call到我自己定義的rand()。 此變數好處是城市好維護,無須重新編議原程式即可patch等等,但也有其危險性,需自行斟酌。

註1:

nm 指令: 可看到program中所有symbol ex: 

ran5

中間的大寫英文子母表type 可用man nm 檢視所有type,或可參考: GUN Binary Utility

 

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *