Как закодировать относительный короткий jmp в x86
Предположим, что я хочу сделать короткий прыжок, используя следующие коды операций:
EB CB или JMP rel8
"Переход короткий, RIP = RIP + 8-битный знак смещения расширен до 64 бит"
(где CB является байтом знаковым значением, представляющим относительное смещение, относящееся к направлению в регистре EIP)
Может быть всегда смещение будет офсета + 2, потому что ОПЗ во время выполнения (ссылка направление) в этом коротком прыжке является основой инструкции twobyte, но слагаемый всегда происходит
eb 30 = jmp 0x00000032 (+30)
eb e2 = jmp 0xffffffe4 (-30)
тогда EIP может быть намеренно в том же направлении, потому что fe + 2 00 или EIP.
eb fe = jmp 0x00000000
Я нахожу удивительным, что чрезмерное расстройство вызвало раздвоение, хотя число отрицательно. Но в Intel я не нахожу упоминания (может быть, из-за 3000 страниц).
Архитектуры Intel® 64 и IA-32 Руководство для разработчиков программного обеспечения: Vol. 2A 3-423
Ближайший скачок, где диапазон прыжка ограничен -128 до +127 от текущего значения EIP.
Затем я рассматриваю три возможности:
- равно +2, поскольку это значение после EIP во время выполнения
- Закодированное значение не является кодированным номером со знаком 2s.
- это появляется в руководстве, но я не видел, потому что я глуп.
Ответы
Ответ 1
rel8
относится к следующему адресу памяти инструкции, так как это легко подтвердить, создав два исполняемых файла и разобрав их:
@label:
jmp @label
nop
Это дизассемблируется как (с ndisasm, то же самое в 16-битном, 32-битном и 64-битном коде):
EBFE jmp short 0x0
90 nop
Затем другой исполняемый файл:
jmp @label
@label:
nop
EB00 jmp short 0x2
90 nop
Итак, rel8
всегда кодируется относительно следующей инструкции после jmp
. Однако дизассемблеры (не менее ndisasm
и udcli
) показывают это относительно самой инструкции jmp
. Это может вызвать некоторую путаницу.
Ответ 2
Будь то короткий прыжок или нет, это всегда destination - (source + sizeof(instruction))
.
т.е. dst - end_of_jmp
В вашем случае (короткий прыжок) sizeof(instruction)
равен 2.
Причина этого добавления заключается в том, что, как только процессор выполнил этап выборки инструкции, указатель инструкции уже указывает на инструкцию, которая идет после ветки. Смещение ветки rel8 или rel32 относительно этого значения EIP/RIP.
Ответ 3
Короткий переход занимает EIP относительно конца команды перехода (длиной два байта) и принимает один байтовый операнд, который является расширением знака и добавляется в EIP.