2011-01-27 84 views
2

如何在保護模式下執行間接遠程跳轉/呼叫?首先,我在想,這樣做是允許的:在保護模式下進行間接遠程跳轉/呼叫

jmp 0x10:eax; 

(不要擔心我的GDT的段selector..the第二項是有效的代碼段)

但是當NASM組裝好,這是一個語法錯誤。查看英特爾(指令集參考)手冊2a,只能使用jmp ptr16:32(其中ptr16:32是立即數)或jmp m16:32來完成,其中m16:32是包含48位跳轉地址( 16:32)。

現在,我想這種方式進行編碼:

mov dword[ds:jumpaddress_offset],eax 
; or just dword[jumpaddress_offset],eax 
mov word[ds:jumpaddress_sel],0x10; 
; or just mov word[ds:jumpaddress_sel],0x10; 
jmp dword far [dword ds:jumpaddress]; 
... 
jumpaddress: 
jumpaddress_sel dw 0 
jumpaddress_offset dd 0 

它組裝成功,但是當我試圖運行它的處理器獲得一個一般性保護錯誤並重新啓動。我不知道發生了什麼事。

我假定編碼是這樣的:

(例如我想跳爲0x10:0x8010使用間接跳轉)

dw 0x10 
dd 0x8010 

可能是什麼問題呢? 48位內存值是否應該用小端編碼? 而且它應該像這樣編碼?

;0010 0000 8010 
dd 0x10,0x80,0,0,0x10,0 

我還沒有試過最後一個。

回答

3

經常使用的技巧是使用遠RET,如以模擬跳躍:

push 0x10 
push eax 
retf 
+0

我已經解決了它。 48位地址應該用小端編碼,即首先定義32位偏移量,然後再定義16位段選擇器。好吧,就像你可以做的那樣,使用間接跳轉也有一些優點。 – prinzrainer 2011-01-29 02:48:25

1

的x86處理器使用小端模式。與此相符,目標的偏移在內存中的段之前。爲了您的例子中,你應該使用:

DD 0x8010,偏移量遠跳轉

DD爲0x10;遠跳段,擴大到雙字對準原因

; ------- -----------

db 0x10,0x80,0,0,0x10,0,0,0;也可以。

您可能仍會收到特權例外。要使代碼工作,目標代碼段必須具有與源段相同的特權級別。

主要來源:Robert L. Hummel的處理器和協處理器