mirror of https://github.com/x64dbg/zydis
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:
parent
e7a7be70e9
commit
55400e9206
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue