如何在保护模式下执行间接远程跳转/呼叫?首先,我认为这样做是可以接受的:
jmp 0x10:eax;
(不要担心段选择器......我的GDT的第二个条目是一个有效的代码段)
但是当nasm组装它时,这是一个语法错误。查看英特尔(指令集参考)手册的第2a册,只能使用jmp ptr16:32
,其中ptr16:32
是立即值,或使用jmp m16:32
,其中{ {1}}是一个包含48位跳转地址(16:32)的内存位置。
现在我尝试用这种方式编码:
m16:32
它已成功组装,但当我尝试运行它时,处理器会出现一般性保护错误并重新启动。我不知道发生了什么。
我认为编码是这样的:
(例如我想使用间接跳转跳转到0x10:0x8010)
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
这可能有什么问题? 应该用小端编码48位内存值吗? 它应该像这样编码吗?
dw 0x10
dd 0x8010
我没有尝试过做最后一次。
答案 0 :(得分:3)
常用的技巧是使用远距离模拟跳跃,例如:
push 0x10
push eax
retf
答案 1 :(得分:1)
x86处理器使用little-endian模式。与此一致,目标的偏移量在内存中的段之前。对于您的示例,您应该使用:
dd 0x8010;远跳的偏移量
dd 0x10;跳远段,由于对齐原因扩展为双字
; ------------------
db 0x10,0x80,0,0,0x10,0,0,0;也可以。
您可能仍会获得特权异常。要使代码生效,目标代码段必须具有与源段相同的权限级别。
主要来源:Robert L. Hummel的处理器和协处理器