4

プロテクトモードで間接的なファージャンプ/コールを実行するにはどうすればよいですか?最初に私はこれを行うことは許容できると考えていました:

jmp 0x10:eax;

(セグメントセレクターについて心配する必要はありません。GDTの2番目のエントリは有効なコードセグメントです)

しかし、nasmがそれを組み立てたとき、それは構文エラーでした。Intel(命令セットリファレンス)マニュアルのBook 2aを見ると、これは、が即値である、またはを使用してのみ実行できますjmp ptr16:32。ここで、は48ビットジャンプアドレス(16:32)を含むメモリ位置です。 )。ptr16:32jmp m16:32m16: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

頻繁に使用されるトリックは、次のように far ret を使用してジャンプをエミュレートすることです。

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

x86 プロセッサはリトルエンディアン モードを使用します。それに合わせて、ターゲットのオフセットはメモリ内のセグメントよりも前になります。あなたの例では、次を使用する必要があります。

dd 0x8010 ;ファージャンプのオフセット

dd 0x10 ; far jump のセグメント、アラインメント上の理由からダブルワードに拡張

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

db 0x10, 0x80, 0, 0, 0x10, 0, 0, 0 ;も機能します。

それでも特権例外が発生する可能性があります。コードが機能するには、ターゲット コード セグメントがソース セグメントと同じ特権レベルを持っている必要があります。

一次資料: Robert L. Hummel による The Processor and Coprocessor

于 2013-04-29T04:38:59.190 に答える