Original Post
Hi folks, I'm trying to understand a function I've found that writes the x86 opcodes for an absolute jump:
void write_abs_jump(unsigned char *opcodes, const void *jmpdest)
{
opcodes[0] = 0xFF;
opcodes[1] = 0x25;
*reinterpret_cast<DWORD *>(opcodes + 2) = reinterpret_cast<DWORD>(opcodes + 6);
*reinterpret_cast<DWORD *>(opcodes + 6) = reinterpret_cast<DWORD>(jmpdest);
}
Here's what I've gleamed so far. Please correct me if any of this is wrong. I believe 0x25 is a ModR/M byte whose constituent parts are in binary: mod=00, reg/opcode=100, r/m=101 The reg/opcode part is 4 in decimal, so the instruction is found under "FF /4" in the intel reference manual. The instruction mnemonic listed for this is "JMP r/m32" and it has a single operand: "ModRM:r/m (r)". The "(r)" in there means that the content of the operand will be read by the processor. At this point I'm a bit stuck. Specifically, I can't figure out what that first DWORD is for (opcodes + 6). It's a pointer to the memory location that contains the value of jmpdest, but why is it needed? What part of the intel manual do I have to understand to appreciate its role in the instruction? There's a table in Intel's manual ("Table 2.2: 32-Bit Addressing Forms with the ModR/M Byte") where I can lookup the "effective address" corresponding to the value of the ModR/M byte, which in this case is "disp32". The manual tells me "The disp32 nomenclature denotes a 32-bit displacement that follows the ModR/M byte (or the SIB byte if one is present) and that is added to the index". I haven't got a clue what this part means though, but I'm pretty sure I don't have an SIB byte here. So any help in getting further with this would be very much appreciated!