Как закодировать относительно короткий 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.
Затем я рассматриваю три возможности:
- +2, потому что это значение EIP после / в будущем во время выполнения
- Кодированное значение не является кодированным номером со знаком 2s.
- это появляется в руководстве, но я не видел, потому что я тупой
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.