mirror of https://github.com/x64dbg/zydis
Various bugfixes
- Fixed operand-size and element-count of AGEN operands - Fixed decoding of 8-bit modrm.rm register-operands - Fixed vector-length for EVEX instructions with rounding-semantics
This commit is contained in:
parent
2d2e1acf27
commit
4bceac86c9
|
@ -750,6 +750,10 @@ enum ZydisTupleTypes
|
||||||
* @brief Tuple1 Fixed
|
* @brief Tuple1 Fixed
|
||||||
*/
|
*/
|
||||||
ZYDIS_TUPLETYPE_T1F,
|
ZYDIS_TUPLETYPE_T1F,
|
||||||
|
/**
|
||||||
|
* @brief Tuple1 4x32
|
||||||
|
*/
|
||||||
|
ZYDIS_TUPLETYPE_T1_4X,
|
||||||
/**
|
/**
|
||||||
* @brief Gather / Scatter
|
* @brief Gather / Scatter
|
||||||
*/
|
*/
|
||||||
|
@ -785,11 +789,7 @@ enum ZydisTupleTypes
|
||||||
/**
|
/**
|
||||||
* @brief MOVDDUP
|
* @brief MOVDDUP
|
||||||
*/
|
*/
|
||||||
ZYDIS_TUPLETYPE_DUP,
|
ZYDIS_TUPLETYPE_DUP
|
||||||
/**
|
|
||||||
* @brief Tuple1 4x32
|
|
||||||
*/
|
|
||||||
ZYDIS_TUPLETYPE_T1_4X
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -290,6 +290,43 @@ enum ZydisImplicitMemBase
|
||||||
/* Instruction definition */
|
/* Instruction definition */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisInternalVectorLength datatype.
|
||||||
|
*/
|
||||||
|
typedef uint8_t ZydisInternalVectorLength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Values that represent internal vector-lengths.
|
||||||
|
*/
|
||||||
|
enum ZydisInternalVectorLengths
|
||||||
|
{
|
||||||
|
ZYDIS_IVECTOR_LENGTH_DEFAULT,
|
||||||
|
ZYDIS_IVECTOR_LENGTH_FIXED_128,
|
||||||
|
ZYDIS_IVECTOR_LENGTH_FIXED_256,
|
||||||
|
ZYDIS_IVECTOR_LENGTH_FIXED_512
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisInternalElementSize datatype.
|
||||||
|
*/
|
||||||
|
typedef uint8_t ZydisInternalElementSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Values that represent internal element-sizes.
|
||||||
|
*/
|
||||||
|
enum ZydisInternalElementSizes
|
||||||
|
{
|
||||||
|
ZYDIS_IELEMENT_SIZE_INVALID,
|
||||||
|
ZYDIS_IELEMENT_SIZE_8,
|
||||||
|
ZYDIS_IELEMENT_SIZE_16,
|
||||||
|
ZYDIS_IELEMENT_SIZE_32,
|
||||||
|
ZYDIS_IELEMENT_SIZE_64
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisEVEXFunctionality datatype.
|
* @brief Defines the @c ZydisEVEXFunctionality datatype.
|
||||||
*/
|
*/
|
||||||
|
@ -392,8 +429,9 @@ typedef struct ZydisInstructionDefinitionVEX_
|
||||||
typedef struct ZydisInstructionDefinitionEVEX_
|
typedef struct ZydisInstructionDefinitionEVEX_
|
||||||
{
|
{
|
||||||
ZYDIS_INSTRUCTION_DEFINITION_BASE;
|
ZYDIS_INSTRUCTION_DEFINITION_BASE;
|
||||||
|
ZydisInternalVectorLength vectorLength: 2;
|
||||||
ZydisTupleType tupleType : 4;
|
ZydisTupleType tupleType : 4;
|
||||||
uint8_t elementSize : 7;
|
ZydisInternalElementSize elementSize : 4;
|
||||||
ZydisEVEXFunctionality functionality : 2;
|
ZydisEVEXFunctionality functionality : 2;
|
||||||
ZydisMaskPolicy maskPolicy : 2;
|
ZydisMaskPolicy maskPolicy : 2;
|
||||||
} ZydisInstructionDefinitionEVEX;
|
} ZydisInstructionDefinitionEVEX;
|
||||||
|
|
120
src/Decoder.c
120
src/Decoder.c
|
@ -940,7 +940,16 @@ static void ZydisSetOperandSizeAndElementInfo(ZydisDecoderContext* context,
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_3DNOW:
|
case ZYDIS_INSTRUCTION_ENCODING_3DNOW:
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_XOP:
|
case ZYDIS_INSTRUCTION_ENCODING_XOP:
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_VEX:
|
case ZYDIS_INSTRUCTION_ENCODING_VEX:
|
||||||
operand->size = definition->size[context->eoszIndex] * 8;
|
if (operand->mem.isAddressGenOnly)
|
||||||
|
{
|
||||||
|
ZYDIS_ASSERT(definition->size[context->eoszIndex] == 0);
|
||||||
|
operand->size = info->addressWidth;
|
||||||
|
operand->elementCount = 1;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
ZYDIS_ASSERT(definition->size[context->eoszIndex]);
|
||||||
|
operand->size = definition->size[context->eoszIndex] * 8;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
|
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
|
||||||
if (definition->size[context->eoszIndex])
|
if (definition->size[context->eoszIndex])
|
||||||
|
@ -977,6 +986,7 @@ static void ZydisSetOperandSizeAndElementInfo(ZydisDecoderContext* context,
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ZYDIS_ASSERT(operand->size);
|
||||||
break;
|
break;
|
||||||
case ZYDIS_INSTRUCTION_ENCODING_MVEX:
|
case ZYDIS_INSTRUCTION_ENCODING_MVEX:
|
||||||
// TODO:
|
// TODO:
|
||||||
|
@ -993,7 +1003,6 @@ static void ZydisSetOperandSizeAndElementInfo(ZydisDecoderContext* context,
|
||||||
break;
|
break;
|
||||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||||
operand->size = definition->size[context->eoszIndex] * 8;
|
operand->size = definition->size[context->eoszIndex] * 8;
|
||||||
ZYDIS_ASSERT(operand->size);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
|
@ -1523,10 +1532,18 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
|
||||||
break;
|
break;
|
||||||
case ZYDIS_OPERAND_ENCODING_MODRM_RM:
|
case ZYDIS_OPERAND_ENCODING_MODRM_RM:
|
||||||
ZYDIS_ASSERT(info->details.modrm.isDecoded);
|
ZYDIS_ASSERT(info->details.modrm.isDecoded);
|
||||||
ZYDIS_CHECK(
|
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX)
|
||||||
|
{
|
||||||
|
ZYDIS_CHECK(
|
||||||
|
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
||||||
|
(context->cache.X << 4) |
|
||||||
|
(context->cache.B << 3) | info->details.modrm.rm));
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
ZYDIS_CHECK(
|
||||||
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
|
||||||
(context->cache.X << 4) |
|
|
||||||
(context->cache.B << 3) | info->details.modrm.rm));
|
(context->cache.B << 3) | info->details.modrm.rm));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ZYDIS_OPERAND_ENCODING_OPCODE:
|
case ZYDIS_OPERAND_ENCODING_OPCODE:
|
||||||
{
|
{
|
||||||
|
@ -2086,35 +2103,57 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
|
||||||
ZYDIS_ASSERT(context);
|
ZYDIS_ASSERT(context);
|
||||||
ZYDIS_ASSERT(info);
|
ZYDIS_ASSERT(info);
|
||||||
ZYDIS_ASSERT(definition);
|
ZYDIS_ASSERT(definition);
|
||||||
|
|
||||||
// Vector length
|
|
||||||
switch (context->cache.LL)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
info->avx.vectorLength = ZYDIS_VECTOR_LENGTH_128;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
info->avx.vectorLength = ZYDIS_VECTOR_LENGTH_256;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
info->avx.vectorLength = ZYDIS_VECTOR_LENGTH_512;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ZYDIS_UNREACHABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX)
|
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX)
|
||||||
{
|
{
|
||||||
const ZydisInstructionDefinitionEVEX* def =
|
const ZydisInstructionDefinitionEVEX* def =
|
||||||
(const ZydisInstructionDefinitionEVEX*)definition;
|
(const ZydisInstructionDefinitionEVEX*)definition;
|
||||||
|
|
||||||
|
uint8_t vectorLength = vectorLength = context->cache.LL;;
|
||||||
|
if (def->vectorLength)
|
||||||
|
{
|
||||||
|
vectorLength = def->vectorLength - 1;
|
||||||
|
}
|
||||||
|
// Vector length
|
||||||
|
switch (vectorLength)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
info->avx.vectorLength = ZYDIS_VECTOR_LENGTH_128;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
info->avx.vectorLength = ZYDIS_VECTOR_LENGTH_256;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
info->avx.vectorLength = ZYDIS_VECTOR_LENGTH_512;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ZYDIS_UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
info->avx.tupleType = def->tupleType;
|
info->avx.tupleType = def->tupleType;
|
||||||
if (info->avx.tupleType)
|
if (info->avx.tupleType)
|
||||||
{
|
{
|
||||||
ZYDIS_ASSERT(info->details.modrm.mod != 3);
|
ZYDIS_ASSERT(info->details.modrm.mod != 3);
|
||||||
ZYDIS_ASSERT((def->elementSize == 8) || (def->elementSize == 16) ||
|
ZYDIS_ASSERT(def->elementSize);
|
||||||
(def->elementSize == 32) || (def->elementSize == 64));
|
|
||||||
info->avx.elementSize = def->elementSize;
|
// Element size
|
||||||
|
switch (def->elementSize)
|
||||||
|
{
|
||||||
|
case ZYDIS_IELEMENT_SIZE_8:
|
||||||
|
info->avx.elementSize = 8;
|
||||||
|
break;
|
||||||
|
case ZYDIS_IELEMENT_SIZE_16:
|
||||||
|
info->avx.elementSize = 16;
|
||||||
|
break;
|
||||||
|
case ZYDIS_IELEMENT_SIZE_32:
|
||||||
|
info->avx.elementSize = 32;
|
||||||
|
break;
|
||||||
|
case ZYDIS_IELEMENT_SIZE_64:
|
||||||
|
info->avx.elementSize = 64;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ZYDIS_UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
// Compressed disp8 scale and broadcast-factor
|
// Compressed disp8 scale and broadcast-factor
|
||||||
switch (info->avx.tupleType)
|
switch (info->avx.tupleType)
|
||||||
|
@ -2243,6 +2282,18 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ZYDIS_TUPLETYPE_GSCAT:
|
||||||
|
switch (context->cache.W)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ZYDIS_ASSERT(info->avx.elementSize == 64);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ZYDIS_UNREACHABLE;
|
||||||
|
}
|
||||||
case ZYDIS_TUPLETYPE_T1S:
|
case ZYDIS_TUPLETYPE_T1S:
|
||||||
info->avx.compressedDisp8Scale = info->avx.elementSize / 8;
|
info->avx.compressedDisp8Scale = info->avx.elementSize / 8;
|
||||||
break;
|
break;
|
||||||
|
@ -2259,20 +2310,10 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZYDIS_TUPLETYPE_GSCAT:
|
case ZYDIS_TUPLETYPE_T1_4X:
|
||||||
switch (context->cache.W)
|
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
||||||
{
|
ZYDIS_ASSERT(context->cache.W == 0);
|
||||||
case 0:
|
info->avx.compressedDisp8Scale = 16;
|
||||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
|
||||||
info->avx.compressedDisp8Scale = 4;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
ZYDIS_ASSERT(info->avx.elementSize == 64);
|
|
||||||
info->avx.compressedDisp8Scale = 8;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ZYDIS_UNREACHABLE;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_TUPLETYPE_T2:
|
case ZYDIS_TUPLETYPE_T2:
|
||||||
switch (context->cache.W)
|
switch (context->cache.W)
|
||||||
|
@ -2382,11 +2423,6 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZYDIS_TUPLETYPE_T1_4X:
|
|
||||||
ZYDIS_ASSERT(info->avx.elementSize == 32);
|
|
||||||
ZYDIS_ASSERT(context->cache.W == 0);
|
|
||||||
info->avx.compressedDisp8Scale = 16;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
ZYDIS_UNREACHABLE;
|
ZYDIS_UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue