OK. So I am really trying to figure out how to use the "Intel 64 and IA-32 Architectures Software Developer's Manual" for myself, since it seems like the authoritative source for x86(_64) machine code.
I am looking at a program in Ghidra (specifically, a dynamically linked .so file to the program I actually care about). File info for the .so file:
ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked
I come to the following instruction in Ghidra:
ff 25 de ad be ef --- deadbeef being a substitute for the real bytes.
I have Ghidra set up so that I can right click on the instruction and go to the relevant page in the processor manual, which brings me to the JMP reference (p.590 in the version of the manual I have). Cool.
From looking through the options there, I find the ff
opcode rows that correspond to the instruction I am looking at. Further, I know that my ModR/M
byte is 25H
which corresponds to MOD = 00B
, REG = 100B
and R/M = 101B
so I know that this narrows it down to the FF /4
rows in the JMP
instruction description table. But how do I know if it is referring to JMP r/m16
or JMP r/m32
or JMP r/m64
? Also what is the difference between those three? And further, I know from looking at tables 2-1 through 2-3 (combined with how Ghidra interprets the instruction) that de ad be ef
actually ends up being a disp32 that gets added to the index. But how would I have known which table to reference in tables 2-1 to 2-3, and how does that information correspond to choosing between JMP r/m16
or JMP r/m32
or JMP r/m64
?
r
inr/m16
et al means register.m16
/m32
/m64
means memory, either 16- 32- or 64-bit address width. If mod is 11,r/m
is interpreted asr
, otherwisem
. If the CPU were operating in 16-bit mode, onlyff 25
would contribute to the instruction, resulting injmp [di]
followed by four gibberish bytes. For differentiating 32/64, it depends on the operating mode -- it's probably going to be 64-bit based on your .so info and question tags. – smitelli Oct 23 '19 at 0:38