努力という種をまけば、幸せという花が咲く |
步驟有以下這些:
- 找出 image_base
- 找到 relocation 的資訊
為了減少複雜度, 本篇只有討論 image_base。
image_base 主要用來輔助, 可以用它來計算出一些 relocation 相關的操作。它是在 k.ld L5 中描述的, 並不存在於程式碼中, 這是一個很特殊的技巧, 一般的程式並不會這樣寫。
怎麼找出它的值呢? 找出執行的 image_base 比想像中還容易, 不過這部份的程式碼和平台有關, 沒有一個通用的作法, 至少 x86_64 和 x86_32 作法是不一樣的。
以下說明 x86_64 的程式碼實作:
k_crt.S L14 就是在取得執行時期的 image_base, 這是 x86_64 的 lea 用法, 它會把 image_base 執行時期的位址存到 %rdi。
x86 32bit 的 lea 沒有這種用法, 並不是改成 edi 就會有一樣的行為, x86 32bit 是用不同的作法來達成類似的事情。你可能覺得很神奇, 這是怎麼辦到了, 不過我實在不想解釋這個, 請參考: 从机器码理解RIP 相对寻址。
參考 fig 1 右圖, 如果當 elf 執行檔被載入到 0x6882018 時, image_base 是 0x687e018; fig 1 左圖則是按照 elf 的 load segment 載入到記憶體的樣子。
fig 1 左圖:
elf_entry_point - image_base = 0x5010 - 0x0 = 0x5010
fig 1 右圖:
new_elf_entry_point - new_image_base = 0x6883028 - 0x687e018 = 0x5010
elf_entry_point 和 image_base 的差是不會變的。
fig 1 load kernel elf to 0x6882018 address |
呼! 是不是短很多, 看起來應該輕鬆些了。
好了, 有了 image_base, 我們就可以發大財了! 厄 ... 是拿來處理 relocation。
下一篇會有點複雜, 複雜到我都不想寫了!
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。