mirror of https://github.com/x64dbg/zydis
Improved formatting of decorators
This commit is contained in:
parent
9f735b0f51
commit
8a626388ae
|
@ -50,20 +50,23 @@ typedef uint32_t ZydisDecodeGranularity;
|
|||
*/
|
||||
enum ZydisDecodeGranularities
|
||||
{
|
||||
/**
|
||||
* @brief Defaults to `ZYDIS_DECODE_GRANULARITY_FULL`.
|
||||
*/
|
||||
ZYDIS_DECODE_GRANULARITY_DEFAULT,
|
||||
/**
|
||||
* @brief Minimal instruction decoding without semantic analysis.
|
||||
*
|
||||
* This mode should be sufficient, if you plan to analyse code for pure relocation purposes,
|
||||
* as it gives you access to the mnemonic, the instruction-length, displacements, immediates
|
||||
* and the `ZYDIS_ATTRIB_IS_RELATIVE` attribute.
|
||||
* This mode provides access to the mnemonic, the instruction-length, the effective
|
||||
* operand-size, the effective address-width, some attributes (e.g. `ZYDIS_ATTRIB_IS_RELATIVE`)
|
||||
* and all of the information in the `raw` field of the `ZydisDecodedInstruction` struct.
|
||||
*
|
||||
* Operands, most attributes and other specific information (like AVX info) are not
|
||||
* accessible in this mode.
|
||||
*/
|
||||
ZYDIS_DECODE_GRANULARITY_MINIMAL,
|
||||
/**
|
||||
* @brief Full physical and semantical instruction-decoding.
|
||||
* @brief Full physical and semantic instruction-decoding.
|
||||
*/
|
||||
ZYDIS_DECODE_GRANULARITY_FULL
|
||||
};
|
||||
|
|
|
@ -277,6 +277,26 @@ enum ZydisFormatterHookTypes
|
|||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisDecoratorType datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisDecoratorType;
|
||||
|
||||
/**
|
||||
* @brief Values that represent decorator-types.
|
||||
*/
|
||||
enum ZydisDecoratorTypes
|
||||
{
|
||||
ZYDIS_DECORATOR_TYPE_INVALID,
|
||||
ZYDIS_DECORATOR_TYPE_MASK,
|
||||
ZYDIS_DECORATOR_TYPE_BROADCAST,
|
||||
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL,
|
||||
ZYDIS_DECORATOR_TYPE_SAE,
|
||||
ZYDIS_DECORATOR_TYPE_SWIZZLE,
|
||||
ZYDIS_DECORATOR_TYPE_CONVERSION,
|
||||
ZYDIS_DECORATOR_TYPE_EVICTION_HINT
|
||||
};
|
||||
|
||||
typedef struct ZydisFormatter_ ZydisFormatter;
|
||||
|
||||
/**
|
||||
|
@ -373,6 +393,32 @@ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* for
|
|||
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
|
||||
ZydisDecodedOperand* operand, uint64_t address);
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisFormatterFormatDecoratorFunc function pointer.
|
||||
*
|
||||
* @param formatter A pointer to the @c ZydisFormatter instance.
|
||||
* @param buffer A pointer to the string-buffer.
|
||||
* @param bufferLen The length of the string-buffer.
|
||||
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
|
||||
* @param operand A pointer to the @c ZydisDecodedOperand struct.
|
||||
* @param type The decorator type.
|
||||
* @param mask The embedded-mask register (`ZYDIS_DECORATOR_TYPE_MASK` only).
|
||||
*
|
||||
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
||||
* formatting process to fail.
|
||||
*
|
||||
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
|
||||
* number of chars written.
|
||||
*
|
||||
* Returning @c ZYDIS_STATUS_SUCCESS without increasing the buffer-pointer is valid and will cause
|
||||
* the formatter to omit the current decorator.
|
||||
*
|
||||
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type.
|
||||
*/
|
||||
typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter,
|
||||
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
|
||||
ZydisDecodedOperand* operand, ZydisDecoratorType type, ZydisRegister mask);
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisFormatter struct.
|
||||
*/
|
||||
|
@ -393,15 +439,10 @@ struct ZydisFormatter_
|
|||
ZydisFormatterFormatOperandFunc funcFormatOperandImm;
|
||||
ZydisFormatterFormatOperandFunc funcPrintOperandSize;
|
||||
ZydisFormatterFormatOperandFunc funcPrintSegment;
|
||||
ZydisFormatterFormatOperandFunc funcPrintDecorator;
|
||||
ZydisFormatterFormatDecoratorFunc funcPrintDecorator;
|
||||
ZydisFormatterFormatAddressFunc funcPrintAddress;
|
||||
ZydisFormatterFormatOperandFunc funcPrintDisplacement;
|
||||
ZydisFormatterFormatOperandFunc funcPrintImmediate;
|
||||
const char* prefixHEX;
|
||||
const char* prefixOCT;
|
||||
const char* delimMnemonic;
|
||||
const char* delimOperands;
|
||||
const char* fmtDecorator; // TODO:
|
||||
ZydisFormatterFormatOperandFunc funcPrintImmediate;
|
||||
};
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
@ -435,13 +476,18 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterInitEx(ZydisFormatter* formatter, ZydisFo
|
|||
ZydisFormatterImmediateFormat immmediateFormat);
|
||||
|
||||
/**
|
||||
* @brief TODO:
|
||||
* @brief Replaces a formatter function with a custom callback and/or retrieves the currently
|
||||
* used function.
|
||||
*
|
||||
* @param formatter A pointer to the @c ZydisFormatter instance.
|
||||
* @param hook The formatter hook-type.
|
||||
* @param callback TODO: In Out
|
||||
* @param callback A pointer to a variable that contains the pointer of the callback function
|
||||
* and receives the pointer of the currently used function.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*
|
||||
* Call this function with `callback` pointing to a `NULL` value to retrieve the currently used
|
||||
* function without replacing it.
|
||||
*/
|
||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter,
|
||||
ZydisFormatterHookType hook, const void** callback);
|
||||
|
|
|
@ -2026,14 +2026,14 @@ FinalizeOperand:
|
|||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Sets prefix-related attributes for the given instruction.
|
||||
* @brief Sets attributes for the given instruction.
|
||||
*
|
||||
* @param context A pointer to the @c ZydisDecoderContext struct.
|
||||
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
|
||||
* @param definition A pointer to the @c ZydisInstructionDefinition struct.
|
||||
*/
|
||||
static void ZydisSetPrefixRelatedAttributes(ZydisDecoderContext* context,
|
||||
ZydisDecodedInstruction* instruction, const ZydisInstructionDefinition* definition)
|
||||
static void ZydisSetAttributes(ZydisDecoderContext* context, ZydisDecodedInstruction* instruction,
|
||||
const ZydisInstructionDefinition* definition)
|
||||
{
|
||||
ZYDIS_ASSERT(context);
|
||||
ZYDIS_ASSERT(instruction);
|
||||
|
@ -4294,7 +4294,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
|
|||
|
||||
if (context->decoder->decodeGranularity == ZYDIS_DECODE_GRANULARITY_FULL)
|
||||
{
|
||||
ZydisSetPrefixRelatedAttributes(context, instruction, definition);
|
||||
ZydisSetAttributes(context, instruction, definition);
|
||||
switch (instruction->encoding)
|
||||
{
|
||||
case ZYDIS_INSTRUCTION_ENCODING_XOP:
|
||||
|
|
392
src/Formatter.c
392
src/Formatter.c
|
@ -251,6 +251,11 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for
|
|||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((operand->id == 1) && (operand->encoding == ZYDIS_OPERAND_ENCODING_MASK))
|
||||
{
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
const char* reg = ZydisRegisterGetString(operand->reg);
|
||||
if (!reg)
|
||||
{
|
||||
|
@ -514,9 +519,11 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
|
|||
switch (operand->id)
|
||||
{
|
||||
case 0:
|
||||
typecast = ((instruction->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
|
||||
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
|
||||
(instruction->operands[0].size != instruction->operands[1].size)) ? instruction->operands[0].size : 0;
|
||||
typecast =
|
||||
((instruction->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
|
||||
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
|
||||
(instruction->operands[0].size != instruction->operands[1].size)) ?
|
||||
instruction->operands[0].size : 0;
|
||||
if (!typecast &&
|
||||
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER) &&
|
||||
(instruction->operands[1].reg == ZYDIS_REGISTER_CL))
|
||||
|
@ -539,8 +546,9 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
|
|||
case 1:
|
||||
case 2:
|
||||
typecast =
|
||||
(instruction->operands[operand->id - 1].size != instruction->operands[operand->id].size) ?
|
||||
instruction->operands[operand->id].size : 0;
|
||||
(instruction->operands[operand->id - 1].size !=
|
||||
instruction->operands[operand->id].size) ?
|
||||
instruction->operands[operand->id].size : 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -627,7 +635,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt
|
|||
|
||||
static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter,
|
||||
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
|
||||
ZydisDecodedOperand* operand)
|
||||
ZydisDecodedOperand* operand, ZydisDecoratorType type, ZydisRegister mask)
|
||||
{
|
||||
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
|
||||
{
|
||||
|
@ -635,194 +643,197 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
|||
}
|
||||
|
||||
const char* bufEnd = *buffer + bufferLen;
|
||||
|
||||
if (operand->id == 1)
|
||||
switch (type)
|
||||
{
|
||||
if ((operand->type == ZYDIS_OPERAND_TYPE_REGISTER) &&
|
||||
(operand->encoding == ZYDIS_OPERAND_ENCODING_MASK) &&
|
||||
(operand->reg != ZYDIS_REGISTER_K0))
|
||||
case ZYDIS_DECORATOR_TYPE_MASK:
|
||||
{
|
||||
if (mask != ZYDIS_REGISTER_K0)
|
||||
{
|
||||
const char* reg = ZydisRegisterGetString(operand->reg);
|
||||
const char* reg = ZydisRegisterGetString(mask);
|
||||
if (!reg)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE,
|
||||
" {%s}", reg));
|
||||
ZYDIS_CHECK(ZydisStringBufferAppendFormat(
|
||||
buffer, bufEnd - *buffer, ZYDIS_APPENDMODE, " {%s}", reg));
|
||||
if (instruction->avx.maskMode == ZYDIS_MASK_MODE_ZERO)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (instruction->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
if (!instruction->avx.broadcast.isStatic)
|
||||
{
|
||||
switch (instruction->avx.broadcast.mode)
|
||||
{
|
||||
case ZYDIS_BROADCAST_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_2:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_4:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_4_TO_8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to8}"));
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_4_TO_16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to16}"));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
switch (instruction->avx.conversionMode)
|
||||
{
|
||||
case ZYDIS_CONVERSION_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_FLOAT16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {float16}"));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_SINT8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint8}"));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_UINT8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint8}"));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_SINT16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint16}"));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_UINT16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint16}"));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (instruction->avx.hasEvictionHint)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {eh}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((operand->id == (instruction->operandCount - 1)) ||
|
||||
((operand->id != (instruction->operandCount - 1)) &&
|
||||
(instruction->operands[operand->id + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)))
|
||||
break;
|
||||
}
|
||||
case ZYDIS_DECORATOR_TYPE_BROADCAST:
|
||||
if (!instruction->avx.broadcast.isStatic)
|
||||
{
|
||||
if (instruction->avx.hasSAE)
|
||||
switch (instruction->avx.broadcast.mode)
|
||||
{
|
||||
switch (instruction->avx.roundingMode)
|
||||
{
|
||||
case ZYDIS_ROUNDING_MODE_INVALID:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sae}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RN:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn-sae}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RD:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd-sae}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RU:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru-sae}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RZ:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz-sae}"));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
} else
|
||||
{
|
||||
switch (instruction->avx.roundingMode)
|
||||
{
|
||||
case ZYDIS_ROUNDING_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RN:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RD:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RU:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RZ:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz}"));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
switch (instruction->avx.swizzleMode)
|
||||
{
|
||||
case ZYDIS_SWIZZLE_MODE_INVALID:
|
||||
case ZYDIS_SWIZZLE_MODE_DCBA:
|
||||
// Nothing to do here
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_CDAB:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cdab}"));
|
||||
case ZYDIS_BROADCAST_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_BADC:
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_2:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {badc}"));
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_DACB:
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_4:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dacb}"));
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_AAAA:
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {aaaa}"));
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_BBBB:
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {bbbb}"));
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_CCCC:
|
||||
case ZYDIS_BROADCAST_MODE_4_TO_8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cccc}"));
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to8}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_DDDD:
|
||||
case ZYDIS_BROADCAST_MODE_4_TO_16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dddd}"));
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to16}"));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL:
|
||||
if (instruction->avx.hasSAE)
|
||||
{
|
||||
switch (instruction->avx.roundingMode)
|
||||
{
|
||||
case ZYDIS_ROUNDING_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RN:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn-sae}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RD:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd-sae}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RU:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru-sae}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RZ:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz-sae}"));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
} else
|
||||
{
|
||||
switch (instruction->avx.roundingMode)
|
||||
{
|
||||
case ZYDIS_ROUNDING_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RN:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RD:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RU:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru}"));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RZ:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz}"));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZYDIS_DECORATOR_TYPE_SAE:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sae}"));
|
||||
break;
|
||||
case ZYDIS_DECORATOR_TYPE_SWIZZLE:
|
||||
switch (instruction->avx.swizzleMode)
|
||||
{
|
||||
case ZYDIS_SWIZZLE_MODE_INVALID:
|
||||
case ZYDIS_SWIZZLE_MODE_DCBA:
|
||||
// Nothing to do here
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_CDAB:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cdab}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_BADC:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {badc}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_DACB:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dacb}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_AAAA:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {aaaa}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_BBBB:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {bbbb}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_CCCC:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cccc}"));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_DDDD:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dddd}"));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_DECORATOR_TYPE_CONVERSION:
|
||||
switch (instruction->avx.conversionMode)
|
||||
{
|
||||
case ZYDIS_CONVERSION_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_FLOAT16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {float16}"));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_SINT8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint8}"));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_UINT8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint8}"));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_SINT16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint16}"));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_UINT16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint16}"));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_DECORATOR_TYPE_EVICTION_HINT:
|
||||
if (instruction->avx.hasEvictionHint)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {eh}"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
|
@ -903,8 +914,55 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
|
|||
if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
|
||||
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX))
|
||||
{
|
||||
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer,
|
||||
instruction, &instruction->operands[i]));
|
||||
if (i == 0)
|
||||
{
|
||||
if (instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK)
|
||||
{
|
||||
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
|
||||
bufEnd - *buffer, instruction, &instruction->operands[i],
|
||||
ZYDIS_DECORATOR_TYPE_MASK, instruction->operands[i + 1].reg));
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
|
||||
bufEnd - *buffer, instruction, &instruction->operands[i],
|
||||
ZYDIS_DECORATOR_TYPE_BROADCAST, ZYDIS_REGISTER_NONE));
|
||||
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
|
||||
{
|
||||
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
|
||||
bufEnd - *buffer, instruction, &instruction->operands[i],
|
||||
ZYDIS_DECORATOR_TYPE_CONVERSION, ZYDIS_REGISTER_NONE));
|
||||
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
|
||||
bufEnd - *buffer, instruction, &instruction->operands[i],
|
||||
ZYDIS_DECORATOR_TYPE_EVICTION_HINT, ZYDIS_REGISTER_NONE));
|
||||
}
|
||||
} else
|
||||
{
|
||||
if ((i == (instruction->operandCount - 1)) ||
|
||||
(instruction->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
|
||||
{
|
||||
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
|
||||
{
|
||||
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
|
||||
bufEnd - *buffer, instruction, &instruction->operands[i],
|
||||
ZYDIS_DECORATOR_TYPE_SWIZZLE, ZYDIS_REGISTER_NONE));
|
||||
}
|
||||
if (instruction->avx.roundingMode)
|
||||
{
|
||||
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
|
||||
bufEnd - *buffer, instruction, &instruction->operands[i],
|
||||
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, ZYDIS_REGISTER_NONE));
|
||||
} else
|
||||
{
|
||||
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
|
||||
bufEnd - *buffer, instruction, &instruction->operands[i],
|
||||
ZYDIS_DECORATOR_TYPE_SAE, ZYDIS_REGISTER_NONE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1079,7 +1137,7 @@ ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookT
|
|||
formatter->funcPrintSegment = *(ZydisFormatterFormatOperandFunc*)&temp;
|
||||
break;
|
||||
case ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR:
|
||||
formatter->funcPrintDecorator = *(ZydisFormatterFormatOperandFunc*)&temp;
|
||||
formatter->funcPrintDecorator = *(ZydisFormatterFormatDecoratorFunc*)&temp;
|
||||
break;
|
||||
case ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS:
|
||||
formatter->funcPrintAddress = *(ZydisFormatterFormatAddressFunc*)&temp;
|
||||
|
|
|
@ -217,7 +217,7 @@ typedef uint8_t ZydisInternalElementType;
|
|||
enum ZydisInternalElementTypes
|
||||
{
|
||||
ZYDIS_IELEMENT_TYPE_INVALID,
|
||||
ZYDIS_IELEMENT_TYPE_VARIABLE, // TODO: Remove
|
||||
ZYDIS_IELEMENT_TYPE_VARIABLE,
|
||||
ZYDIS_IELEMENT_TYPE_STRUCT,
|
||||
ZYDIS_IELEMENT_TYPE_INT,
|
||||
ZYDIS_IELEMENT_TYPE_UINT,
|
||||
|
@ -270,6 +270,9 @@ typedef struct ZydisOperandDefinition_
|
|||
} op;
|
||||
} ZydisOperandDefinition;
|
||||
|
||||
/**
|
||||
* @brief Values that represent implicit-register types.
|
||||
*/
|
||||
enum ZydisImplicitRegisterType
|
||||
{
|
||||
ZYDIS_IMPLREG_TYPE_STATIC,
|
||||
|
@ -281,6 +284,9 @@ enum ZydisImplicitRegisterType
|
|||
ZYDIS_IMPLREG_TYPE_FLAGS_SSZ
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Values that represent implicit-memory base-registers.
|
||||
*/
|
||||
enum ZydisImplicitMemBase
|
||||
{
|
||||
ZYDIS_IMPLMEM_BASE_ABX,
|
||||
|
@ -657,7 +663,7 @@ enum ZydisMaskPolicies
|
|||
|
||||
#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX \
|
||||
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; \
|
||||
ZydisBool hasVSIB ZYDIS_BITFIELD( 1)
|
||||
ZydisBool hasVSIB ZYDIS_BITFIELD( 1)
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisInstructionDefinition struct.
|
||||
|
|
Loading…
Reference in New Issue