4

如何在保护模式下执行间接远跳转/呼叫?首先,我认为这样做是允许的:

jmp 0x10:eax;

(不用担心段选择器。我的 GDT 的第二个条目是有效的代码段)

但是当 nasm 组装它时,这是一个语法错误。查看 Intel (instruction set reference) 手册的 Book 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

我还没试过做最后一个。

4

2 回答 2

3

一个常用的技巧是使用远距离模拟跳跃,例如:

push 0x10
push eax
retf
于 2011-01-27T14:08:09.350 回答
1

x86 处理器使用 little-endian 模式。与此一致,目标的偏移量在内存中的段之前。对于您的示例,您应该使用:

dd 0x8010 ; 远跳偏移量

dd 0x10 ; 远跳段,由于对齐原因扩展为双字

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

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

您可能仍然会获得特权异常。要使代码工作,目标代码段必须与源代码段具有相同的权限级别。

主要来源:Robert L. Hummel 的处理器和协处理器

于 2013-04-29T04:38:59.190 回答