diff --git a/arch/X86/X86Disassembler.c b/arch/X86/X86Disassembler.c index 8daa04393c..6c0b2e06f7 100644 --- a/arch/X86/X86Disassembler.c +++ b/arch/X86/X86Disassembler.c @@ -711,7 +711,7 @@ static void update_pub_insn(cs_insn_flat *pub, InternalInstruction *inter) pub->x86.disp_size = inter->displacementSize; pub->x86.imm_size = inter->immediateSize; - pub->x86.modrm = inter->modRM; + pub->x86.modrm = inter->orgModRM; pub->x86.sib = inter->sib; pub->x86.disp = inter->displacement; diff --git a/arch/X86/X86DisassemblerDecoder.c b/arch/X86/X86DisassemblerDecoder.c index 852ad9ceba..1afa3aad9f 100644 --- a/arch/X86/X86DisassemblerDecoder.c +++ b/arch/X86/X86DisassemblerDecoder.c @@ -806,6 +806,9 @@ static int readOpcode(struct InternalInstruction* insn) if (consumeByte(insn, ¤t)) return -1; + // save this first byte for MOV32cr, MOV32dr, MOV32rc, MOV32rd + insn->firstByte = current; + if (current == 0x0f) { // dbgprintf(insn, "Found a two-byte escape prefix (0x%hhx)", current); @@ -1314,6 +1317,11 @@ static int readModRM(struct InternalInstruction* insn) if (consumeByte(insn, &insn->modRM)) return -1; insn->consumedModRM = TRUE; + insn->orgModRM = insn->modRM; + // handle MOV32cr, MOV32dr, MOV32rc, MOV32rd by pretending they have MRM.mod = 0xC + if ((insn->firstByte == 0x0f && insn->mode == MODE_32BIT && insn->opcodeType == TWOBYTE) && + (insn->opcode >= 0x20 && insn->opcode <= 0x23 )) + insn->modRM |= 0xC0; mod = modFromModRM(insn->modRM); rm = rmFromModRM(insn->modRM); diff --git a/arch/X86/X86DisassemblerDecoder.h b/arch/X86/X86DisassemblerDecoder.h index e6ffa69a59..83b8154cba 100644 --- a/arch/X86/X86DisassemblerDecoder.h +++ b/arch/X86/X86DisassemblerDecoder.h @@ -631,6 +631,10 @@ typedef struct InternalInstruction { BOOL consumedModRM; uint8_t modRM; + // special data to handle MOV32cr, MOV32dr, MOV32rc, MOV32rd + uint8_t firstByte; // save the first byte in stream + uint8_t orgModRM; // save original modRM because we will modify modRM + /* The SIB byte, used for more complex 32- or 64-bit memory operands */ BOOL consumedSIB; uint8_t sib;