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_RM,
|
||||
ZYDIS_OPERAND_ENCODING_OPCODE,
|
||||
ZYDIS_OPERAND_ENCODING_NDS,
|
||||
ZYDIS_OPERAND_ENCODING_NDSNDD,
|
||||
ZYDIS_OPERAND_ENCODING_IS4,
|
||||
ZYDIS_OPERAND_ENCODING_MASK,
|
||||
ZYDIS_OPERAND_ENCODING_UIMM8_LO,
|
||||
ZYDIS_OPERAND_ENCODING_UIMM8_HI,
|
||||
ZYDIS_OPERAND_ENCODING_DISP8,
|
||||
ZYDIS_OPERAND_ENCODING_DISP16,
|
||||
ZYDIS_OPERAND_ENCODING_DISP32,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -648,6 +648,10 @@ enum ZydisMaskPolicies
|
|||
ZYDIS_INSTRUCTION_DEFINITION_BASE; \
|
||||
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.
|
||||
*/
|
||||
|
@ -689,7 +693,7 @@ typedef struct ZydisInstructionDefinitionVEX_
|
|||
|
||||
typedef struct ZydisInstructionDefinitionEVEX_
|
||||
{
|
||||
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
|
||||
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX;
|
||||
ZydisInternalVectorLength vectorLength ZYDIS_BITFIELD(2);
|
||||
ZydisEVEXTupleType tupleType ZYDIS_BITFIELD(4);
|
||||
ZydisInternalElementSize elementSize ZYDIS_BITFIELD(4);
|
||||
|
@ -700,7 +704,7 @@ typedef struct ZydisInstructionDefinitionEVEX_
|
|||
|
||||
typedef struct ZydisInstructionDefinitionMVEX_
|
||||
{
|
||||
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
|
||||
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX;
|
||||
ZydisMVEXFunctionality functionality ZYDIS_BITFIELD(5);
|
||||
ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD(2);
|
||||
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,
|
||||
ZydisCalcRegisterId(context, info, ZYDIS_REG_ENCODING_OPCODE, registerClass)));
|
||||
break;
|
||||
case ZYDIS_OPERAND_ENCODING_NDS:
|
||||
case ZYDIS_OPERAND_ENCODING_NDSNDD:
|
||||
ZYDIS_CHECK(
|
||||
ZydisDecodeOperandRegister(info, &info->operands[i], 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,
|
||||
ZydisCalcRegisterId(context, info, ZYDIS_REG_ENCODING_MASK, registerClass)));
|
||||
break;
|
||||
case ZYDIS_OPERAND_ENCODING_UIMM8_HI:
|
||||
case ZYDIS_OPERAND_ENCODING_IS4:
|
||||
ZYDIS_CHECK(
|
||||
ZydisDecodeOperandRegister(info, &info->operands[i], 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));
|
||||
info->operands[i].type = ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
||||
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.isRelative = info->details.imm[immId].isRelative;
|
||||
++immId;
|
||||
|
@ -4017,6 +4025,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
|
|||
ZYDIS_CHECK(ZydisDecodeOptionalInstructionParts(context, info, optionalParts));
|
||||
|
||||
ZydisBool hasNDSNDDOperand = ZYDIS_FALSE;
|
||||
ZydisBool hasVSIB = ZYDIS_FALSE;
|
||||
ZydisMaskPolicy maskPolicy = ZYDIS_MASK_POLICY_INVALID;
|
||||
switch (info->encoding)
|
||||
{
|
||||
|
@ -4059,6 +4068,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
|
|||
const ZydisInstructionDefinitionEVEX* def =
|
||||
(const ZydisInstructionDefinitionEVEX*)definition;
|
||||
hasNDSNDDOperand = def->hasNDSNDDOperand;
|
||||
hasVSIB = def->hasVSIB;
|
||||
maskPolicy = def->maskPolicy;
|
||||
break;
|
||||
}
|
||||
|
@ -4067,6 +4077,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
|
|||
const ZydisInstructionDefinitionMVEX* def =
|
||||
(const ZydisInstructionDefinitionMVEX*)definition;
|
||||
hasNDSNDDOperand = def->hasNDSNDDOperand;
|
||||
hasVSIB = def->hasVSIB;
|
||||
maskPolicy = def->maskPolicy;
|
||||
|
||||
// Check for invalid MVEX.SSS values
|
||||
|
@ -4135,14 +4146,18 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns
|
|||
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))
|
||||
{
|
||||
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
|
||||
switch (maskPolicy)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue