2011-05-14 106 views
2

我剛剛使用objdump -x ...來檢查PE文件的各個部分。那麼大部分的二進制文件都是由reloc表組成的?

還有約90,000線RELOC條目:

reloc 92 offset bc0 [524bc0] HIGHLOW 
reloc 93 offset bc4 [524bc4] HIGHLOW 
    .... 

是否持有誠然,大多數PE文件的大部分空間是由像上面的RELOC項?

這些條目是什麼?

UPDATE

任何人都可以解釋搬遷項目如何運作像上面?

+0

搬遷。不完全是。 – 2011-05-14 14:27:43

+0

@Ignacio Vazquez-Abrams,你能詳細說明一下嗎? – 2011-05-14 14:32:04

+0

雖然有惡意軟件樣本完全由*組成的重定位項目組成(即沒有顯式代碼或數據,而是將重定位序列反覆應用到同一內存位置以形成最終值),但代碼+數據超過重定位的數量。這個想法是,任何引用內存中絕對地址的值都必須有一個相應的重定位項,以防圖像無法加載到其請求的地址。 – 2017-04-28 18:28:58

回答

10

當存儲器中存在基本衝突時需要重定位。如果動態鏈接庫希望將其代碼段加載到某個內存空間中,但是當它已經被另一個模塊佔用時,它必須加載到另一個地方。但是,通過將其加載到不同的地址空間中,它會混淆庫引用的所有絕對引用。例如,假設可執行文件具有名爲int dummy;的全局變量,並且該變量位於0x602315中。每當這個變量被訪問/寫入,該程序執行以下的操作碼(假定代碼位於0x524BBE,相同你提到的條目):

0x524BBE: MOV EAX, DWORD PTR DS:[0x602315];//move dummy to eax register to do stuff

如果庫在不同的裝空間0x602315不會指向該變量,因爲地址空間0x602315已被其他模塊佔用。因此,要解決此問題,您必須告訴PE加載器將位移(|new base address-expected base address|)添加/減去此值(0x602315)。爲此,每個PE都包含一個稱爲重定位表的表,並且此表包含代碼中引用此變量的所有偏移量。

所以,讓我們說,而不是0x524000(預期的基準偏移量),該庫被加載在0x700000。那麼,PE裝載器將做的是查找條目在表中的位移(0x700000-0x524000 = 0x1DC000)添加到偏移(0x602315),使得您的加載代碼看起來就像這樣:

0x700BBE: MOV EAX, DWORD PTR DS:[0x7DE315];//move dummy to eax register to do stuff

這將運行良好,因爲它指向變量dummy的正確位置。

回到你的問題,objdump的輸出顯示了這個表的每個條目。 92可能意味着條目的索引,BC0是您訪問變量的代碼的相對地址,[524BC0]將是相對地址+預期基準偏移量的結果。而HIGHLOW只是一種重新定位(這基本上是爲將來的使用保留的),目前只有一種重定位(HIGHLOW)被使用,所以你不必擔心其他類型)。當加載器讀取此條目時,它將更改0x524BC0的值以反映此更改。

關於你對PE的多數空間構成的問題.reloc表,答案是它取決於。如果你的程序頻繁地訪問全局變量和常量,它將會有一個巨大的重定位表,因爲這些地方的加載器必須更新。

相關問題