Improved decoding of XOP/VEX/EVEX/MVEX instructions

Decoding of XOP/VEX/EVEX/MVEX instructions without a NDS register encoded in .vvvv will now fail, if the .vvvv value is != 1111b
This commit is contained in:
flobernd 2017-06-27 04:14:17 +02:00
parent e7a7be70e9
commit 55400e9206
3 changed files with 5004 additions and 4975 deletions

File diff suppressed because it is too large Load Diff

View File

@ -644,6 +644,10 @@ enum ZydisMaskPolicies
uint16_t operandReference ZYDIS_BITFIELD(15); \ uint16_t operandReference ZYDIS_BITFIELD(15); \
uint8_t operandSizeMap ZYDIS_BITFIELD( 3) uint8_t operandSizeMap ZYDIS_BITFIELD( 3)
#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR \
ZYDIS_INSTRUCTION_DEFINITION_BASE; \
ZydisBool hasNDSOperand ZYDIS_BITFIELD( 1)
/** /**
* @brief Defines the @c ZydisInstructionDefinition struct. * @brief Defines the @c ZydisInstructionDefinition struct.
*/ */
@ -669,23 +673,23 @@ typedef struct ZydisInstructionDefinitionDEFAULT_
typedef struct ZydisInstructionDefinition3DNOW_ typedef struct ZydisInstructionDefinition3DNOW_
{ {
ZydisInstructionDefinition base; ZYDIS_INSTRUCTION_DEFINITION_BASE;
} ZydisInstructionDefinition3DNOW; } ZydisInstructionDefinition3DNOW;
typedef struct ZydisInstructionDefinitionXOP_ typedef struct ZydisInstructionDefinitionXOP_
{ {
ZydisInstructionDefinition base; ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
} ZydisInstructionDefinitionXOP; } ZydisInstructionDefinitionXOP;
typedef struct ZydisInstructionDefinitionVEX_ typedef struct ZydisInstructionDefinitionVEX_
{ {
ZYDIS_INSTRUCTION_DEFINITION_BASE; ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
ZydisVEXStaticBroadcast broadcast ZYDIS_BITFIELD(3); ZydisVEXStaticBroadcast broadcast ZYDIS_BITFIELD(3);
} ZydisInstructionDefinitionVEX; } ZydisInstructionDefinitionVEX;
typedef struct ZydisInstructionDefinitionEVEX_ typedef struct ZydisInstructionDefinitionEVEX_
{ {
ZYDIS_INSTRUCTION_DEFINITION_BASE; ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
ZydisInternalVectorLength vectorLength ZYDIS_BITFIELD(2); ZydisInternalVectorLength vectorLength ZYDIS_BITFIELD(2);
ZydisEVEXTupleType tupleType ZYDIS_BITFIELD(4); ZydisEVEXTupleType tupleType ZYDIS_BITFIELD(4);
ZydisInternalElementSize elementSize ZYDIS_BITFIELD(4); ZydisInternalElementSize elementSize ZYDIS_BITFIELD(4);
@ -696,7 +700,7 @@ typedef struct ZydisInstructionDefinitionEVEX_
typedef struct ZydisInstructionDefinitionMVEX_ typedef struct ZydisInstructionDefinitionMVEX_
{ {
ZYDIS_INSTRUCTION_DEFINITION_BASE; ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
ZydisMVEXFunctionality functionality ZYDIS_BITFIELD(5); ZydisMVEXFunctionality functionality ZYDIS_BITFIELD(5);
ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD(2); ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD(2);
ZydisBool hasElementGranularity ZYDIS_BITFIELD(1); ZydisBool hasElementGranularity ZYDIS_BITFIELD(1);

View File

@ -641,6 +641,7 @@ static ZydisStatus ZydisReadDisplacement(ZydisDecoderContext* context, ZydisInst
default: default:
ZYDIS_UNREACHABLE; ZYDIS_UNREACHABLE;
} }
// TODO: Fix endianess on big-endian systems // TODO: Fix endianess on big-endian systems
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
@ -3762,6 +3763,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
ZydisGetOptionalInstructionParts(node, &optionalParts); ZydisGetOptionalInstructionParts(node, &optionalParts);
ZYDIS_CHECK(ZydisDecodeOptionalInstructionParts(context, info, optionalParts)); ZYDIS_CHECK(ZydisDecodeOptionalInstructionParts(context, info, optionalParts));
ZydisBool hasNDSOperand = ZYDIS_FALSE;
ZydisMaskPolicy maskPolicy = ZYDIS_MASK_POLICY_INVALID; ZydisMaskPolicy maskPolicy = ZYDIS_MASK_POLICY_INVALID;
switch (info->encoding) switch (info->encoding)
{ {
@ -3786,23 +3788,40 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
break; break;
} }
case ZYDIS_INSTRUCTION_ENCODING_XOP: case ZYDIS_INSTRUCTION_ENCODING_XOP:
case ZYDIS_INSTRUCTION_ENCODING_VEX: {
const ZydisInstructionDefinitionXOP* def =
(const ZydisInstructionDefinitionXOP*)definition;
hasNDSOperand = def->hasNDSOperand;
break; break;
}
case ZYDIS_INSTRUCTION_ENCODING_VEX:
{
const ZydisInstructionDefinitionVEX* def =
(const ZydisInstructionDefinitionVEX*)definition;
hasNDSOperand = def->hasNDSOperand;
break;
}
case ZYDIS_INSTRUCTION_ENCODING_EVEX: case ZYDIS_INSTRUCTION_ENCODING_EVEX:
{ {
const ZydisInstructionDefinitionEVEX* def = const ZydisInstructionDefinitionEVEX* def =
(const ZydisInstructionDefinitionEVEX*)definition; (const ZydisInstructionDefinitionEVEX*)definition;
hasNDSOperand = def->hasNDSOperand;
maskPolicy = def->maskPolicy; maskPolicy = def->maskPolicy;
// TODO: Check for invalid .vvvv value
break; break;
} }
case ZYDIS_INSTRUCTION_ENCODING_MVEX: case ZYDIS_INSTRUCTION_ENCODING_MVEX:
{ {
const ZydisInstructionDefinitionMVEX* def = const ZydisInstructionDefinitionMVEX* def =
(const ZydisInstructionDefinitionMVEX*)definition; (const ZydisInstructionDefinitionMVEX*)definition;
hasNDSOperand = def->hasNDSOperand;
maskPolicy = def->maskPolicy; maskPolicy = def->maskPolicy;
// Check for invalid MVEX.vvvv value
if (!def->hasNDSOperand && context->cache.v_vvvv)
{
return ZYDIS_STATUS_DECODING_ERROR;
}
// Check for invalid MVEX.SSS values // Check for invalid MVEX.SSS values
static const uint8_t lookup[25][8] = static const uint8_t lookup[25][8] =
{ {
@ -3869,6 +3888,12 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
ZYDIS_UNREACHABLE; ZYDIS_UNREACHABLE;
} }
// Check for invalid EVEX.vvvv value
if (!hasNDSOperand && context->cache.v_vvvv)
{
return ZYDIS_STATUS_DECODING_ERROR;
}
// Check for invalid MASK registers // Check for invalid MASK registers
switch (maskPolicy) switch (maskPolicy)
{ {