Libc function override 標準函式庫覆載

在 Tiny AES Library 好移植加密函式庫 文章裡提到客戶來洽談的合作方案,不只有加密的需求,而且還需要”透明式” (transparently) 的加密。什麼是透明式加密??以往我所知道的密碼方法,都是會先用一塊 Block device 當做一個 image,然後將它 mount 成一個 folder,往裡面存取的檔案最終就會被加密的存在 image 內,下次 mount device 時就需要密碼才行。像是我用過的 dmcrypt 就是這種。

而 transparent 的方式則是針對個別檔案(當然針對檔案就可以處理整個 disk,透過攔截標準的 FILE IO 的方式,在做操作時進行加解密(其實也是我猜的,跟客戶還沒談到這麼細)。這個方式比較通用,不需要 root 權限,檔名也都可以辨識,但內容是看不到的。這用在一些網路硬碟 (ex. Google driver or dropbox),也可以有效保護隱私。當然,檔名被看到就好像不是這麼安全,這也算是一種選擇吧。

總之,這個覆寫 function 的東西對我很新奇。實驗了一下,就順便記下來了。

原理

完整的測試包附在檔尾,以下說明程式碼。其主要是先透過 Linux 的 LD_PRELOAD 變數先預載要覆寫的function, 在載入程式進行FILE IO時,就會先使用自己的 FILE IO,使用完再呼叫 LIBC 的 IO。這邊的例子是覆寫 sleep(),換成 fopen 或 open 都可以。

Makefile

 

行2: mysleep.c 是實作自己的 sleep() 原始檔,將其編成 .so 以便稍後載入。自定的sleep() 執行到時會印出一些訊息

行3: mysleep_try.c 是簡單的 sleep() 程式,睡的前後會印出訊息。

行7~8: 在行7先執行無覆載的 mysleep_try 程式,會看到單純的sleep訊息。行8則是會先載入 libmysleep.so,因此在執行myslep_try時會多印出一些訊息

訊息比較

mysleep.c – 自定的 sleep()

 

行3~4: include 後面 RTLD_NEXT 的 header

行7: 呼叫自定 sleep() 時,印出個訊息

行8: 宣告 libc sleep() 的 function pointer,稍後會取得 libc sleep() 的 pointer

行9: 在已載入的所有 library 內,尋找下一個 symbol 為 sleep 的 function,也就是原本 libc 的 sleep

行10: 呼叫原本libc的 sleep

mysleep_try.c – 單純的呼叫 sleep

 

行6: 此處呼叫的 sleep,就看當時是否有透過 LD_PRELOAD 載入 libmysleep.so。若有,則先呼叫自定的,再呼叫libc。無的話,則只呼叫libc。

結語

這個攔截 LIBC function 還蠻有趣的 (可怕?),透過攔截就可以先做一些加密或壓縮的處理。當然,想的壞一點,就可以做一些側錄,放毒的事…

開始跟不同領域的人接觸後,才知道 Linux 有多廣泛,要學的東西還很多啊~~~

附件

覆載 LIBC FILE IO API 範例

Leave a Reply