From 8976c7141a0836952a056e3163f8783cf6be7095 Mon Sep 17 00:00:00 2001 From: Alexis Engelke Date: Sat, 28 Nov 2020 13:54:19 +0100 Subject: [PATCH] decode: Fix erroneous decoding of high-byte regs --- decode.c | 16 ++++++++++++---- tests/test_decode.c | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/decode.c b/decode.c index b0d71ca..e3e3fcd 100644 --- a/decode.c +++ b/decode.c @@ -605,11 +605,19 @@ prefix_end: break; operand->size = operand_sizes[(desc->operand_sizes >> 2 * i) & 3]; + } - // if (operand->type == FD_OT_REG && operand->misc == FD_RT_GPL && - // !(prefixes & PREFIX_REX) && operand->size == 1 && operand->reg >= 4) - if (!(prefix_rex & PREFIX_REX) && (LOAD_LE_4(operand) & 0xfffcffff) == 0x01040101) - operand->misc = FD_RT_GPH; + if (UNLIKELY(op_size == 1 || instr->type == FDI_MOVSX || instr->type == FDI_MOVZX)) { + if (!(prefix_rex & PREFIX_REX)) { + for (int i = 0; i < 2; i++) { + FdOp* operand = &instr->operands[i]; + if (operand->type == FD_OT_NONE) + break; + if (operand->type == FD_OT_REG && operand->misc == FD_RT_GPL && + operand->size == 1 && operand->reg >= 4) + operand->misc = FD_RT_GPH; + } + } } instr->size = off; diff --git a/tests/test_decode.c b/tests/test_decode.c index fa5beaf..854aeca 100644 --- a/tests/test_decode.c +++ b/tests/test_decode.c @@ -280,6 +280,7 @@ main(int argc, char** argv) TEST64("\x66\x0f\x50\xc1", "[SSE_MOVMSKPD reg8:r0 reg16:r1]"); TEST("\x66\x0f\xc6\xc0\x01", "[SSE_SHUFPD reg16:r0 reg16:r0 imm1:0x1]"); TEST("\x66\x0f\x71\xd0\x01", "[SSE_PSRLW reg16:r0 imm1:0x1]"); + TEST("\x66\x0f\x3a\x20\xc4\x01", "[SSE_PINSRB reg16:r0 reg1:r4 imm1:0x1]"); TEST("\x66\x0f\x71\x10\x01", "UD"); TEST32("\xc4\x00", "[LES reg4:r0 mem0:r0]");