3

I have some machine codes as follow:

FF 25 CA 21 00 00

I know it's a JMP's opcode with Op/En set to M, which means there's a ModR/M byte after it.

0x25 => 0x00100101, so the reg is 0b100, and the opcode is actually FF /4. However, the only matching one in JMP opcode summary table is:

FF /4 ---- JMP r/m64 ---- Jump near, absolute indirect, RIP = 64-Bit offset from register or memory

This means what follows the ModR/M byte should be a 64-bit operand. But I only have a 32-bit operand, CA 21 00 00.

Did I miss something? Give me some hints on this.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Evan
  • 430
  • 6
  • 16

1 Answers1

3

It's an indirect jump. r/m64 is the operand-size for the pointer to load as data into RIP, not the number of bytes used to encode the address to load from, or the new RIP itself.

25 is a ModRM that encodes a RIP-relative addressing mode, so the 4 bytes are a rel32 for the [rip+rel32] addressing mode.

Check https://defuse.ca/online-x86-assembler.htm#disassembly2 or any other convenient way to feed those bytes to a disassembler:

ff 25 ca 21 00 00   jmp    QWORD PTR [rip+0x21ca]

See also

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    I found what you've said in chapter 3.7.5.1 of *Intel® 64 and IA-32 Architectures Software Developer’s Manual*: "RIP + Displacement ⎯ In 64-bit mode, RIP-relative addressing uses a signed 32-bit displacement to calculate the effective address of the next instruction by sign-extend the 32-bit value and add to the 64-bit value in RIP." – Evan Apr 17 '23 at 15:02