arch-x86: Fix misc registers in mov instructions (#593)
MOV instructions 8C and 8E can be prefixed with a REX prefix to extend the source/destination register. However, the R bit in REX will be applied to the segment register. The decoder file checks for valid segment registers, checking the MODRM_REG only, however, later this will be extended with the REX_R when adding the register to the sources/destinations of the instruction. This will trigger an assert. Additionally, MOV instructions of various miscelaneous registers are also not check for being valid when taking into account the REX_R bit. This patch checks that the REX_R is not set, otherwise, UD2 will be generated.
This commit is contained in:
@@ -287,25 +287,31 @@
|
||||
0x1: MOV(Ev,Gv);
|
||||
0x2: MOV(Gb,Eb);
|
||||
0x3: MOV(Gv,Ev);
|
||||
0x4: decode MODRM_REG {
|
||||
0x0, 0x1, 0x2,
|
||||
0x3, 0x4, 0x5: MOV(Ev,Sv);
|
||||
0x4: decode REX_R {
|
||||
0x0: decode MODRM_REG {
|
||||
0x0, 0x1, 0x2,
|
||||
0x3, 0x4, 0x5: MOV(Ev,Sv);
|
||||
}
|
||||
default: UD2();
|
||||
}
|
||||
0x5: LEA(Gv,M);
|
||||
0x6: decode MODE_SUBMODE {
|
||||
0x3, 0x4: decode MODRM_REG {
|
||||
// Moving to the CS selector (0x1) is illegal, and 0x6 and
|
||||
// 0x7 are reserved.
|
||||
0x1, 0x6, 0x7: UD2();
|
||||
default: MOV_REAL(Sv,Ev);
|
||||
}
|
||||
default: decode MODRM_REG {
|
||||
// Moving to the CS selector (0x1) is illegal, and 0x6 and
|
||||
// 0x7 are reserved.
|
||||
0x1, 0x6, 0x7: UD2();
|
||||
0x2: MOVSS(Sv,Ev);
|
||||
default: MOV(Sv,Ev);
|
||||
0x6: decode REX_R {
|
||||
0x0: decode MODE_SUBMODE {
|
||||
0x3, 0x4: decode MODRM_REG {
|
||||
// Moving to the CS selector (0x1) is illegal, and 0x6 and
|
||||
// 0x7 are reserved.
|
||||
0x1, 0x6, 0x7: UD2();
|
||||
default: MOV_REAL(Sv,Ev);
|
||||
}
|
||||
default: decode MODRM_REG {
|
||||
// Moving to the CS selector (0x1) is illegal, and 0x6 and
|
||||
// 0x7 are reserved.
|
||||
0x1, 0x6, 0x7: UD2();
|
||||
0x2: MOVSS(Sv,Ev);
|
||||
default: MOV(Sv,Ev);
|
||||
}
|
||||
}
|
||||
default: UD2();
|
||||
}
|
||||
//0x7: group10_Ev();
|
||||
0x7: decode MODRM_REG {
|
||||
|
||||
@@ -287,24 +287,27 @@
|
||||
0x6: HINT_NOP();
|
||||
0x7: HINT_NOP();
|
||||
}
|
||||
0x04: decode LEGACY_DECODEVAL {
|
||||
// no prefix
|
||||
0x0: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: Cpl0CondInst::MOV(
|
||||
{{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Rd,Cd);
|
||||
0x1: Cpl0CondInst::MOV({{MODRM_REG < 8}},Rd,Dd);
|
||||
0x2: Cpl0CondInst::MOV(
|
||||
{{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Cd,Rd);
|
||||
0x3: Cpl0CondInst::MOV({{MODRM_REG < 8}},Dd,Rd);
|
||||
0x04: decode REX_R {
|
||||
0x0: decode LEGACY_DECODEVAL {
|
||||
// no prefix
|
||||
0x0: decode OPCODE_OP_BOTTOM3 {
|
||||
0x6: Cpl0CondInst::MOV(
|
||||
{{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Rd,Cd);
|
||||
0x1: Cpl0CondInst::MOV({{MODRM_REG < 8}},Rd,Dd);
|
||||
0x2: Cpl0CondInst::MOV(
|
||||
{{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Cd,Rd);
|
||||
0x3: Cpl0CondInst::MOV({{MODRM_REG < 8}},Dd,Rd);
|
||||
default: UD2();
|
||||
}
|
||||
// operand size (0x66)
|
||||
0x1: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: Cpl0CondInst::MOV(
|
||||
{{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Rd,Cd);
|
||||
0x2: Cpl0CondInst::MOV(
|
||||
{{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Cd,Rd);
|
||||
}
|
||||
default: UD2();
|
||||
}
|
||||
// operand size (0x66)
|
||||
0x1: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: Cpl0CondInst::MOV(
|
||||
{{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Rd,Cd);
|
||||
0x2: Cpl0CondInst::MOV(
|
||||
{{misc_reg::isValid(misc_reg::cr(MODRM_REG))}},Cd,Rd);
|
||||
}
|
||||
default: UD2();
|
||||
}
|
||||
0x05: decode LEGACY_DECODEVAL {
|
||||
|
||||
Reference in New Issue
Block a user