Выполнение косвенного прыжка в длину / вызова в защищенном режиме - PullRequest
3 голосов
/ 27 января 2011

Как выполнить косвенный переход в другое положение / вызов в защищенном режиме?Сначала я подумал, что это допустимо:

jmp 0x10:eax;

(не беспокойтесь о селекторе сегмента. 2-я запись моего GDT является допустимым сегментом кода)

Но когдаНасм собрал его, это была синтаксическая ошибка.Глядя на Книгу 2a руководства Intel (руководство по набору инструкций), это можно сделать только с помощью 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

Я не пытался сделать последний.

Ответы [ 2 ]

3 голосов
/ 27 января 2011

Часто используемый трюк состоит в том, чтобы эмулировать прыжок с использованием дальнего поворота, например:

push 0x10
push eax
retf
1 голос
/ 29 апреля 2013

Процессоры x86 используют режим с прямым порядком байтов. В соответствии с этим, смещение цели предшествует сегменту в памяти. Для вашего примера вы должны использовать:

дд 0x8010; смещение дальнего прыжка

dd 0x10; сегмент дальнего прыжка, расширенный до двойного слова для выравнивания

; * ------------------ * 1007

дБ 0x10, 0x80, 0, 0, 0x10, 0, 0, 0; также будет работать.

Возможно, вы все еще получите исключение привилегии. Чтобы код работал, целевой сегмент кода должен иметь тот же уровень привилегий, что и исходный сегмент.

Первоисточник: Процессор и сопроцессор Роберта Л. Хаммела

...