diff --git a/include/Zydis/Decoder.h b/include/Zydis/Decoder.h index 717a6f6..000cd94 100644 --- a/include/Zydis/Decoder.h +++ b/include/Zydis/Decoder.h @@ -73,7 +73,11 @@ enum ZydisDecodeGranularities /** * @brief Full physical and semantic instruction-decoding. */ - ZYDIS_DECODE_GRANULARITY_FULL + ZYDIS_DECODE_GRANULARITY_FULL, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_DECODE_GRANULARITY_MAX_VALUE = ZYDIS_DECODE_GRANULARITY_FULL, }; /** diff --git a/include/Zydis/DecoderTypes.h b/include/Zydis/DecoderTypes.h index aac1c50..b51aab2 100644 --- a/include/Zydis/DecoderTypes.h +++ b/include/Zydis/DecoderTypes.h @@ -461,11 +461,10 @@ enum ZydisCPUFlags * @brief FPU condition-code flag 3. */ ZYDIS_CPUFLAG_C3, - /** - * @brief Marker value. + * @brief Maximum value of this enum. */ - ZYDIS_CPUFLAG_ENUM_COUNT + ZYDIS_CPUFLAG_MAX_VALUE = ZYDIS_CPUFLAG_C3 }; /** @@ -483,7 +482,11 @@ enum ZydisCPUFlagActions ZYDIS_CPUFLAG_ACTION_MODIFIED, ZYDIS_CPUFLAG_ACTION_SET_0, ZYDIS_CPUFLAG_ACTION_SET_1, - ZYDIS_CPUFLAG_ACTION_UNDEFINED + ZYDIS_CPUFLAG_ACTION_UNDEFINED, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_CPUFLAG_ACTION_MAX_VALUE = ZYDIS_CPUFLAG_ACTION_UNDEFINED }; /* ---------------------------------------------------------------------------------------------- */ @@ -540,7 +543,11 @@ enum ZydisExceptionClasses ZYDIS_EXCEPTION_CLASS_E12, ZYDIS_EXCEPTION_CLASS_E12NP, ZYDIS_EXCEPTION_CLASS_K20, - ZYDIS_EXCEPTION_CLASS_K21 + ZYDIS_EXCEPTION_CLASS_K21, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_EXCEPTION_CLASS_MAX_VALUE = ZYDIS_EXCEPTION_CLASS_K21 }; /* ---------------------------------------------------------------------------------------------- */ @@ -560,7 +567,11 @@ enum ZydisVectorLengths ZYDIS_VECTOR_LENGTH_INVALID = 0, ZYDIS_VECTOR_LENGTH_128 = 128, ZYDIS_VECTOR_LENGTH_256 = 256, - ZYDIS_VECTOR_LENGTH_512 = 512 + ZYDIS_VECTOR_LENGTH_512 = 512, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_VECTOR_LENGTH_MAX_VALUE = ZYDIS_VECTOR_LENGTH_512 }; /* ---------------------------------------------------------------------------------------------- */ @@ -586,7 +597,11 @@ enum ZydisMaskModes /** * @brief The embedded mask register is used as a zero-mask. */ - ZYDIS_MASK_MODE_ZERO + ZYDIS_MASK_MODE_ZERO, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_MASK_MODE_MAX_VALUE = ZYDIS_MASK_MODE_ZERO }; /* ---------------------------------------------------------------------------------------------- */ @@ -615,7 +630,11 @@ enum ZydisBroadcastModes ZYDIS_BROADCAST_MODE_2_TO_16, ZYDIS_BROADCAST_MODE_4_TO_8, ZYDIS_BROADCAST_MODE_4_TO_16, - ZYDIS_BROADCAST_MODE_8_TO_16 + ZYDIS_BROADCAST_MODE_8_TO_16, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_BROADCAST_MODE_MAX_VALUE = ZYDIS_BROADCAST_MODE_8_TO_16 }; /* ---------------------------------------------------------------------------------------------- */ @@ -648,7 +667,11 @@ enum ZydisRoundingModes /** * @brief Round towards zero. */ - ZYDIS_ROUNDING_MODE_RZ + ZYDIS_ROUNDING_MODE_RZ, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_ROUNDING_MODE_MAX_VALUE = ZYDIS_ROUNDING_MODE_RZ }; /* ---------------------------------------------------------------------------------------------- */ @@ -673,7 +696,11 @@ enum ZydisSwizzleModes ZYDIS_SWIZZLE_MODE_AAAA, ZYDIS_SWIZZLE_MODE_BBBB, ZYDIS_SWIZZLE_MODE_CCCC, - ZYDIS_SWIZZLE_MODE_DDDD + ZYDIS_SWIZZLE_MODE_DDDD, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_SWIZZLE_MODE_MAX_VALUE = ZYDIS_SWIZZLE_MODE_DDDD }; /* ---------------------------------------------------------------------------------------------- */ @@ -695,7 +722,11 @@ enum ZydisConversionModes ZYDIS_CONVERSION_MODE_SINT8, ZYDIS_CONVERSION_MODE_UINT8, ZYDIS_CONVERSION_MODE_SINT16, - ZYDIS_CONVERSION_MODE_UINT16 + ZYDIS_CONVERSION_MODE_UINT16, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_CONVERSION_MODE_MAX_VALUE = ZYDIS_CONVERSION_MODE_UINT16 }; /* ---------------------------------------------------------------------------------------------- */ @@ -783,7 +814,7 @@ typedef struct ZydisDecodedInstruction_ * specific action. */ ZydisCPUFlagAction action; - } accessedFlags[ZYDIS_CPUFLAG_ENUM_COUNT]; + } accessedFlags[ZYDIS_CPUFLAG_MAX_VALUE + 1]; /** * @brief Extended info for AVX instructions. */ diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index adc153b..033bbb4 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -57,7 +57,11 @@ enum ZydisFormatterStyles /** * @brief Generates intel-style disassembly. */ - ZYDIS_FORMATTER_STYLE_INTEL + ZYDIS_FORMATTER_STYLE_INTEL, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_FORMATTER_STYLE_MAX_VALUE = ZYDIS_FORMATTER_STYLE_INTEL }; /* ---------------------------------------------------------------------------------------------- */ @@ -117,6 +121,10 @@ enum ZydisFormatterAddressFormats * "JMP 0xE0" */ ZYDIS_FORMATTER_ADDR_RELATIVE_UNSIGNED, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_FORMATTER_ADDR_MAX_VALUE = ZYDIS_FORMATTER_ADDR_RELATIVE_UNSIGNED }; /* ---------------------------------------------------------------------------------------------- */ @@ -150,7 +158,11 @@ enum ZydisFormatterDisplacementFormats * "MOV EAX, DWORD PTR SS:[ESP+0x400]" * "MOV EAX, DWORD PTR SS:[ESP+0xFFFFFC00]" */ - ZYDIS_FORMATTER_DISP_HEX_UNSIGNED + ZYDIS_FORMATTER_DISP_HEX_UNSIGNED, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_FORMATTER_DISP_MAX_VALUE = ZYDIS_FORMATTER_DISP_HEX_UNSIGNED }; /* ---------------------------------------------------------------------------------------------- */ @@ -189,7 +201,11 @@ enum ZydisFormatterImmediateFormats * "MOV EAX, 0x400" * "MOV EAX, 0xFFFFFC00" */ - ZYDIS_FORMATTER_IMM_HEX_UNSIGNED + ZYDIS_FORMATTER_IMM_HEX_UNSIGNED, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_FORMATTER_IMM_MAX_VALUE = ZYDIS_FORMATTER_IMM_HEX_UNSIGNED }; /* ---------------------------------------------------------------------------------------------- */ @@ -277,7 +293,11 @@ enum ZydisFormatterHookTypes /** * @brief This function is called to print an immediate value. */ - ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE + ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_FORMATTER_HOOK_MAX_VALUE = ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE }; /* ---------------------------------------------------------------------------------------------- */ @@ -299,7 +319,11 @@ enum ZydisDecoratorTypes ZYDIS_DECORATOR_TYPE_SAE, ZYDIS_DECORATOR_TYPE_SWIZZLE, ZYDIS_DECORATOR_TYPE_CONVERSION, - ZYDIS_DECORATOR_TYPE_EVICTION_HINT + ZYDIS_DECORATOR_TYPE_EVICTION_HINT, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_DECORATOR_TYPE_MAX_VALUE = ZYDIS_DECORATOR_TYPE_EVICTION_HINT }; typedef struct ZydisFormatter_ ZydisFormatter; diff --git a/include/Zydis/Register.h b/include/Zydis/Register.h index 3a7d2a4..c596e57 100644 --- a/include/Zydis/Register.h +++ b/include/Zydis/Register.h @@ -142,7 +142,16 @@ enum ZydisRegisters ZYDIS_REGISTER_K4, ZYDIS_REGISTER_K5, ZYDIS_REGISTER_K6, ZYDIS_REGISTER_K7, // Bound registers ZYDIS_REGISTER_BND0, ZYDIS_REGISTER_BND1, ZYDIS_REGISTER_BND2, ZYDIS_REGISTER_BND3, - ZYDIS_REGISTER_BNDCFG, ZYDIS_REGISTER_BNDSTATUS + ZYDIS_REGISTER_BNDCFG, ZYDIS_REGISTER_BNDSTATUS, + + /** + * @brief Maximum value of this enum. + */ + ZYDIS_REGISTER_MAX_VALUE = ZYDIS_REGISTER_BNDSTATUS, + /** + * @brief Maximum amount of bits occupied by an integer from this enum. + */ + ZYDIS_REGISTER_MAX_BITS = 8 }; /* ---------------------------------------------------------------------------------------------- */ @@ -227,7 +236,11 @@ enum ZydisRegisterClasses /** * @brief Bound registers. */ - ZYDIS_REGCLASS_BOUND + ZYDIS_REGCLASS_BOUND, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_REGCLASS_MAX_VALUE = ZYDIS_REGCLASS_BOUND }; /* ---------------------------------------------------------------------------------------------- */ diff --git a/include/Zydis/SharedTypes.h b/include/Zydis/SharedTypes.h index 43b462d..bd2dd8d 100644 --- a/include/Zydis/SharedTypes.h +++ b/include/Zydis/SharedTypes.h @@ -93,7 +93,11 @@ enum ZydisMachineModes /** * @brief 16 bit real mode. */ - ZYDIS_MACHINE_MODE_REAL_16 = 16 + ZYDIS_MACHINE_MODE_REAL_16 = 16, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_MACHINE_MODE_MAX_VALUE = ZYDIS_MACHINE_MODE_LONG_64 }; /* ---------------------------------------------------------------------------------------------- */ @@ -113,7 +117,8 @@ enum ZydisAddressWidths ZYDIS_ADDRESS_WIDTH_INVALID = 0, ZYDIS_ADDRESS_WIDTH_16 = 16, ZYDIS_ADDRESS_WIDTH_32 = 32, - ZYDIS_ADDRESS_WIDTH_64 = 64 + ZYDIS_ADDRESS_WIDTH_64 = 64, + ZYDIS_ADDRESS_WIDTH_MAX_VALUE = ZYDIS_ADDRESS_WIDTH_64 }; /* ---------------------------------------------------------------------------------------------- */ @@ -138,7 +143,8 @@ enum ZydisElementTypes ZYDIS_ELEMENT_TYPE_FLOAT32, ZYDIS_ELEMENT_TYPE_FLOAT64, ZYDIS_ELEMENT_TYPE_FLOAT80, - ZYDIS_ELEMENT_TYPE_LONGBCD + ZYDIS_ELEMENT_TYPE_LONGBCD, + ZYDIS_ELEMENT_TYPE_MAX_VALUE = ZYDIS_ELEMENT_TYPE_LONGBCD }; /** @@ -179,7 +185,11 @@ enum ZydisOperandTypes /** * @brief The operand is an immediate operand. */ - ZYDIS_OPERAND_TYPE_IMMEDIATE + ZYDIS_OPERAND_TYPE_IMMEDIATE, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_OPERAND_TYPE_MAX_VALUE = ZYDIS_OPERAND_TYPE_IMMEDIATE }; /* ---------------------------------------------------------------------------------------------- */ @@ -230,7 +240,8 @@ enum ZydisOperandEncodings ZYDIS_OPERAND_ENCODING_JIMM64, ZYDIS_OPERAND_ENCODING_JIMM16_32_64, ZYDIS_OPERAND_ENCODING_JIMM32_32_64, - ZYDIS_OPERAND_ENCODING_JIMM16_32_32 + ZYDIS_OPERAND_ENCODING_JIMM16_32_32, + ZYDIS_OPERAND_ENCODING_MAX_VALUE = ZYDIS_OPERAND_ENCODING_JIMM16_32_32 }; /* ---------------------------------------------------------------------------------------------- */ @@ -259,7 +270,11 @@ enum ZydisOperandVisibilities /** * @brief The operand is part of the opcode, and not typically listed as an operand. */ - ZYDIS_OPERAND_VISIBILITY_HIDDEN + ZYDIS_OPERAND_VISIBILITY_HIDDEN, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_OPERAND_VISIBILITY_MAX_VALUE = ZYDIS_OPERAND_VISIBILITY_HIDDEN }; /* ---------------------------------------------------------------------------------------------- */ @@ -304,7 +319,25 @@ enum ZydisOperandActions /** * @brief The operand is written and conditionally read by the instruction (must write). */ - ZYDIS_OPERAND_ACTION_CONDREAD_WRITE + ZYDIS_OPERAND_ACTION_CONDREAD_WRITE, + + /** + * @brief Mask combining all writing access flags. + */ + ZYDIS_OPERAND_ACTION_MASK_WRITE = ZYDIS_OPERAND_ACTION_WRITE | + ZYDIS_OPERAND_ACTION_READWRITE | ZYDIS_OPERAND_ACTION_CONDWRITE | + ZYDIS_OPERAND_ACTION_READ_CONDWRITE | ZYDIS_OPERAND_ACTION_CONDREAD_WRITE, + /** + * @brief Mask combining all reading access flags. + */ + ZYDIS_OPERAND_ACTION_MASK_READ = ZYDIS_OPERAND_ACTION_READ | ZYDIS_OPERAND_ACTION_READWRITE | + ZYDIS_OPERAND_ACTION_CONDREAD | ZYDIS_OPERAND_ACTION_READ_CONDWRITE | + ZYDIS_OPERAND_ACTION_CONDREAD_WRITE, + + /** + * @brief Maximum value of this enum. + */ + ZYDIS_OPERAND_ACTION_MAX_VALUE = ZYDIS_OPERAND_ACTION_CONDREAD_WRITE }; /* ---------------------------------------------------------------------------------------------- */ @@ -345,7 +378,11 @@ enum ZydisInstructionEncodings /** * @brief The instruction uses the MVEX-encoding. */ - ZYDIS_INSTRUCTION_ENCODING_MVEX + ZYDIS_INSTRUCTION_ENCODING_MVEX, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_INSTRUCTION_ENCODING_MAX_VALUE = ZYDIS_INSTRUCTION_ENCODING_MVEX }; /* ---------------------------------------------------------------------------------------------- */ @@ -369,7 +406,8 @@ enum ZydisOpcodeMaps ZYDIS_OPCODE_MAP_0F0F, ZYDIS_OPCODE_MAP_XOP8, ZYDIS_OPCODE_MAP_XOP9, - ZYDIS_OPCODE_MAP_XOPA + ZYDIS_OPCODE_MAP_XOPA, + ZYDIS_OPCODE_MAP_MAX_VALUE = ZYDIS_OPCODE_MAP_XOP9 }; /* ---------------------------------------------------------------------------------------------- */ diff --git a/include/Zydis/Status.h b/include/Zydis/Status.h index f2d89b7..8eaa044 100644 --- a/include/Zydis/Status.h +++ b/include/Zydis/Status.h @@ -140,6 +140,9 @@ enum ZydisStatusCode * @brief The base value for user-defined status codes. */ ZYDIS_STATUS_USER = 0x10000000 + + // Max value entry intentionally omitted since users might + // define custom error codes for formatter hooks. }; /* ============================================================================================== */ diff --git a/src/SharedData.h b/src/SharedData.h index 32caeac..5b7c077 100644 --- a/src/SharedData.h +++ b/src/SharedData.h @@ -629,7 +629,7 @@ typedef struct ZydisInstructionDefinitionMVEX_ typedef struct ZydisAccessedFlags_ { - ZydisCPUFlagAction action[ZYDIS_CPUFLAG_ENUM_COUNT]; + ZydisCPUFlagAction action[ZYDIS_CPUFLAG_MAX_VALUE + 1]; } ZydisAccessedFlags; /* ---------------------------------------------------------------------------------------------- */ diff --git a/tools/ZydisInfo.c b/tools/ZydisInfo.c index 80f21a3..2cb3330 100644 --- a/tools/ZydisInfo.c +++ b/tools/ZydisInfo.c @@ -435,6 +435,55 @@ void printInstruction(ZydisDecodedInstruction* instruction) "K21" }; + struct + { + ZydisInstructionAttributes attrMask; + const char* str; + } attributeMap[] = + { + {ZYDIS_ATTRIB_HAS_MODRM, "HAS_MODRM" }, + {ZYDIS_ATTRIB_HAS_SIB, "HAS_SIB" }, + {ZYDIS_ATTRIB_HAS_REX, "HAS_REX" }, + {ZYDIS_ATTRIB_HAS_XOP, "HAS_XOP" }, + {ZYDIS_ATTRIB_HAS_VEX, "HAS_VEX" }, + {ZYDIS_ATTRIB_HAS_EVEX, "HAS_EVEX" }, + {ZYDIS_ATTRIB_HAS_MVEX, "HAS_MVEX" }, + {ZYDIS_ATTRIB_IS_RELATIVE, "IS_RELATIVE" }, + {ZYDIS_ATTRIB_IS_PRIVILEGED, "IS_PRIVILEGED" }, + {ZYDIS_ATTRIB_ACCEPTS_LOCK, "ACCEPTS_LOCK" }, + {ZYDIS_ATTRIB_ACCEPTS_REP, "ACCEPTS_REP" }, + {ZYDIS_ATTRIB_ACCEPTS_REPE, "ACCEPTS_REPE" }, + {ZYDIS_ATTRIB_ACCEPTS_REPZ, "ACCEPTS_REPZ" }, + {ZYDIS_ATTRIB_ACCEPTS_REPNE, "ACCEPTS_REPNE" }, + {ZYDIS_ATTRIB_ACCEPTS_REPNZ, "ACCEPTS_REPNZ" }, + {ZYDIS_ATTRIB_ACCEPTS_BOUND, "ACCEPTS_BOUND" }, + {ZYDIS_ATTRIB_ACCEPTS_XACQUIRE, "ACCEPTS_XACQUIRE" }, + {ZYDIS_ATTRIB_ACCEPTS_XRELEASE, "ACCEPTS_XRELEASE" }, + {ZYDIS_ATTRIB_ACCEPTS_HLE_WITHOUT_LOCK, "ACCEPTS_HLE_WITHOUT_LOCK" }, + {ZYDIS_ATTRIB_ACCEPTS_BRANCH_HINTS, "ACCEPTS_BRANCH_HINTS" }, + {ZYDIS_ATTRIB_ACCEPTS_SEGMENT, "ACCEPTS_SEGMENT" }, + {ZYDIS_ATTRIB_HAS_LOCK, "HAS_LOCK" }, + {ZYDIS_ATTRIB_HAS_REP, "HAS_REP" }, + {ZYDIS_ATTRIB_HAS_REPE, "HAS_REPE" }, + {ZYDIS_ATTRIB_HAS_REPZ, "HAS_REPZ" }, + {ZYDIS_ATTRIB_HAS_REPNE, "HAS_REPNE" }, + {ZYDIS_ATTRIB_HAS_REPNZ, "HAS_REPNZ" }, + {ZYDIS_ATTRIB_HAS_BOUND, "HAS_BOUND" }, + {ZYDIS_ATTRIB_HAS_XACQUIRE, "HAS_XACQUIRE" }, + {ZYDIS_ATTRIB_HAS_XRELEASE, "HAS_XRELEASE" }, + {ZYDIS_ATTRIB_HAS_BRANCH_NOT_TAKEN, "HAS_BRANCH_NOT_TAKEN" }, + {ZYDIS_ATTRIB_HAS_BRANCH_TAKEN, "HAS_BRANCH_TAKEN" }, + {ZYDIS_ATTRIB_HAS_SEGMENT, "HAS_SEGMENT" }, + {ZYDIS_ATTRIB_HAS_SEGMENT_CS, "HAS_SEGMENT_CS" }, + {ZYDIS_ATTRIB_HAS_SEGMENT_SS, "HAS_SEGMENT_SS" }, + {ZYDIS_ATTRIB_HAS_SEGMENT_DS, "HAS_SEGMENT_DS" }, + {ZYDIS_ATTRIB_HAS_SEGMENT_ES, "HAS_SEGMENT_ES" }, + {ZYDIS_ATTRIB_HAS_SEGMENT_FS, "HAS_SEGMENT_FS" }, + {ZYDIS_ATTRIB_HAS_SEGMENT_GS, "HAS_SEGMENT_GS" }, + {ZYDIS_ATTRIB_HAS_OPERANDSIZE, "HAS_OPERANDSIZE" }, + {ZYDIS_ATTRIB_HAS_ADDRESSSIZE, "HAS_ADDRESSSIZE" } + }; + fputs("== [ BASIC ] =====================================================", stdout); fputs("=======================================\n", stdout); printf(" MNEMONIC: %s [ENC: %s, MAP: %s, OPC: %02X]\n", @@ -450,6 +499,17 @@ void printInstruction(ZydisDecodedInstruction* instruction) printf(" ISA-SET: %s\n", ZydisISASetGetString(instruction->meta.isaSet)); printf(" ISA-EXT: %s\n", ZydisISAExtGetString(instruction->meta.isaExt)); printf(" EXCEPTIONS: %s\n", exceptionClassStrings[instruction->meta.exceptionClass]); + fputs (" ATTRIBUTES: ", stdout); + + for (size_t i = 0; i < ZYDIS_ARRAY_SIZE(attributeMap); ++i) + { + if (instruction->attributes & attributeMap[i].attrMask) + { + printf("%s ", attributeMap[i].str); + } + } + + fputs("\n", stdout); if (instruction->operandCount > 0) {