From 61f607e1dfdfe996e5cf8263564398670dc40369 Mon Sep 17 00:00:00 2001 From: flobernd Date: Wed, 17 Jan 2018 00:31:32 +0100 Subject: [PATCH] Minor optimizations and bugfixes - Fixed `XCHG R8, RAX` falsely beeing decoded as `NOP` - Fixed `EVEX/MVEX.R'` not beeing ignored in 16- and 32-bit mode - Removed some unnecessary conditions from operand-action related code --- src/Decoder.c | 30 ++++++++++++++++++++++++++---- src/Generated/DecoderTables.inc | 2 +- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/Decoder.c b/src/Decoder.c index aa0b0dc..ea41ddc 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -1994,7 +1994,7 @@ FinalizeOperand: #if !defined(ZYDIS_DISABLE_EVEX) || !defined(ZYDIS_DISABLE_MVEX) // Fix operand-action for EVEX instructions with merge-mask - if (((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || + /*if (((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)) && (instruction->avx.mask.mode == ZYDIS_MASK_MODE_MERGE) && (instruction->operandCount >= 3) && @@ -2027,6 +2027,28 @@ FinalizeOperand: default: break; } + }*/ + if (instruction->avx.mask.reg && (instruction->avx.mask.mode == ZYDIS_MASK_MODE_MERGE) && + !instruction->avx.mask.isControlMask) + { + ZYDIS_ASSERT(instruction->operandCount >= 2); + switch (instruction->operands[0].action) + { + case ZYDIS_OPERAND_ACTION_WRITE: + if (instruction->operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY) + { + instruction->operands[0].action = ZYDIS_OPERAND_ACTION_CONDWRITE; + } else + { + instruction->operands[0].action = ZYDIS_OPERAND_ACTION_READ_CONDWRITE; + } + break; + case ZYDIS_OPERAND_ACTION_READWRITE: + instruction->operands[0].action = ZYDIS_OPERAND_ACTION_READ_CONDWRITE; + break; + default: + break; + } } #endif @@ -4152,7 +4174,7 @@ static ZydisStatus ZydisCheckErrorConditions(ZydisDecoderContext* context, case ZYDIS_REG_CONSTRAINTS_NONE: break; case ZYDIS_REG_CONSTRAINTS_GPR: - if (context->cache.R2) + if ((context->decoder->machineMode == ZYDIS_MACHINE_MODE_LONG_64) && context->cache.R2) { return ZYDIS_STATUS_BAD_REGISTER; } @@ -4198,8 +4220,8 @@ static ZydisStatus ZydisCheckErrorConditions(ZydisDecoderContext* context, } break; case ZYDIS_REG_CONSTRAINTS_MASK: - // TODO: ZYDIS_ASSERT(!context->cache.R2) ? - if (context->cache.R || context->cache.R2) + if ((context->decoder->machineMode == ZYDIS_MACHINE_MODE_LONG_64) && + (context->cache.R || context->cache.R2)) { return ZYDIS_STATUS_BAD_REGISTER; } diff --git a/src/Generated/DecoderTables.inc b/src/Generated/DecoderTables.inc index 5785eb9..e84368b 100644 --- a/src/Generated/DecoderTables.inc +++ b/src/Generated/DecoderTables.inc @@ -2620,7 +2620,7 @@ const ZydisDecoderTreeNode filtersMandatoryPrefix[][5] = { ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_OPERAND_SIZE, 0x5), ZYDIS_INVALID, ZYDIS_INVALID, ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_OPERAND_SIZE, 0x6), ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_OPERAND_SIZE, 0x7) }, { ZYDIS_DEFINITION(0x0, 0x3E4), ZYDIS_INVALID, ZYDIS_INVALID, ZYDIS_DEFINITION(0x0, 0x3E5), ZYDIS_DEFINITION(0x0, 0x3E6) }, { ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_OPERAND_SIZE, 0x8), ZYDIS_INVALID, ZYDIS_INVALID, ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_OPERAND_SIZE, 0x9), ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_OPERAND_SIZE, 0xA) }, - { ZYDIS_DEFINITION(0x0, 0x390), ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_REX_B, 0x0), ZYDIS_INVALID, ZYDIS_DEFINITION(0x0, 0x436), ZYDIS_INVALID }, + { ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_REX_B, 0x0), ZYDIS_INVALID, ZYDIS_INVALID, ZYDIS_DEFINITION(0x0, 0x436), ZYDIS_INVALID }, { ZYDIS_DEFINITION(0x0, 0x353), ZYDIS_INVALID, ZYDIS_INVALID, ZYDIS_DEFINITION(0x0, 0x354), ZYDIS_DEFINITION(0x0, 0x355) }, { ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_OPERAND_SIZE, 0x11), ZYDIS_INVALID, ZYDIS_INVALID, ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_OPERAND_SIZE, 0x12), ZYDIS_FILTER(ZYDIS_NODETYPE_FILTER_OPERAND_SIZE, 0x13) }, { ZYDIS_DEFINITION(0x0, 0xEB), ZYDIS_INVALID, ZYDIS_INVALID, ZYDIS_DEFINITION(0x0, 0xEC), ZYDIS_DEFINITION(0x0, 0xED) },