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); \
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.
*/
@ -669,23 +673,23 @@ typedef struct ZydisInstructionDefinitionDEFAULT_
typedef struct ZydisInstructionDefinition3DNOW_
{
ZydisInstructionDefinition base;
ZYDIS_INSTRUCTION_DEFINITION_BASE;
} ZydisInstructionDefinition3DNOW;
typedef struct ZydisInstructionDefinitionXOP_
{
ZydisInstructionDefinition base;
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
} ZydisInstructionDefinitionXOP;
typedef struct ZydisInstructionDefinitionVEX_
{
ZYDIS_INSTRUCTION_DEFINITION_BASE;
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
ZydisVEXStaticBroadcast broadcast ZYDIS_BITFIELD(3);
} ZydisInstructionDefinitionVEX;
typedef struct ZydisInstructionDefinitionEVEX_
{
ZYDIS_INSTRUCTION_DEFINITION_BASE;
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
ZydisInternalVectorLength vectorLength ZYDIS_BITFIELD(2);
ZydisEVEXTupleType tupleType ZYDIS_BITFIELD(4);
ZydisInternalElementSize elementSize ZYDIS_BITFIELD(4);
@ -696,7 +700,7 @@ typedef struct ZydisInstructionDefinitionEVEX_
typedef struct ZydisInstructionDefinitionMVEX_
{
ZYDIS_INSTRUCTION_DEFINITION_BASE;
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
ZydisMVEXFunctionality functionality ZYDIS_BITFIELD(5);
ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD(2);
ZydisBool hasElementGranularity ZYDIS_BITFIELD(1);

View File

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