2010-07-20 41 views
3

我正在使用GNU ld的「-wrap」選項來攔截應用程序中的調用,但遇到了實現封裝程序的代碼間接調用封裝函數並創建循環引用的場景。阻止「ld -wrap」循環引用

目標是閱讀包裝中出現的程序foo的調用。此代碼可以重新編譯/重新鏈接,但不能修改。

計劃富

main() { 
    ... 
    read(fd, buf, size); 
    ... 
} 

這裏的包裝將攔截來電libc中使用 「-wrap讀」 時,在程序foo的閱讀。

包裝

extern int __real_read(...); 
int __wrap_read(...) { 
    bar(); 
    __real_read(...); 
} 

然而,圖書館酒吧,從包裝稱爲需要使用libc中的read()函數,不用經過包裝(從而導致循環依賴)。

圖書館酒吧

void bar(void) { 
    read(fd, buf, size) 
} 

改變圖書館酒吧都包裹程序使用__real_read()是不是一種選擇,因爲這裏面的圖書館酒吧外部庫的其他調用存在間接性的水平是任意的。

避免旗

解決這個

的方法之一是使用每個線程的標誌,以防止讀取包裹從圖書館酒吧發起重新進入圖書館。雖然我寧願不使用這種解決方案,但我也樂於提供有關如何在包裝器和條形庫中實現最小代碼更改的建議。

理想解決方案

???這就是爲什麼我問的問題:)

謝謝... -n

+1

您可以指示鏈接器僅將-wrap應用於某些目標文件嗎?也許一個鏈接腳本可以讓你在那裏。 – nmichaels 2010-07-20 18:52:21

+0

這不太可能。考慮一下bar()在另一個目標文件(等等)中調用函數,然後又調用read()的情況。這些間接水平會迅速增長,跟蹤這一切都會出錯。 – 2010-07-20 19:08:58

回答

1

解決這一問題的基本知識,在中詳細介紹。任何感興趣的人都可以要求我提供更多的信息,這些信息來自我根據上述URL提供的思想構建的更復雜的案例。

1

正如納通說,它應該是可能的包裹FHE閱讀()只對特定的目標文件調用。不知道有關linux的問題,但在windows中,在DLL中包裝導入的函數不會影響其他模塊中的導入函數,因此將Bar放入帶有unwrapped read()的單獨DLL中可以解決問題。

http://okmij.org/ftp/syscall-interpose.html

然而,取決於具體的情況事情會有所不同:

+0

您的解決方案相當於在構成不應包裹的對象文件的文件中手動重命名__real_read()的所有read()調用。正如我所指出的,這是不夠的,因爲通過未知級別的間接發生的read()調用。 我當然不會聲稱你的想法不起作用,但我不確定它涵蓋了所有的基礎。 – 2010-07-20 19:19:23