mirror of https://github.com/x64dbg/zydis
Minor bugfixes and refactorings
This commit is contained in:
parent
c4dce1adb9
commit
be56ef937d
|
@ -223,7 +223,7 @@ static ZydisStatus ZydisBufferAppendImport(char* buffer, size_t bufferLen, size_
|
|||
++descriptor;
|
||||
}
|
||||
}
|
||||
return ZYDIS_STATUS_USER + 1000;
|
||||
return 1337 + 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -387,14 +387,14 @@ int main(int argc, char** argv)
|
|||
switch (info.mode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
printf("%04llX ", info.instrAddress);
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
printf("%08llX ", info.instrAddress);
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
printf("%016llX ", info.instrAddress);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < info.length; ++j)
|
||||
{
|
||||
|
@ -404,7 +404,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
printf(" ");
|
||||
}
|
||||
if (info.flags & ZYDIS_IFLAG_ERROR_MASK)
|
||||
if (info.instrFlags & ZYDIS_INSTRFLAG_ERROR_MASK)
|
||||
{
|
||||
printf(" db %02x\n", info.data[0]);
|
||||
continue;
|
||||
|
|
|
@ -48,11 +48,11 @@ typedef uint32_t ZydisDecoderFlags;
|
|||
|
||||
/**
|
||||
* @brief Set this flag if you do not want @c ZydisDecoderDecodeNextInstruction to fail with
|
||||
* @c ZYDIS_STATUS_INVALID_INSTRUCTION, if an invalid instruction was found.
|
||||
* @c ZYDIS_STATUS_DECODING_ERROR, if an invalid instruction was found.
|
||||
*
|
||||
* If this flag is set, @c ZydisDecoderDecodeNextInstruction just skips one byte and
|
||||
* returns @c ZYDIS_STATUS_SUCCESS. The returned @c ZydisInstructionInfo struct will
|
||||
* have one of the @c ZYDIS_IFLAG_ERROR_MASK flags set.
|
||||
* have one of the @c ZYDIS_INSTRFLAG_ERROR_MASK flags set.
|
||||
*/
|
||||
#define ZYDIS_DECODER_FLAG_SKIP_DATA 0x00000001
|
||||
/**
|
||||
|
|
|
@ -38,15 +38,11 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Instruction formatter */
|
||||
/* Enums and types */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Enums and types */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis formatter-style datatype.
|
||||
* @brief Defines the @c ZydisFormatterStyle datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterStyle;
|
||||
|
||||
|
@ -62,7 +58,7 @@ enum ZydisFormatterStyles
|
|||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis formatter-flags datatype.
|
||||
* @brief Defines the @c ZydisFormatterFlags datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterFlags;
|
||||
|
||||
|
@ -73,7 +69,7 @@ typedef uint8_t ZydisFormatterFlags;
|
|||
#define ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT 0x10
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis address-format datatype.
|
||||
* @brief Defines the @c ZydisFormatterAddressFormat datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterAddressFormat;
|
||||
|
||||
|
@ -82,10 +78,11 @@ typedef uint8_t ZydisFormatterAddressFormat;
|
|||
*/
|
||||
enum ZydisFormatterAddressFormat
|
||||
{
|
||||
ZYDIS_FORMATTER_ADDR_DEFAULT,
|
||||
/**
|
||||
* @brief Displays absolute addresses instead of relative ones.
|
||||
*/
|
||||
ZYDIS_FORMATTER_ADDRESS_ABSOLUTE,
|
||||
ZYDIS_FORMATTER_ADDR_ABSOLUTE,
|
||||
/**
|
||||
* @brief Uses signed hexadecimal values to display relative addresses.
|
||||
*
|
||||
|
@ -93,7 +90,7 @@ enum ZydisFormatterAddressFormat
|
|||
* "JMP 0x20"
|
||||
* "JMP -0x20"
|
||||
*/
|
||||
ZYDIS_FORMATTER_ADDRESS_RELATIVE_SIGNED,
|
||||
ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED,
|
||||
/**
|
||||
* @brief Uses unsigned hexadecimal values to display relative addresses.
|
||||
*
|
||||
|
@ -101,11 +98,11 @@ enum ZydisFormatterAddressFormat
|
|||
* "JMP 0x20"
|
||||
* "JMP 0xE0"
|
||||
*/
|
||||
ZYDIS_FORMATTER_ADDRESS_RELATIVE_UNSIGNED,
|
||||
ZYDIS_FORMATTER_ADDR_RELATIVE_UNSIGNED,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis displacement-format datatype.
|
||||
* @brief Defines the @c ZydisFormatterDisplacementFormat datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterDisplacementFormat;
|
||||
|
||||
|
@ -114,6 +111,7 @@ typedef uint8_t ZydisFormatterDisplacementFormat;
|
|||
*/
|
||||
enum ZydisFormatterDisplacementFormats
|
||||
{
|
||||
ZYDIS_FORMATTER_DISP_DEFAULT,
|
||||
/**
|
||||
* @brief Formats displacements as signed hexadecimal values.
|
||||
*
|
||||
|
@ -133,7 +131,7 @@ enum ZydisFormatterDisplacementFormats
|
|||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis formatter immediate-format datatype.
|
||||
* @brief Defines the @c ZydisFormatterImmediateFormat datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterImmediateFormat;
|
||||
|
||||
|
@ -142,6 +140,7 @@ typedef uint8_t ZydisFormatterImmediateFormat;
|
|||
*/
|
||||
enum ZydisFormatterImmediateFormats
|
||||
{
|
||||
ZYDIS_FORMATTER_IMM_DEFAULT,
|
||||
/**
|
||||
* @brief Formats immediates as signed hexadecimal values.
|
||||
*
|
||||
|
@ -161,7 +160,38 @@ enum ZydisFormatterImmediateFormats
|
|||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis instruction-formatter struct.
|
||||
* @brief Defines the @c ZydisFormatterHookType datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterHookType;
|
||||
|
||||
/**
|
||||
* @brief Values that represent formatter hook-types.
|
||||
*/
|
||||
enum ZydisFormatterHookTypes
|
||||
{
|
||||
/**
|
||||
* @brief This hook is called right
|
||||
*/
|
||||
ZYDIS_FORMATTER_HOOK_PRE,
|
||||
ZYDIS_FORMATTER_HOOK_POST,
|
||||
ZYDIS_FORMATTER_HOOK_FORMAT_MNEMONIC,
|
||||
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND,
|
||||
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG,
|
||||
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM,
|
||||
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM,
|
||||
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR,
|
||||
ZYDIS_FORMATTER_HOOK_FORMAT_ADDRESS_ABS,
|
||||
ZYDIS_FORMATTER_HOOK_FORMAT_ADDRESS_REL,
|
||||
ZYDIS_FORMATTER_HOOK_FORMAT_DISPLACEMENT,
|
||||
ZYDIS_FORMATTER_HOOK_FORMAT_IMMEDIATE
|
||||
};
|
||||
|
||||
typedef const char* (*ZydisFormatterHookFormatMnemonicFunc)(void* context,
|
||||
const ZydisInstructionInfo* info, const ZydisOperandInfo* operand, uint64_t address,
|
||||
int64_t* offset);
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisInstructionFormatter struct.
|
||||
*/
|
||||
typedef struct ZydisInstructionFormatter_
|
||||
{
|
||||
|
@ -174,8 +204,12 @@ typedef struct ZydisInstructionFormatter_
|
|||
|
||||
} ZydisInstructionFormatter;
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* ============================================================================================== */
|
||||
/* Exported functions */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Basic functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
|
@ -224,6 +258,9 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterGetSymbolResolver(
|
|||
ZYDIS_EXPORT ZydisStatus ZydisFormatterSetSymbolResolver(
|
||||
ZydisInstructionFormatter* formatter, ZydisCustomSymbolResolver* symbolResolver);
|
||||
|
||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* formatter,
|
||||
ZydisFormatterHookType hook, const void* callback);
|
||||
|
||||
/**
|
||||
* @brief Formats the given instruction and writes it into the output buffer.
|
||||
*
|
||||
|
@ -238,6 +275,18 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(
|
|||
ZydisInstructionFormatter* formatter, const ZydisInstructionInfo* info, char* buffer,
|
||||
size_t bufferLen);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Formatting functions for custom implementations */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatOperandIntel(
|
||||
const ZydisInstructionFormatter* formatter, char* buffer, size_t bufferLen, size_t* offset,
|
||||
const ZydisInstructionInfo* info, const ZydisOperandInfo* operand, uint16_t typecast);
|
||||
|
||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatOperandMemIntel(
|
||||
const ZydisInstructionFormatter* formatter, char* buffer, size_t bufferLen, size_t* offset,
|
||||
const ZydisInstructionInfo* info, const ZydisOperandInfo* operand, uint16_t typecast);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
|
|
@ -69,221 +69,221 @@ enum ZydisDisassemblerModes
|
|||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines an alias representing instruction flags.
|
||||
* @brief Defines the @c ZydisInstructionFlags datatype.
|
||||
*/
|
||||
typedef uint32_t ZydisInstructionFlags;
|
||||
|
||||
/**
|
||||
* @brief The instruction has the modrm byte.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_HAS_MODRM 0x00000001
|
||||
#define ZYDIS_INSTRFLAG_HAS_MODRM 0x00000001
|
||||
/**
|
||||
* @brief The instruction has the sib byte.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_HAS_SIB 0x00000002
|
||||
#define ZYDIS_INSTRFLAG_HAS_SIB 0x00000002
|
||||
/**
|
||||
* @brief The instruction has one or more operands with position-relative offsets.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_RELATIVE 0x00000004
|
||||
#define ZYDIS_INSTRFLAG_IS_RELATIVE 0x00000004
|
||||
/**
|
||||
* @brief The instruction is privileged and may only be executed in kernel-mode (ring0).
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_PRIVILEGED 0x00000008
|
||||
#define ZYDIS_INSTRFLAG_IS_PRIVILEGED 0x00000008
|
||||
/**
|
||||
* @brief An error occured while decoding the current instruction.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_ERROR_MASK 0x7F000000
|
||||
#define ZYDIS_INSTRFLAG_ERROR_MASK 0x7F000000
|
||||
/**
|
||||
* @brief The instruction is invalid.
|
||||
* @brief The instruction is undefined.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_ERROR_INVALID 0x01000000
|
||||
#define ZYDIS_INSTRFLAG_ERROR_UNDEFINED 0x01000000
|
||||
/**
|
||||
* @brief The instruction length has exceeded the maximum of 15 bytes.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_ERROR_INSTRUCTION_LENGTH 0x02000000
|
||||
#define ZYDIS_INSTRFLAG_ERROR_MAXLENGTH 0x02000000
|
||||
/**
|
||||
* @brief An error occured while decoding the vex-prefix.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_ERROR_MALFORMED_VEX 0x04000000
|
||||
#define ZYDIS_INSTRFLAG_ERROR_MALFORMED_VEX 0x04000000
|
||||
/**
|
||||
* @brief An error occured while decoding the evex-prefix.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_ERROR_MALFORMED_EVEX 0x08000000
|
||||
#define ZYDIS_INSTRFLAG_ERROR_MALFORMED_EVEX 0x08000000
|
||||
/**
|
||||
* @brief An error occured while decoding the xop-prefix.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_ERROR_MALFORMED_XOP 0x10000000
|
||||
#define ZYDIS_INSTRFLAG_ERROR_MALFORMED_XOP 0x10000000
|
||||
/**
|
||||
* @brief A rex-prefix was found while decoding a vex/evex/xop instruction.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX 0x20000000
|
||||
#define ZYDIS_INSTRFLAG_ERROR_ILLEGAL_REX 0x20000000
|
||||
/**
|
||||
* @brief An invalid constellation was found while decoding an instruction that uses the VSIB
|
||||
* addressing mode.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB 0x40000000
|
||||
#define ZYDIS_INSTRFLAG_ERROR_INVALID_VSIB 0x40000000
|
||||
/**
|
||||
* @brief An error occured while decoding the instruction-operands.
|
||||
*/
|
||||
#define ZYDIS_INSTRUCTION_ERROR_OPERANDS 0x40000000
|
||||
#define ZYDIS_INSTRFLAG_ERROR_OPERANDS 0x40000000
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Prefix flags */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis prefix-flags datatype.
|
||||
* @brief Defines the @c ZydisPrefixFlags datatype.
|
||||
*/
|
||||
typedef uint32_t ZydisPrefixFlags;
|
||||
|
||||
/**
|
||||
* @brief The instruction has the rex-prefix (0x40 - 0x4F).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REX 0x00000001
|
||||
#define ZYDIS_PREFIXFLAG_HAS_REX 0x00000001
|
||||
/**
|
||||
* @brief The instruction has the xop-prefix (0x8F).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_XOP 0x00000002
|
||||
#define ZYDIS_PREFIXFLAG_HAS_XOP 0x00000002
|
||||
/**
|
||||
* @brief The instruction has the vex-prefix (0xC4 or 0xC5).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_VEX 0x00000004
|
||||
#define ZYDIS_PREFIXFLAG_HAS_VEX 0x00000004
|
||||
/**
|
||||
* @brief The instruction has the evex-prefix (0x62).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_EVEX 0x00000008
|
||||
#define ZYDIS_PREFIXFLAG_HAS_EVEX 0x00000008
|
||||
/**
|
||||
* @brief The instruction has the lock-prefix (0x0F)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_LOCK 0x00000010
|
||||
#define ZYDIS_PREFIXFLAG_HAS_LOCK 0x00000010
|
||||
/**
|
||||
* @brief The instruction has the rep/repe/repz-prefix (0xF3)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REP 0x00000020
|
||||
#define ZYDIS_PREFIXFLAG_HAS_REP 0x00000020
|
||||
/**
|
||||
* @brief The instruction has the rep/repe/repz-prefix (0xF3)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REPE 0x00000020
|
||||
#define ZYDIS_PREFIXFLAG_HAS_REPE 0x00000020
|
||||
/**
|
||||
* @brief The instruction has the rep/repe/repz-prefix (0xF3)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REPZ 0x00000020
|
||||
#define ZYDIS_PREFIXFLAGG_HAS_REPZ 0x00000020
|
||||
/**
|
||||
* @brief The instruction has the repne/repnz-prefix (0xF2)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REPNE 0x00000040
|
||||
#define ZYDIS_PREFIXFLAG_HAS_REPNE 0x00000040
|
||||
/**
|
||||
* @brief The instruction has the repne/repnz-prefix (0xF2)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REPNZ 0x00000040
|
||||
#define ZYDIS_PREFIXFLAG_HAS_REPNZ 0x00000040
|
||||
/**
|
||||
* @brief The instruction has a segment-override prefix.
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_MASK 0x00001F80
|
||||
#define ZYDIS_PREFIXFLAG_SEGMENT_MASK 0x00001F80
|
||||
/**
|
||||
* @brief The instruction has the cs segment-override prefix (0x2E).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_CS 0x00000080
|
||||
#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS 0x00000080
|
||||
/**
|
||||
* @brief The instruction has the ss segment-override prefix (0x36).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_SS 0x00000100
|
||||
#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_SS 0x00000100
|
||||
/**
|
||||
* @brief The instruction has the ds segment-override prefix (0x3E).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_DS 0x00000200
|
||||
#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS 0x00000200
|
||||
/**
|
||||
* @brief The instruction has the es segment-override prefix (0x26).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_ES 0x00000400
|
||||
#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_ES 0x00000400
|
||||
/**
|
||||
* @brief The instruction has the fs segment-override prefix (0x64).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_FS 0x00000800
|
||||
#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_FS 0x00000800
|
||||
/**
|
||||
* @brief The instruction has the gs segment-override prefix (0x65).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_GS 0x00001000
|
||||
#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_GS 0x00001000
|
||||
/**
|
||||
* @brief The instruction has the operand-size-override prefix (0x66).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_OPERANDSIZE 0x00002000
|
||||
#define ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE 0x00002000
|
||||
/**
|
||||
* @brief The instruction has the address-size-override prefix (0x67).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ADDRESSSIZE 0x00004000
|
||||
#define ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE 0x00004000
|
||||
/**
|
||||
* @brief The instruction has the xacquire prefix (0xF2).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_XACQUIRE 0x00008000
|
||||
#define ZYDIS_PREFIXFLAG_HAS_XACQUIRE 0x00008000
|
||||
/**
|
||||
* @brief The instruction has the xrelease prefix (0xF3).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_XRELEASE 0x00010000
|
||||
#define ZYDIS_PREFIXFLAG_HAS_XRELEASE 0x00010000
|
||||
/**
|
||||
* @brief The instruction has the branch-not-taken hint (0x2E).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_BRANCH_NOT_TAKEN 0x00020000
|
||||
#define ZYDIS_PREFIXFLAG_HAS_BRANCH_NOT_TAKEN 0x00020000
|
||||
/**
|
||||
* @brief The instruction has the branch-taken hint (0x3E).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_BRANCH_TAKEN 0x00040000
|
||||
#define ZYDIS_PREFIXFLAG_HAS_BRANCH_TAKEN 0x00040000
|
||||
/**
|
||||
* @brief The instruction accepts the operand-size override prefix (0x66)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_OPERANDSIZE 0x00080000
|
||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_OPERANDSIZE 0x00080000
|
||||
/**
|
||||
* @brief The instruction accepts the adress-size override prefix (0x67)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE 0x00100000
|
||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_ADDRESSSIZE 0x00100000
|
||||
/**
|
||||
* @brief The instruction accepts the lock-prefix.
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_LOCK 0x00200000
|
||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_LOCK 0x00200000
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REP 0x00400000
|
||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_REP 0x00400000
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPE 0x00400000
|
||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPE 0x00400000
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPZ 0x00400000
|
||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPZ 0x00400000
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPNE 0x00400000
|
||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPNE 0x00400000
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPNZ 0x00400000
|
||||
#define ZYDIS_PREFIXFLAG_ACCEPTS_REPNZ 0x00400000
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the first prefix-group (0x0F, 0xF3, 0xF2).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP1 0x00800000
|
||||
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP1 0x00800000
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the second prefix-group (0x2E, 0x36,
|
||||
* 0x3E, 0x26, 0x64, 0x65).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP2 0x01000000
|
||||
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP2 0x01000000
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the third prefix-group (0x66).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP3 0x02000000
|
||||
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP3 0x02000000
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the fourth prefix-group (0x67).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP4 0x04000000
|
||||
#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP4 0x04000000
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Instruction encoding */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis instruction-encoding datatype.
|
||||
* @brief Defines the @c ZydisInstructionEncoding datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisInstructionEncoding;
|
||||
|
||||
|
@ -304,12 +304,12 @@ enum ZydisInstructionEncodings
|
|||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines an alias representing an opcode map.
|
||||
* @brief Defines the @c ZydisOpcodeMap map.
|
||||
*/
|
||||
typedef uint8_t ZydisOpcodeMap;
|
||||
|
||||
/**
|
||||
* @brief Values that represent opcode maps.
|
||||
* @brief Values that represent opcode-maps.
|
||||
*/
|
||||
enum ZydisOpcodeMaps
|
||||
{
|
||||
|
@ -327,7 +327,7 @@ enum ZydisOpcodeMaps
|
|||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines an alias representing an operand-type.
|
||||
* @brief Defines the @c ZydisOperandType datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisOperandType;
|
||||
|
||||
|
@ -363,7 +363,7 @@ enum ZydisOperandTypes
|
|||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines an alias representing an operand-encoding.
|
||||
* @brief Defines the @c ZydisOperandEncoding datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisOperandEncoding;
|
||||
|
||||
|
@ -657,11 +657,11 @@ typedef struct ZydisInstructionInfo_
|
|||
/**
|
||||
* @brief Instruction specific info- and error-flags.
|
||||
*/
|
||||
ZydisInstructionFlags flags;
|
||||
ZydisInstructionFlags instrFlags;
|
||||
/**
|
||||
* @brief Prefix flags.
|
||||
*/
|
||||
ZydisPrefixFlags prefixes;
|
||||
ZydisPrefixFlags prefixFlags;
|
||||
/**
|
||||
* @brief The instruction-mnemonic.
|
||||
*/
|
||||
|
|
|
@ -190,8 +190,6 @@ enum ZydisRegisterSizes
|
|||
ZYDIS_REGISTERSIZE_512 = 512
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Macros */
|
||||
/* ============================================================================================== */
|
||||
|
@ -201,7 +199,7 @@ enum ZydisRegisterSizes
|
|||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_GPR (reg) \
|
||||
#define ZYDIS_REGISTER_IS_GPR(reg) \
|
||||
((ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8) ||) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16) || \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32))
|
||||
|
@ -211,7 +209,7 @@ enum ZydisRegisterSizes
|
|||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_GPR8 (reg) \
|
||||
#define ZYDIS_REGISTER_IS_GPR8(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8)
|
||||
|
||||
/**
|
||||
|
@ -219,7 +217,7 @@ enum ZydisRegisterSizes
|
|||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_GPR16 (reg) \
|
||||
#define ZYDIS_REGISTER_IS_GPR16(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16)
|
||||
|
||||
/**
|
||||
|
@ -227,10 +225,130 @@ enum ZydisRegisterSizes
|
|||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_GPR32 (reg) \
|
||||
#define ZYDIS_REGISTER_IS_GPR32(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32)
|
||||
|
||||
// TODO: Add macros for all register-classes
|
||||
/**
|
||||
* @brief Checks, if the given register is a legacy floating-point register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_FLOATING_POINT(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_FLOATING_POINT)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a multimedia floating-point register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_MLUTIMEDIA(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_MULTIMEDIA)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_VECTOR(reg) \
|
||||
((ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR128) ||) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR256) || \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR512))
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a 128-bit vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_VECTOR128(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR128)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a 256-bit vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_VECTOR256(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR256)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a 512-bit vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_VECTOR512(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR512)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a flags register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_FLAGS(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_FLAGS)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is an instruction-pointer register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_IP(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_IP)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a segment register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_SEGMENT(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_SEGMENT)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a table register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_TABLE(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_TABLE)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a test register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_TEST(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_TEST)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a control register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_CONTROL(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_CONTROL)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a debug register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_DEBUG(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_DEBUG)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a mask register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_MASK(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_MASK)
|
||||
|
||||
/**
|
||||
* @brief Checks, if the given register is a bounds register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
#define ZYDIS_REGISTER_IS_BOUNDS(reg) \
|
||||
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_BOUNDS)
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Exported functions */
|
||||
|
|
|
@ -65,10 +65,10 @@ enum ZydisStatusCode
|
|||
*/
|
||||
ZYDIS_STATUS_NO_MORE_DATA = 0x00000003,
|
||||
/**
|
||||
* @brief An error occured while decoding the current instruction. Check the @c flags field
|
||||
* of the @c ZydisInstructionInfo struct for further details.
|
||||
* @brief An error occured while decoding the current instruction. Check the @c instrFlags
|
||||
* field of the @c ZydisInstructionInfo struct for further details.
|
||||
*/
|
||||
ZYDIS_STATUS_INVALID_INSTRUCTION = 0x00000004, // TODO: Rename
|
||||
ZYDIS_STATUS_DECODING_ERROR = 0x00000004,
|
||||
/**
|
||||
* @brief A buffer passed to a function was too small to complete the requested operation.
|
||||
*/
|
||||
|
|
213
src/Decoder.c
213
src/Decoder.c
|
@ -69,11 +69,11 @@ typedef enum ZydisDecoderStatusCode_
|
|||
{
|
||||
ZYDIS_STATUS_DECODER_SUCCESS,
|
||||
ZYDIS_STATUS_DECODER_NO_MORE_DATA,
|
||||
ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION,
|
||||
ZYDIS_STATUS_DECODER_UNDEFINED_INSTRUCTION,
|
||||
ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION_LENGTH,
|
||||
ZYDIS_STATUS_DECODER_MALFORMED_VEX_PREFIX,
|
||||
ZYDIS_STATUS_DECODER_MALFORMED_EVEX_PREFIX,
|
||||
ZYDIS_STATUS_DECODER_MALFORMED_XOP_PREFIX,
|
||||
ZYDIS_STATUS_DECODER_MALFORMED_VEX,
|
||||
ZYDIS_STATUS_DECODER_MALFORMED_EVEX,
|
||||
ZYDIS_STATUS_DECODER_MALFORMED_XOP,
|
||||
ZYDIS_STATUS_DECODER_ILLEGAL_REX,
|
||||
ZYDIS_STATUS_DECODER_INVALID_VSIB
|
||||
} ZydisDecoderStatusCode;
|
||||
|
@ -110,7 +110,7 @@ static ZydisDecoderStatus ZydisInputPeek(ZydisInstructionDecoder* decoder,
|
|||
|
||||
if (info->length >= ZYDIS_MAX_INSTRUCTION_LENGTH)
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_INSTRUCTION_LENGTH;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_MAXLENGTH;
|
||||
return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION_LENGTH;
|
||||
}
|
||||
|
||||
|
@ -388,7 +388,7 @@ static void ZydisDecodeModrm(uint8_t modrmByte, ZydisInstructionInfo* info)
|
|||
{
|
||||
ZYDIS_ASSERT(info);
|
||||
|
||||
info->flags |= ZYDIS_INSTRUCTION_HAS_MODRM;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_HAS_MODRM;
|
||||
info->details.modrm.isDecoded = true;
|
||||
info->details.modrm.data[0] = modrmByte;
|
||||
info->details.modrm.mod = (modrmByte >> 6) & 0x03;
|
||||
|
@ -408,7 +408,7 @@ static void ZydisDecodeSib(uint8_t sibByte, ZydisInstructionInfo* info)
|
|||
ZYDIS_ASSERT(info->details.modrm.isDecoded);
|
||||
ZYDIS_ASSERT((info->details.modrm.rm & 0x7) == 4);
|
||||
|
||||
info->flags |= ZYDIS_INSTRUCTION_HAS_SIB;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_HAS_SIB;
|
||||
info->details.sib.isDecoded = true;
|
||||
info->details.sib.data[0] = sibByte;
|
||||
info->details.sib.scale = (sibByte >> 6) & 0x03;
|
||||
|
@ -444,58 +444,58 @@ static ZydisDecoderStatus ZydisCollectOptionalPrefixes(ZydisInstructionDecoder*
|
|||
switch (prefixByte)
|
||||
{
|
||||
case 0xF0:
|
||||
info->prefixes |= ZYDIS_PREFIX_LOCK;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_LOCK;
|
||||
++groups[0];
|
||||
break;
|
||||
case 0xF2:
|
||||
// 0xF2 and 0xF3 are mutally exclusive. The one that comes later has precedence.
|
||||
info->prefixes |= ZYDIS_PREFIX_REPNE;
|
||||
info->prefixes &= ~ZYDIS_PREFIX_REP;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_REPNE;
|
||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REP;
|
||||
++groups[0];
|
||||
break;
|
||||
case 0xF3:
|
||||
// 0xF2 and 0xF3 are mutally exclusive. The one that comes later has precedence.
|
||||
info->prefixes |= ZYDIS_PREFIX_REP;
|
||||
info->prefixes &= ~ZYDIS_PREFIX_REPNE;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_REP;
|
||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REPNE;
|
||||
++groups[0];
|
||||
break;
|
||||
case 0x2E:
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_CS;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x36:
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_SS;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_SS;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x3E:
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_DS;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x26:
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_ES;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_ES;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x64:
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_FS;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_FS;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x65:
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_GS;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_GS;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x66:
|
||||
info->prefixes |= ZYDIS_PREFIX_OPERANDSIZE;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE;
|
||||
++groups[2];
|
||||
break;
|
||||
case 0x67:
|
||||
info->prefixes |= ZYDIS_PREFIX_ADDRESSSIZE;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE;
|
||||
++groups[3];
|
||||
break;
|
||||
default:
|
||||
if ((decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT) &&
|
||||
(prefixByte & 0xF0) == 0x40)
|
||||
{
|
||||
info->prefixes |= ZYDIS_PREFIX_REX;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_REX;
|
||||
info->details.rex.data[0] = prefixByte;
|
||||
} else
|
||||
{
|
||||
|
@ -509,26 +509,26 @@ static ZydisDecoderStatus ZydisCollectOptionalPrefixes(ZydisInstructionDecoder*
|
|||
}
|
||||
} while (!done);
|
||||
|
||||
if (info->prefixes & ZYDIS_PREFIX_REX)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REX)
|
||||
{
|
||||
ZydisDecodeRexPrefix(info, info->details.rex.data[0]);
|
||||
}
|
||||
|
||||
if (groups[0] > 1)
|
||||
{
|
||||
info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP1;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_MULTIPLE_GRP1;
|
||||
}
|
||||
if (groups[1] > 1)
|
||||
{
|
||||
info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP2;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_MULTIPLE_GRP2;
|
||||
}
|
||||
if (groups[2] > 1)
|
||||
{
|
||||
info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP3;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_MULTIPLE_GRP3;
|
||||
}
|
||||
if (groups[3] > 1)
|
||||
{
|
||||
info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP4;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_MULTIPLE_GRP4;
|
||||
}
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
|
@ -661,7 +661,7 @@ static ZydisDecoderStatus ZydisDecodeOperandRegister(ZydisInstructionInfo* info,
|
|||
operand->type = ZYDIS_OPERAND_TYPE_REGISTER;
|
||||
if (registerClass == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8)
|
||||
{
|
||||
if ((info->prefixes & ZYDIS_PREFIX_REX) && (registerId >= 4))
|
||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REX) && (registerId >= 4))
|
||||
{
|
||||
operand->reg = ZYDIS_REGISTER_SPL + (registerId - 4);
|
||||
} else
|
||||
|
@ -707,17 +707,17 @@ static ZydisDecoderStatus ZydisDecodeOperandModrmRm(ZydisInstructionDecoder* dec
|
|||
}
|
||||
operand->type = ZYDIS_OPERAND_TYPE_MEMORY;
|
||||
uint8_t displacementSize = 0;
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_ADDRESSSIZE;
|
||||
switch (decoder->disassemblerMode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 16;
|
||||
operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 32 : 16;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 16 : 32;
|
||||
operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 16 : 32;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 64;
|
||||
operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 32 : 64;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
|
@ -762,7 +762,7 @@ static ZydisDecoderStatus ZydisDecodeOperandModrmRm(ZydisInstructionDecoder* dec
|
|||
{
|
||||
if (decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT)
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE;
|
||||
operand->mem.base = ZYDIS_REGISTER_EIP;
|
||||
} else
|
||||
{
|
||||
|
@ -821,7 +821,7 @@ static ZydisDecoderStatus ZydisDecodeOperandModrmRm(ZydisInstructionDecoder* dec
|
|||
case 0:
|
||||
if (modrm_rm == 5)
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE;
|
||||
operand->mem.base = ZYDIS_REGISTER_RIP;
|
||||
displacementSize = 32;
|
||||
}
|
||||
|
@ -1000,7 +1000,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
registerClass = ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64;
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_TR:
|
||||
operand->size = 32; // TODO: ?
|
||||
operand->size = 32;
|
||||
registerClass = ZYDIS_REGISTERCLASS_TEST;
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_CR:
|
||||
|
@ -1271,13 +1271,13 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
{
|
||||
if (info->details.modrm.rm != 0x04)
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_INVALID_VSIB;
|
||||
return ZYDIS_STATUS_DECODER_INVALID_VSIB;
|
||||
}
|
||||
switch (operand->mem.addressSize)
|
||||
{
|
||||
case 16:
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_INVALID_VSIB;
|
||||
return ZYDIS_STATUS_DECODER_INVALID_VSIB;
|
||||
case 32:
|
||||
operand->mem.index = operand->mem.index - ZYDIS_REGISTER_EAX + vsibBaseRegister;
|
||||
|
@ -1301,7 +1301,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
operand->imm.value.ubyte = 1;
|
||||
return ZYDIS_STATUS_DECODER_SUCCESS;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_REL8:
|
||||
info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE;
|
||||
operand->imm.isRelative = true;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_IMM8:
|
||||
operand->size = 8;
|
||||
|
@ -1312,21 +1312,21 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
operand->imm.isSigned = false;
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_REL16:
|
||||
info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE;
|
||||
operand->imm.isRelative = true;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_IMM16:
|
||||
operand->size = 16;
|
||||
operand->imm.isSigned = true;
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_REL32:
|
||||
info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE;
|
||||
operand->imm.isRelative = true;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_IMM32:
|
||||
operand->size = 32;
|
||||
operand->imm.isSigned = true;
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_REL64:
|
||||
info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE;
|
||||
operand->imm.isRelative = true;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_IMM64:
|
||||
operand->size = 64;
|
||||
|
@ -1469,17 +1469,17 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
}
|
||||
if (srcidx || dstidx)
|
||||
{
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_ADDRESSSIZE;
|
||||
switch (decoder->disassemblerMode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 16;
|
||||
operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 32 : 16;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 16 : 32;
|
||||
operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 16 : 32;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 64;
|
||||
operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 32 : 64;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
|
@ -1556,33 +1556,33 @@ static ZydisDecoderStatus ZydisDecodeOperands(ZydisInstructionDecoder* decoder,
|
|||
info->operand[i].access = definition->operands[i].access;
|
||||
if (status != ZYDIS_STATUS_DECODER_SUCCESS)
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_OPERANDS;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_OPERANDS;
|
||||
return status;
|
||||
}
|
||||
// Adjust segment register for memory operands
|
||||
if (info->operand[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_CS)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_CS;
|
||||
} else
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_SS)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_SS)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_SS;
|
||||
} else
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_DS)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_DS;
|
||||
} else
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_ES)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_ES)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_ES;
|
||||
} else
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_FS)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_FS)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_FS;
|
||||
} else
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_GS)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_GS)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_GS;
|
||||
} else
|
||||
|
@ -1637,17 +1637,14 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info)
|
|||
case ZYDIS_MNEMONIC_XCHG:
|
||||
if (info->operand[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_LOCK;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_LOCK;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_MOVSB:
|
||||
case ZYDIS_MNEMONIC_MOVSW:
|
||||
case ZYDIS_MNEMONIC_MOVSD:
|
||||
case ZYDIS_MNEMONIC_MOVSQ:
|
||||
case ZYDIS_MNEMONIC_CMPSB:
|
||||
case ZYDIS_MNEMONIC_CMPSW:
|
||||
case ZYDIS_MNEMONIC_CMPSD:
|
||||
case ZYDIS_MNEMONIC_CMPSQ:
|
||||
case ZYDIS_MNEMONIC_CMPS: // TODO: Only the string-instruction! We will use flags later.
|
||||
case ZYDIS_MNEMONIC_SCASB:
|
||||
case ZYDIS_MNEMONIC_SCASW:
|
||||
case ZYDIS_MNEMONIC_SCASD:
|
||||
|
@ -1666,7 +1663,7 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info)
|
|||
case ZYDIS_MNEMONIC_OUTSB:
|
||||
case ZYDIS_MNEMONIC_OUTSW:
|
||||
case ZYDIS_MNEMONIC_OUTSD:
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_REP | ZYDIS_PREFIX_ACCEPTS_REPNE;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_REP | ZYDIS_PREFIXFLAG_ACCEPTS_REPNE;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_JO:
|
||||
case ZYDIS_MNEMONIC_JNO:
|
||||
|
@ -1687,44 +1684,46 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info)
|
|||
case ZYDIS_MNEMONIC_JCXZ:
|
||||
case ZYDIS_MNEMONIC_JECXZ:
|
||||
case ZYDIS_MNEMONIC_JRCXZ:
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_CS)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS)
|
||||
{
|
||||
info->prefixes &= ~ZYDIS_PREFIX_SEGMENT_CS;
|
||||
info->prefixes |= ZYDIS_PREFIX_BRANCH_NOT_TAKEN;
|
||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_BRANCH_NOT_TAKEN;
|
||||
} else
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_DS)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS)
|
||||
{
|
||||
info->prefixes &= ~ZYDIS_PREFIX_SEGMENT_DS;
|
||||
info->prefixes |= ZYDIS_PREFIX_BRANCH_TAKEN;
|
||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_BRANCH_TAKEN;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_LOCK) &&
|
||||
((info->prefixes & ZYDIS_PREFIX_REP) || (info->prefixes & ZYDIS_PREFIX_REPNE)))
|
||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_LOCK) &&
|
||||
((info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP) ||
|
||||
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE)))
|
||||
{
|
||||
if (info->mnemonic != ZYDIS_MNEMONIC_CMPXCHG16B)
|
||||
{
|
||||
if ((info->prefixes & ZYDIS_PREFIX_LOCK) || (info->mnemonic == ZYDIS_MNEMONIC_XCHG))
|
||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_LOCK) ||
|
||||
(info->mnemonic == ZYDIS_MNEMONIC_XCHG))
|
||||
{
|
||||
if (info->prefixes & ZYDIS_PREFIX_REPNE)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE)
|
||||
{
|
||||
info->prefixes &= ~ZYDIS_PREFIX_REPNE;
|
||||
info->prefixes |= ZYDIS_PREFIX_XACQUIRE;
|
||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REPNE;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XACQUIRE;
|
||||
}
|
||||
{
|
||||
info->prefixes &= ~ZYDIS_PREFIX_REP;
|
||||
info->prefixes |= ZYDIS_PREFIX_XRELEASE;
|
||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REP;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XRELEASE;
|
||||
}
|
||||
} else
|
||||
if ((info->mnemonic == ZYDIS_MNEMONIC_MOV) && ((info->opcode == 0x88) ||
|
||||
(info->opcode == 0x89) || (info->opcode == 0xC6) || (info->opcode == 0xC7)))
|
||||
{
|
||||
if (info->prefixes & ZYDIS_PREFIX_REP)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP)
|
||||
{
|
||||
info->prefixes &= ~ZYDIS_PREFIX_REP;
|
||||
info->prefixes |= ZYDIS_PREFIX_XRELEASE;
|
||||
info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REP;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XRELEASE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1778,9 +1777,9 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
|
|||
if ((decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT) ||
|
||||
((nextInput & 0xF0) >= 0xC0))
|
||||
{
|
||||
if (info->prefixes & ZYDIS_PREFIX_REX)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REX)
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_ILLEGAL_REX;
|
||||
return ZYDIS_STATUS_DECODER_ILLEGAL_REX;
|
||||
}
|
||||
uint8_t prefixBytes[3];
|
||||
|
@ -1813,24 +1812,24 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
|
|||
case 0xC5:
|
||||
// Decode vex-prefix
|
||||
info->encoding = ZYDIS_INSTRUCTION_ENCODING_VEX;
|
||||
info->prefixes |= ZYDIS_PREFIX_VEX;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_VEX;
|
||||
if (!ZydisDecodeVexPrefix(info->opcode, prefixBytes[0], prefixBytes[1],
|
||||
info))
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_MALFORMED_VEX;
|
||||
return ZYDIS_STATUS_DECODER_MALFORMED_VEX_PREFIX;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_MALFORMED_VEX;
|
||||
return ZYDIS_STATUS_DECODER_MALFORMED_VEX;
|
||||
}
|
||||
info->opcodeMap = info->details.vex.m_mmmm;
|
||||
break;
|
||||
case 0x62:
|
||||
// Decode evex-prefix
|
||||
info->encoding = ZYDIS_INSTRUCTION_ENCODING_EVEX;
|
||||
info->prefixes |= ZYDIS_PREFIX_EVEX;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_EVEX;
|
||||
if (!ZydisDecodeEvexPrefix(prefixBytes[0], prefixBytes[1], prefixBytes[2],
|
||||
info))
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_MALFORMED_EVEX;
|
||||
return ZYDIS_STATUS_DECODER_MALFORMED_EVEX_PREFIX;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_MALFORMED_EVEX;
|
||||
return ZYDIS_STATUS_DECODER_MALFORMED_EVEX;
|
||||
}
|
||||
info->opcodeMap = info->details.evex.mm;
|
||||
break;
|
||||
|
@ -1846,9 +1845,9 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
|
|||
ZYDIS_CHECK(ZydisInputPeek(decoder, info, &nextInput));
|
||||
if (((nextInput >> 0) & 0x1F) >= 8)
|
||||
{
|
||||
if (info->prefixes & ZYDIS_PREFIX_REX)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REX)
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_ILLEGAL_REX;
|
||||
return ZYDIS_STATUS_DECODER_ILLEGAL_REX;
|
||||
}
|
||||
uint8_t prefixBytes[2];
|
||||
|
@ -1858,11 +1857,11 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
|
|||
ZYDIS_CHECK(ZydisInputNext(decoder, info, &prefixBytes[1]));
|
||||
// Decode xop-prefix
|
||||
info->encoding = ZYDIS_INSTRUCTION_ENCODING_XOP;
|
||||
info->prefixes |= ZYDIS_PREFIX_XOP;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XOP;
|
||||
if (!ZydisDecodeXopPrefix(prefixBytes[0], prefixBytes[1], info))
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_MALFORMED_XOP;
|
||||
return ZYDIS_STATUS_DECODER_MALFORMED_XOP_PREFIX;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_MALFORMED_XOP;
|
||||
return ZYDIS_STATUS_DECODER_MALFORMED_XOP;
|
||||
}
|
||||
info->opcodeMap = ZYDIS_OPCODE_MAP_XOP8 + info->details.xop.m_mmmm - 0x08;
|
||||
}
|
||||
|
@ -1974,18 +1973,18 @@ static ZydisDecoderStatus ZydisNodeHandlerMandatoryPrefix(ZydisInstructionInfo*
|
|||
ZYDIS_ASSERT(info);
|
||||
ZYDIS_ASSERT(index);
|
||||
|
||||
if (info->prefixes & ZYDIS_PREFIX_REP)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP)
|
||||
{
|
||||
*index = 2;
|
||||
info->prefixes &= ~ ZYDIS_PREFIX_REP; // TODO: don't remove but mark as mandatory
|
||||
} else if (info->prefixes & ZYDIS_PREFIX_REPNE)
|
||||
info->prefixFlags &= ~ ZYDIS_PREFIXFLAG_HAS_REP; // TODO: don't remove but mark as mandatory
|
||||
} else if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE)
|
||||
{
|
||||
*index = 3;
|
||||
info->prefixes &= ~ ZYDIS_PREFIX_REPNE; // TODO: don't remove but mark as mandatory
|
||||
} else if (info->prefixes & ZYDIS_PREFIX_OPERANDSIZE)
|
||||
info->prefixFlags &= ~ ZYDIS_PREFIXFLAG_HAS_REPNE; // TODO: don't remove but mark as mandatory
|
||||
} else if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE)
|
||||
{
|
||||
*index = 1;
|
||||
info->prefixes &= ~ ZYDIS_PREFIX_OPERANDSIZE; // TODO: don't remove but mark as mandatory
|
||||
info->prefixFlags &= ~ ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE; // TODO: don't remove but mark as mandatory
|
||||
}
|
||||
return ZYDIS_STATUS_DECODER_SUCCESS;
|
||||
}
|
||||
|
@ -2048,16 +2047,16 @@ static ZydisDecoderStatus ZydisNodeHandlerOperandSize(ZydisInstructionDecoder* d
|
|||
ZYDIS_ASSERT(info);
|
||||
ZYDIS_ASSERT(index);
|
||||
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_OPERANDSIZE;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_OPERANDSIZE;
|
||||
|
||||
switch (decoder->disassemblerMode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
*index = (info->prefixes & ZYDIS_PREFIX_OPERANDSIZE) ? 1 : 0;
|
||||
*index = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE) ? 1 : 0;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
*index = (info->prefixes & ZYDIS_PREFIX_OPERANDSIZE) ? 0 : 1;
|
||||
*index = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE) ? 0 : 1;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
|
@ -2072,18 +2071,18 @@ static ZydisDecoderStatus ZydisNodeHandlerAddressSize(ZydisInstructionDecoder* d
|
|||
ZYDIS_ASSERT(info);
|
||||
ZYDIS_ASSERT(index);
|
||||
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE;
|
||||
info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_ADDRESSSIZE;
|
||||
|
||||
switch (decoder->disassemblerMode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
*index = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 1 : 0;
|
||||
*index = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 1 : 0;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
*index = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 0 : 1;
|
||||
*index = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 0 : 1;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
*index = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 1 : 2;
|
||||
*index = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 1 : 2;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
|
@ -2211,8 +2210,8 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
|
|||
{
|
||||
case ZYDIS_NODETYPE_INVALID:
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID;
|
||||
return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_UNDEFINED;
|
||||
return ZYDIS_STATUS_DECODER_UNDEFINED_INSTRUCTION;
|
||||
}
|
||||
case ZYDIS_NODETYPE_DEFINITION_0OP:
|
||||
case ZYDIS_NODETYPE_DEFINITION_1OP:
|
||||
|
@ -2250,8 +2249,8 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
|
|||
node = ZydisInstructionTableGetChildNode(node, info->opcode);
|
||||
if (ZydisInstructionTableGetNodeType(node) == ZYDIS_NODETYPE_INVALID)
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID;
|
||||
return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION;
|
||||
info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_UNDEFINED;
|
||||
return ZYDIS_STATUS_DECODER_UNDEFINED_INSTRUCTION;
|
||||
}
|
||||
node = ZydisInstructionTableGetChildNode(node,
|
||||
(info->details.modrm.mod == 0x3) ? 1 : 0);
|
||||
|
@ -2524,7 +2523,7 @@ ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder,
|
|||
|
||||
DecodeError:
|
||||
{
|
||||
uint32_t flags = info->flags;
|
||||
uint32_t flags = info->instrFlags;
|
||||
uint8_t firstByte = info->data[0];
|
||||
uint64_t instrAddress = info->instrAddress;
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
@ -2551,7 +2550,7 @@ DecodeError:
|
|||
|
||||
++decoder->instructionPointer;
|
||||
info->mode = decoder->disassemblerMode;
|
||||
info->flags = flags & ZYDIS_INSTRUCTION_ERROR_MASK;
|
||||
info->instrFlags = flags & ZYDIS_INSTRFLAG_ERROR_MASK;
|
||||
info->length = 1;
|
||||
info->data[0] = firstByte;
|
||||
info->instrAddress = instrAddress;
|
||||
|
@ -2559,7 +2558,7 @@ DecodeError:
|
|||
|
||||
if (!decoder->flags & ZYDIS_DECODER_FLAG_SKIP_DATA)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_INSTRUCTION;
|
||||
return ZYDIS_STATUS_DECODING_ERROR;
|
||||
}
|
||||
}
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
|
|
|
@ -58,14 +58,14 @@
|
|||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Inserts the @c text into the @c buffer at the given @c offset and increases the
|
||||
* @c offset by the length of the text.
|
||||
* @brief Appends the @c text to the @c buffer at the given @c offset and increases the
|
||||
* @c offset by the length of the @c text.
|
||||
*
|
||||
* @param buffer A pointer to the target buffer.
|
||||
* @param bufferLen The length of the buffer.
|
||||
* @param offset A pointer to the buffer-offset.
|
||||
* @param text The text to insert.
|
||||
* @param uppercase Set true, to convert to uppercase characters.
|
||||
* @param text The text to append.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
|
@ -95,12 +95,13 @@ static ZydisStatus ZydisBufferAppend(char* buffer, size_t bufferLen, size_t* off
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts formatted text into the @c buffer at the given @c offset and increases the
|
||||
* @c offset by the length of the text.
|
||||
* @brief Appends formatted to into the @c buffer at the given @c offset and increases the
|
||||
* @c offset by the length of the @c text.
|
||||
*
|
||||
* @param buffer A pointer to the target buffer.
|
||||
* @param bufferLen The length of the buffer.
|
||||
* @param offset A pointer to the buffer-offset.
|
||||
* @param uppercase Set true, to convert to uppercase characters.
|
||||
* @param format The format string.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
|
@ -199,27 +200,20 @@ static ZydisStatus ZydisBufferAppendAbsoluteAddress(const ZydisInstructionFormat
|
|||
switch (info->mode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%04X", address);
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
switch (operand->size)
|
||||
if (operand->size == 16)
|
||||
{
|
||||
case 16:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%04X", address);
|
||||
case 32:
|
||||
}
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%08lX", address);
|
||||
case 64:
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%016llX", address);
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisBufferAppendImmediate(const ZydisInstructionFormatter* formatter,
|
||||
|
@ -233,7 +227,7 @@ static ZydisStatus ZydisBufferAppendImmediate(const ZydisInstructionFormatter* f
|
|||
ZYDIS_ASSERT(info);
|
||||
ZYDIS_ASSERT(operand);
|
||||
|
||||
if ((formatter->addressFormat == ZYDIS_FORMATTER_ADDRESS_ABSOLUTE) &&
|
||||
if ((formatter->addressFormat == ZYDIS_FORMATTER_ADDR_ABSOLUTE) &&
|
||||
(operand->imm.isRelative))
|
||||
{
|
||||
return ZydisBufferAppendAbsoluteAddress(formatter, buffer, bufferLen, offset, info,
|
||||
|
@ -241,7 +235,7 @@ static ZydisStatus ZydisBufferAppendImmediate(const ZydisInstructionFormatter* f
|
|||
}
|
||||
|
||||
bool useSignedHex = ((operand->imm.isSigned &&
|
||||
(formatter->addressFormat == ZYDIS_FORMATTER_ADDRESS_RELATIVE_SIGNED)) ||
|
||||
(formatter->addressFormat == ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED)) ||
|
||||
(!operand->imm.isSigned && (formatter->immediateFormat == ZYDIS_FORMATTER_IMM_HEX_SIGNED)));
|
||||
|
||||
if (useSignedHex && (operand->imm.value.sqword < 0))
|
||||
|
@ -340,9 +334,9 @@ static ZydisStatus ZydisBufferAppendOperandIntelMemory(const ZydisInstructionFor
|
|||
{
|
||||
if ((formatter->flags & ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT) ||
|
||||
(((operand->mem.segment != ZYDIS_REGISTER_DS) ||
|
||||
(info->prefixes & ZYDIS_PREFIX_SEGMENT_DS)) &&
|
||||
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS)) &&
|
||||
((operand->mem.segment != ZYDIS_REGISTER_SS) ||
|
||||
(info->prefixes & ZYDIS_PREFIX_SEGMENT_SS))))
|
||||
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_SS))))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "%s:",
|
||||
|
@ -446,27 +440,27 @@ static ZydisStatus ZydisFormatterFormatInstructionIntel(ZydisInstructionFormatte
|
|||
{
|
||||
size_t offset = 0;
|
||||
|
||||
if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_REPNE) &&
|
||||
(info->prefixes & ZYDIS_PREFIX_REPNE))
|
||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REPNE) &&
|
||||
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "repne "));
|
||||
}
|
||||
if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_REP) && (info->prefixes & ZYDIS_PREFIX_REP))
|
||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REP) && (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "rep "));
|
||||
}
|
||||
if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_LOCK) && (info->prefixes & ZYDIS_PREFIX_LOCK))
|
||||
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_LOCK) && (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_LOCK))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "lock "));
|
||||
}
|
||||
if (info->prefixes & ZYDIS_PREFIX_XACQUIRE)
|
||||
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_XACQUIRE)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "xacquire "));
|
||||
} else if (info->prefixes & ZYDIS_PREFIX_XRELEASE)
|
||||
} else if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_XRELEASE)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "xrelease "));
|
||||
|
@ -652,7 +646,7 @@ ZydisStatus ZydisFormatterInitInstructionFormatterEx(
|
|||
}
|
||||
formatter->style = style;
|
||||
formatter->flags = flags;
|
||||
formatter->addressFormat = ZYDIS_FORMATTER_ADDRESS_ABSOLUTE;
|
||||
formatter->addressFormat = ZYDIS_FORMATTER_ADDR_ABSOLUTE;
|
||||
formatter->displacementFormat = ZYDIS_FORMATTER_DISP_HEX_SIGNED;
|
||||
formatter->immediateFormat = ZYDIS_FORMATTER_IMM_HEX_UNSIGNED;
|
||||
formatter->symbolResolver = NULL;
|
||||
|
|
|
@ -51,21 +51,32 @@ typedef struct ZydisInternalInstructionTableNode_
|
|||
#define ZYDIS_GET_INSTRUCTIONTABLENODE_VALUE(node) \
|
||||
node.value
|
||||
|
||||
typedef struct ZydisInternalOperandDefinition_
|
||||
{
|
||||
unsigned int type : 8;
|
||||
unsigned int encoding : 8;
|
||||
unsigned int access : 2;
|
||||
} ZydisInternalOperandDefinition;
|
||||
//typedef struct ZydisInternalOperandDefinition_
|
||||
//{
|
||||
// unsigned int type : 8;
|
||||
// unsigned int encoding : 8;
|
||||
// unsigned int access : 2;
|
||||
//} ZydisInternalOperandDefinition;
|
||||
//
|
||||
//#define ZYDIS_MAKE_OPERANDDEFINITION(type, encoding, access) \
|
||||
// { type, encoding, access }
|
||||
//#define ZYDIS_GET_OPERANDDEFINITION_TYPE(def) \
|
||||
// (ZydisSemanticOperandType)def.type
|
||||
//#define ZYDIS_GET_OPERANDDEFINITION_ENCODING(def) \
|
||||
// (ZydisOperandEncoding)def.encoding
|
||||
//#define ZYDIS_GET_OPERANDDEFINITION_ACCESS(def) \
|
||||
// (ZydisOperandAccess)def.access
|
||||
|
||||
typedef uint8_t ZydisInternalOperandDefinition[2];
|
||||
|
||||
#define ZYDIS_MAKE_OPERANDDEFINITION(type, encoding, access) \
|
||||
{ type, encoding, access }
|
||||
{ type, ((encoding & 0x3F) << 2) | (access & 0x03) }
|
||||
#define ZYDIS_GET_OPERANDDEFINITION_TYPE(def) \
|
||||
(ZydisSemanticOperandType)def.type
|
||||
def[0]
|
||||
#define ZYDIS_GET_OPERANDDEFINITION_ENCODING(def) \
|
||||
(ZydisOperandEncoding)def.encoding
|
||||
((def[1] >> 2) & 0x3F)
|
||||
#define ZYDIS_GET_OPERANDDEFINITION_ACCESS(def) \
|
||||
(ZydisOperandAccess)def.access
|
||||
(def[1] & 0x03)
|
||||
|
||||
typedef struct ZydisInternalInstructionDefinition_
|
||||
{
|
||||
|
|
|
@ -322,7 +322,7 @@ ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg)
|
|||
case ZYDIS_REGISTERCLASS_TABLE:
|
||||
return ZYDIS_REGISTERSIZE_DYNAMIC;
|
||||
case ZYDIS_REGISTERCLASS_TEST:
|
||||
return ZYDIS_REGISTERSIZE_INVALID; // TODO:
|
||||
return ZYDIS_REGISTERSIZE_32;
|
||||
case ZYDIS_REGISTERCLASS_CONTROL:
|
||||
return ZYDIS_REGISTERSIZE_DYNAMIC;
|
||||
case ZYDIS_REGISTERCLASS_DEBUG:
|
||||
|
|
19
src/Utils.c
19
src/Utils.c
|
@ -61,23 +61,20 @@ ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info
|
|||
}
|
||||
break;
|
||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||
if (operand->imm.isSigned || operand->imm.isRelative)
|
||||
if (operand->imm.isSigned && operand->imm.isRelative)
|
||||
{
|
||||
*address = (uint64_t)((int64_t)info->instrPointer + operand->imm.value.sqword);
|
||||
switch (operand->size)
|
||||
switch (info->mode)
|
||||
{
|
||||
case 16:
|
||||
*address = (uint16_t)*address;
|
||||
break;
|
||||
case 32:
|
||||
assert((info->mode != ZYDIS_DISASSEMBLER_MODE_64BIT)); // TODO: Remove after fuzzing
|
||||
if (info->mode != ZYDIS_DISASSEMBLER_MODE_64BIT)
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
if (operand->size == 16)
|
||||
{
|
||||
*address = (uint32_t)*address;
|
||||
*address &= 0xFFFF;
|
||||
}
|
||||
break;
|
||||
case 64:
|
||||
assert((info->mode == ZYDIS_DISASSEMBLER_MODE_64BIT)); // TODO: Remove after fuzzing
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
assert((operand->size == 64)); // TODO: Remove after fuzzing
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
|
|
|
@ -78,7 +78,7 @@ int main(int argc, char** argv)
|
|||
ZydisInstructionInfo info;
|
||||
while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info)))
|
||||
{
|
||||
if (info.flags & ZYDIS_IFLAG_ERROR_MASK)
|
||||
if (info.instrFlags & ZYDIS_INSTRFLAG_ERROR_MASK)
|
||||
{
|
||||
printf("db %02X\n", info.data[0]);
|
||||
continue;
|
||||
|
|
|
@ -24,7 +24,9 @@
|
|||
|
||||
***************************************************************************************************/
|
||||
|
||||
/*
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* This file implements a tool that is supposed to be fed as input for fuzzers like AFL,
|
||||
* reading a control block from stdin, allowing the fuzzer to reach every possible
|
||||
* code-path, testing any possible combination of disassembler configurations.
|
||||
|
@ -85,7 +87,7 @@ int main()
|
|||
char *outBuf = malloc(controlBlock.bufSize);
|
||||
while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info)))
|
||||
{
|
||||
if (info.flags & ZYDIS_IFLAG_ERROR_MASK)
|
||||
if (info.instrFlags & ZYDIS_INSTRFLAG_ERROR_MASK)
|
||||
{
|
||||
printf("db %02X\n", info.data[0]);
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue