У меня есть некоторые машинные коды следующим образом:
FF 25 CA 21 00 00
Я знаю, что это код операции JMP
с Op/En, установленным на M, что означает, что после него есть байт ModR/M.
0x25
=> 0x00100101
, поэтому reg
— это 0b100, а код операции на самом деле FF /4
. Тем не менее, в сводной таблице кодов операций JMP есть только одно совпадение:
FF /4 ---- JMP r/m64 ---- Близкий переход, абсолютный косвенный, RIP = 64-битное смещение из регистра или памяти
Это означает, что то, что следует за байтом ModR/M, должно быть 64-битным операндом. Но у меня только 32-битный операнд, CA 21 00 00
.
Я что-то пропустил? Дайте мне несколько советов по этому поводу.
Это непрямой прыжок. r/m64 — это размер операнда для указателя, загружаемого в виде данных в RIP, а не количество байтов, используемых для кодирования загружаемого адреса или самого нового RIP.
25
— это ModRM, который кодирует режим адресации относительно RIP, поэтому 4 байта — это rel32
для режима адресации [rip+rel32]
.
Проверьте https://defuse.ca/online-x86-assembler.htm#disassembly2 или любым другим удобным способом скормить эти байты дизассемблеру:
ff 25 ca 21 00 00 jmp QWORD PTR [rip+0x21ca]
Смотрите также
Я нашел то, что вы сказали в главе 3.7.5.1 Руководства разработчика программного обеспечения для архитектур Intel® 64 и IA-32: «RIP + Displacement — в 64-битном режиме RIP-относительная адресация использует 32-битное смещение со знаком для вычисления эффективный адрес следующей инструкции по знаку, удлините 32-битное значение и добавьте к 64-битному значению в RIP».