Как закодировать относительно короткий 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. 2А 3-423

Ближний прыжок, где диапазон прыжка ограничен от -128 до +127 от текущего значения EIP.

Затем я рассматриваю три возможности:

  1. +2, потому что это значение EIP после / в будущем во время выполнения
  2. Кодированное значение не является кодированным номером со знаком 2s.
  3. это появляется в руководстве, но я не видел, потому что я тупой

3 ответа

Решение

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 сама инструкция. Это может вызвать некоторую путаницу.

Будь то прыжок в длину или нет, это всегда destination - source + sizeof(instruction), В вашем случае (безусловный короткий прыжок), sizeof(instruction) 2. Причиной этого дополнения является тот факт, что после того, как процессор выполнил этап извлечения инструкций, указатель инструкций будет указывать на инструкцию, которая идет после ветвления.

Короткое замыкание берет EIP относительно конца инструкции перехода (длина которого составляет два байта), и принимает однобайтовый операнд, знак которого расширяется и добавляется в EIP.

Другие вопросы по тегам