我剛剛使用objdump -x ...
來檢查PE文件的各個部分。那麼大部分的二進制文件都是由reloc表組成的?
還有約90,000線RELOC條目:
reloc 92 offset bc0 [524bc0] HIGHLOW
reloc 93 offset bc4 [524bc4] HIGHLOW
....
是否持有誠然,大多數PE文件的大部分空間是由像上面的RELOC項?
這些條目是什麼?
UPDATE
任何人都可以解釋搬遷項目如何運作像上面?
我剛剛使用objdump -x ...
來檢查PE文件的各個部分。那麼大部分的二進制文件都是由reloc表組成的?
還有約90,000線RELOC條目:
reloc 92 offset bc0 [524bc0] HIGHLOW
reloc 93 offset bc4 [524bc4] HIGHLOW
....
是否持有誠然,大多數PE文件的大部分空間是由像上面的RELOC項?
這些條目是什麼?
UPDATE
任何人都可以解釋搬遷項目如何運作像上面?
當存儲器中存在基本衝突時需要重定位。如果動態鏈接庫希望將其代碼段加載到某個內存空間中,但是當它已經被另一個模塊佔用時,它必須加載到另一個地方。但是,通過將其加載到不同的地址空間中,它會混淆庫引用的所有絕對引用。例如,假設可執行文件具有名爲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
表,答案是它取決於。如果你的程序頻繁地訪問全局變量和常量,它將會有一個巨大的重定位表,因爲這些地方的加載器必須更新。
搬遷。不完全是。 – 2011-05-14 14:27:43
@Ignacio Vazquez-Abrams,你能詳細說明一下嗎? – 2011-05-14 14:32:04
雖然有惡意軟件樣本完全由*組成的重定位項目組成(即沒有顯式代碼或數據,而是將重定位序列反覆應用到同一內存位置以形成最終值),但代碼+數據超過重定位的數量。這個想法是,任何引用內存中絕對地址的值都必須有一個相應的重定位項,以防圖像無法加載到其請求的地址。 – 2017-04-28 18:28:58