2012-01-09 91 views
7

我希望能夠動態更改我正在使用的庫內的可執行代碼。從本質上講,如果不需要,我想動態地NOP出某些功能。如何讓GCC編譯.text段作爲ELF二進制文件可寫?

不過,我現在用的是圖書館的.text段是不寫的(這是大多數程序的情況下)。我有庫的源代碼,所以想使用GCC將其編譯爲可寫。

有沒有辦法做到這一點?

+0

什麼是這樣做的實際原因GCC來鏈接? – cateof 2012-01-09 21:43:24

回答

1

也許最好的方法是使用系統特定的API來改變你要修改的內存可寫,修改,再改回來。

在Unix家族系統,你會想看看mprotect。請記住,它處理的是您系統的頁面大小的倍數的塊。可能是4096,所以可能需要四捨五入。

+0

那麼我正在使用Genode操作系統,並試圖重寫動態鏈接器的map_object()函數。 mprotect()是否適用於程序的加載階段? – samoz 2012-01-09 20:39:07

5

嘗試objcopy --writable-text在編譯庫,按照它應該的.text寫的文檔。

+1

這是一個問題或答案? – 2012-01-09 22:38:23

7

從一般意義上說,mprotect是在sys/mman.h(檢查http://linux.die.net/man/2/mprotect)下的推薦選擇(在符合POSIX的系統上)。只需獲取進程的可執行部分的地址和系統頁數,然後致電mprotect以請求權限;寫信給它;然後再次撥打mprotect以釋放寫入權限。

然而,如果這意味着要在低級別的程序,其中速度是絕對重要的(或mprotect不可用),那麼你會希望其.text部分寫編譯庫作爲主叫mprotect最有可能的問題翻譯後備緩衝區(TLB)刷新(特別是在多處理器環境中)可能並會造成瓶頸。如果特定的系統是通過分頁使用硬件保護(其中幾乎所有的現在),然後改變其保護的唯一方法是做一個TLB沖洗,必須每個被引用頁面上執行,引用頁表(一組頁),引用頁面目錄(一組頁表)和每個處理器。最重要的是,這必須在環0中執行,這需要一個系統調用,它只是將頂部的櫻桃放在頂部。

在後一種情況下,最簡單的解決方案將是正常編譯庫,然後用--writable-textobjcopy它(如通過ggiroux提到的)。

另一個解決辦法是自己定義的鏈接映射文件linker.ld。然後您可以明確指定任何部分的權限。它不太複雜;如果系統依賴。請參閱文檔http://www.math.utah.edu/docs/info/ld_3.html。你也可以看看你的系統提供的linker.ld文件並從那裏修改它。傳遞-Wl,--verbose到GCC將指示鏈接吐出所有相關文件(包括其默認linker.ld),其中你可以再修改.text段的權限,並重新編譯庫(永遠)使用新的linker.ld文件。

總之,我的建議是做的最後一段的狀態和帶稍微修改鏈接腳本編譯庫。

2

,我發現(binutils的2.22),最簡單的方法是-N 這可以是傳球用gcc-XN

相關問題