mirror of https://github.com/x64dbg/zydis
Improved instruction decoding
- Decoding of EVEX/MVEX instructions without a NDS/NDD-operand encoded in `.vvvv` and without a VSIB-operand will now fail, if `.v'` is != 1b - Added information about XACQUIRE, XRELEASE and BOUND prefixes to the instruction definitions - Fixed immediate-decoding of the `vpermil2pd` / `vpermil2ps` instruction
This commit is contained in:
parent
73b02f6d12
commit
65fe4a4e6c
|
@ -110,10 +110,9 @@ enum ZydisOperandEncodings
|
||||||
ZYDIS_OPERAND_ENCODING_MODRM_REG,
|
ZYDIS_OPERAND_ENCODING_MODRM_REG,
|
||||||
ZYDIS_OPERAND_ENCODING_MODRM_RM,
|
ZYDIS_OPERAND_ENCODING_MODRM_RM,
|
||||||
ZYDIS_OPERAND_ENCODING_OPCODE,
|
ZYDIS_OPERAND_ENCODING_OPCODE,
|
||||||
ZYDIS_OPERAND_ENCODING_NDS,
|
ZYDIS_OPERAND_ENCODING_NDSNDD,
|
||||||
|
ZYDIS_OPERAND_ENCODING_IS4,
|
||||||
ZYDIS_OPERAND_ENCODING_MASK,
|
ZYDIS_OPERAND_ENCODING_MASK,
|
||||||
ZYDIS_OPERAND_ENCODING_UIMM8_LO,
|
|
||||||
ZYDIS_OPERAND_ENCODING_UIMM8_HI,
|
|
||||||
ZYDIS_OPERAND_ENCODING_DISP8,
|
ZYDIS_OPERAND_ENCODING_DISP8,
|
||||||
ZYDIS_OPERAND_ENCODING_DISP16,
|
ZYDIS_OPERAND_ENCODING_DISP16,
|
||||||
ZYDIS_OPERAND_ENCODING_DISP32,
|
ZYDIS_OPERAND_ENCODING_DISP32,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -648,6 +648,10 @@ enum ZydisMaskPolicies
|
||||||
ZYDIS_INSTRUCTION_DEFINITION_BASE; \
|
ZYDIS_INSTRUCTION_DEFINITION_BASE; \
|
||||||
ZydisBool hasNDSNDDOperand ZYDIS_BITFIELD( 1)
|
ZydisBool hasNDSNDDOperand ZYDIS_BITFIELD( 1)
|
||||||
|
|
||||||
|
#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX \
|
||||||
|
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; \
|
||||||
|
ZydisBool hasVSIB ZYDIS_BITFIELD( 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisInstructionDefinition struct.
|
* @brief Defines the @c ZydisInstructionDefinition struct.
|
||||||
*/
|
*/
|
||||||
|
@ -689,7 +693,7 @@ typedef struct ZydisInstructionDefinitionVEX_
|
||||||
|
|
||||||
typedef struct ZydisInstructionDefinitionEVEX_
|
typedef struct ZydisInstructionDefinitionEVEX_
|
||||||
{
|
{
|
||||||
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
|
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX;
|
||||||
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);
|
||||||
|
@ -700,7 +704,7 @@ typedef struct ZydisInstructionDefinitionEVEX_
|
||||||
|
|
||||||
typedef struct ZydisInstructionDefinitionMVEX_
|
typedef struct ZydisInstructionDefinitionMVEX_
|
||||||
{
|
{
|
||||||
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
|
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX;
|
||||||
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);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1780,7 +1780,7 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
|
||||||
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
||||||
ZydisCalcRegisterId(context, info, ZYDIS_REG_ENCODING_OPCODE, registerClass)));
|
ZydisCalcRegisterId(context, info, ZYDIS_REG_ENCODING_OPCODE, registerClass)));
|
||||||
break;
|
break;
|
||||||
case ZYDIS_OPERAND_ENCODING_NDS:
|
case ZYDIS_OPERAND_ENCODING_NDSNDD:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(
|
||||||
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
||||||
ZydisCalcRegisterId(context, info, ZYDIS_REG_ENCODING_NDSNDD, registerClass)));
|
ZydisCalcRegisterId(context, info, ZYDIS_REG_ENCODING_NDSNDD, registerClass)));
|
||||||
|
@ -1790,7 +1790,7 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
|
||||||
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
||||||
ZydisCalcRegisterId(context, info, ZYDIS_REG_ENCODING_MASK, registerClass)));
|
ZydisCalcRegisterId(context, info, ZYDIS_REG_ENCODING_MASK, registerClass)));
|
||||||
break;
|
break;
|
||||||
case ZYDIS_OPERAND_ENCODING_UIMM8_HI:
|
case ZYDIS_OPERAND_ENCODING_IS4:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(
|
||||||
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
||||||
ZydisCalcRegisterId(context, info, ZYDIS_REG_ENCODING_IS4, registerClass)));
|
ZydisCalcRegisterId(context, info, ZYDIS_REG_ENCODING_IS4, registerClass)));
|
||||||
|
@ -1866,7 +1866,15 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
|
||||||
ZYDIS_ASSERT((immId == 0) || (immId == 1));
|
ZYDIS_ASSERT((immId == 0) || (immId == 1));
|
||||||
info->operands[i].type = ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
info->operands[i].type = ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
||||||
info->operands[i].size = operand->size[context->eoszIndex] * 8;
|
info->operands[i].size = operand->size[context->eoszIndex] * 8;
|
||||||
info->operands[i].imm.value.uqword = info->details.imm[immId].value.uqword;
|
if (operand->op.encoding == ZYDIS_OPERAND_ENCODING_IS4)
|
||||||
|
{
|
||||||
|
// The upper half of the 8-bit immediate is used to encode a register specifier
|
||||||
|
ZYDIS_ASSERT(info->details.imm[immId].dataSize == 8);
|
||||||
|
info->operands[i].imm.value.ubyte = info->details.imm[immId].value.ubyte & 0x0F;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
info->operands[i].imm.value.uqword = info->details.imm[immId].value.uqword;
|
||||||
|
}
|
||||||
info->operands[i].imm.isSigned = info->details.imm[immId].isSigned;
|
info->operands[i].imm.isSigned = info->details.imm[immId].isSigned;
|
||||||
info->operands[i].imm.isRelative = info->details.imm[immId].isRelative;
|
info->operands[i].imm.isRelative = info->details.imm[immId].isRelative;
|
||||||
++immId;
|
++immId;
|
||||||
|
@ -4017,6 +4025,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
|
||||||
ZYDIS_CHECK(ZydisDecodeOptionalInstructionParts(context, info, optionalParts));
|
ZYDIS_CHECK(ZydisDecodeOptionalInstructionParts(context, info, optionalParts));
|
||||||
|
|
||||||
ZydisBool hasNDSNDDOperand = ZYDIS_FALSE;
|
ZydisBool hasNDSNDDOperand = ZYDIS_FALSE;
|
||||||
|
ZydisBool hasVSIB = ZYDIS_FALSE;
|
||||||
ZydisMaskPolicy maskPolicy = ZYDIS_MASK_POLICY_INVALID;
|
ZydisMaskPolicy maskPolicy = ZYDIS_MASK_POLICY_INVALID;
|
||||||
switch (info->encoding)
|
switch (info->encoding)
|
||||||
{
|
{
|
||||||
|
@ -4059,6 +4068,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
|
||||||
const ZydisInstructionDefinitionEVEX* def =
|
const ZydisInstructionDefinitionEVEX* def =
|
||||||
(const ZydisInstructionDefinitionEVEX*)definition;
|
(const ZydisInstructionDefinitionEVEX*)definition;
|
||||||
hasNDSNDDOperand = def->hasNDSNDDOperand;
|
hasNDSNDDOperand = def->hasNDSNDDOperand;
|
||||||
|
hasVSIB = def->hasVSIB;
|
||||||
maskPolicy = def->maskPolicy;
|
maskPolicy = def->maskPolicy;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4067,6 +4077,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
|
||||||
const ZydisInstructionDefinitionMVEX* def =
|
const ZydisInstructionDefinitionMVEX* def =
|
||||||
(const ZydisInstructionDefinitionMVEX*)definition;
|
(const ZydisInstructionDefinitionMVEX*)definition;
|
||||||
hasNDSNDDOperand = def->hasNDSNDDOperand;
|
hasNDSNDDOperand = def->hasNDSNDDOperand;
|
||||||
|
hasVSIB = def->hasVSIB;
|
||||||
maskPolicy = def->maskPolicy;
|
maskPolicy = def->maskPolicy;
|
||||||
|
|
||||||
// Check for invalid MVEX.SSS values
|
// Check for invalid MVEX.SSS values
|
||||||
|
@ -4135,14 +4146,18 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add check for invalid .V`
|
// Check for invalid `XOP/VEX/EVEX/MVEX.vvvv` value
|
||||||
|
|
||||||
// Check for invalid XOP/VEX/EVEX/MVEX.vvvv value
|
|
||||||
if (!hasNDSNDDOperand && (context->cache.v_vvvv & 0x0F))
|
if (!hasNDSNDDOperand && (context->cache.v_vvvv & 0x0F))
|
||||||
{
|
{
|
||||||
return ZYDIS_STATUS_DECODING_ERROR;
|
return ZYDIS_STATUS_DECODING_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for invalid `EVEX/MVEX.v'` value
|
||||||
|
if (!hasNDSNDDOperand && !hasVSIB && context->cache.V2)
|
||||||
|
{
|
||||||
|
return ZYDIS_STATUS_DECODING_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for invalid MASK registers
|
// Check for invalid MASK registers
|
||||||
switch (maskPolicy)
|
switch (maskPolicy)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue