Подтвердить что ты не робот

Как закодировать относительный короткий 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.
  • это появляется в руководстве, но я не видел, потому что я глуп.
4b9b3361

Ответ 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.