Skip to content

Commit

Permalink
Add UD0_COMPAT decoder mode
Browse files Browse the repository at this point in the history
  • Loading branch information
flobernd committed Jan 22, 2024
1 parent a605f54 commit cb7c691
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 57 deletions.
11 changes: 10 additions & 1 deletion include/Zydis/Decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,20 @@ typedef enum ZydisDecoderMode_
* This mode is enabled by default.
*/
ZYDIS_DECODER_MODE_IPREFETCH,
/**
* Enables the `UD0` compatibility mode.
*
* Some processors decode the `UD0` instruction without a ModR/M byte. Enable this decoder mode
* to mimic this behavior.
*
* This mode is disabled by default.
*/
ZYDIS_DECODER_MODE_UD0_COMPAT,

/**
* Maximum value of this enum.
*/
ZYDIS_DECODER_MODE_MAX_VALUE = ZYDIS_DECODER_MODE_IPREFETCH,
ZYDIS_DECODER_MODE_MAX_VALUE = ZYDIS_DECODER_MODE_UD0_COMPAT,
/**
* The minimum number of bits required to represent all values of this enum.
*/
Expand Down
6 changes: 5 additions & 1 deletion include/Zydis/Internal/DecoderData.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,11 @@ enum ZydisDecoderTreeNodeTypes
/**
* Reference to a IPREFETCH-mode filter.
*/
ZYDIS_NODETYPE_FILTER_MODE_IPREFETCH = 0x1C
ZYDIS_NODETYPE_FILTER_MODE_IPREFETCH = 0x1C,
/**
* Reference to a UD0_COMPAT-mode filter.
*/
ZYDIS_NODETYPE_FILTER_MODE_UD0_COMPAT = 0x1D
};

/* ---------------------------------------------------------------------------------------------- */
Expand Down
5 changes: 5 additions & 0 deletions src/Decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -4803,6 +4803,9 @@ static ZyanStatus ZydisDecodeInstruction(ZydisDecoderState* state,
case ZYDIS_NODETYPE_FILTER_MODE_IPREFETCH:
index = !!(state->decoder->decoder_mode & (1 << ZYDIS_DECODER_MODE_IPREFETCH));
break;
case ZYDIS_NODETYPE_FILTER_MODE_UD0_COMPAT:
index = !!(state->decoder->decoder_mode & (1 << ZYDIS_DECODER_MODE_UD0_COMPAT));
break;
default:
if (node_type & ZYDIS_NODETYPE_DEFINITION_MASK)
{
Expand Down Expand Up @@ -4899,6 +4902,8 @@ static ZyanStatus ZydisDecodeInstruction(ZydisDecoderState* state,
ZyanStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machine_mode,
ZydisStackWidth stack_width)
{
ZYAN_STATIC_ASSERT(ZYDIS_DECODER_MODE_MAX_VALUE <= 32);

static const ZyanU32 decoder_modes =
#ifdef ZYDIS_MINIMAL_MODE
(1 << ZYDIS_DECODER_MODE_MINIMAL) |
Expand Down
3 changes: 3 additions & 0 deletions src/DecoderData.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ const ZydisDecoderTreeNode* ZydisDecoderTreeGetChildNode(const ZydisDecoderTreeN
case ZYDIS_NODETYPE_FILTER_MODE_IPREFETCH:
ZYAN_ASSERT(index < 2);
return &FILTERS_MODE_IPREFETCH[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODE_UD0_COMPAT:
ZYAN_ASSERT(index < 2);
return &FILTERS_MODE_UD0_COMPAT[parent->value][index];
default:
ZYAN_UNREACHABLE;
}
Expand Down
115 changes: 60 additions & 55 deletions src/Generated/DecoderTables.inc

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/Generated/InstructionDefinitions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1835,6 +1835,7 @@ const ZydisInstructionDefinitionLEGACY ISTR_DEFINITIONS_LEGACY[] =
{ ZYDIS_MNEMONIC_UCOMISD ZYDIS_NOTMIN(3) ZYDIS_NOTMIN(2) ZYDIS_NOTMIN(0xE34), 0, 0 ZYDIS_NOTMIN(0x33), ZYAN_FALSE, ZYAN_FALSE ZYDIS_NOTMIN(ZYDIS_CATEGORY_SSE) ZYDIS_NOTMIN(ZYDIS_ISA_SET_SSE2) ZYDIS_NOTMIN(ZYDIS_ISA_EXT_SSE2) ZYDIS_NOTMIN(ZYDIS_BRANCH_TYPE_NONE) ZYDIS_NOTMIN(ZYDIS_EXCEPTION_CLASS_SSE3), ZYDIS_REGKIND_VR, ZYDIS_MEMOP_TYPE_MEM ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYAN_TRUE) ZYDIS_NOTMIN(ZYAN_FALSE), ZYAN_FALSE ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) },
{ ZYDIS_MNEMONIC_UCOMISS ZYDIS_NOTMIN(3) ZYDIS_NOTMIN(2) ZYDIS_NOTMIN(0xE37), 0, 0 ZYDIS_NOTMIN(0x33), ZYAN_FALSE, ZYAN_FALSE ZYDIS_NOTMIN(ZYDIS_CATEGORY_SSE) ZYDIS_NOTMIN(ZYDIS_ISA_SET_SSE) ZYDIS_NOTMIN(ZYDIS_ISA_EXT_SSE) ZYDIS_NOTMIN(ZYDIS_BRANCH_TYPE_NONE) ZYDIS_NOTMIN(ZYDIS_EXCEPTION_CLASS_SSE3), ZYDIS_REGKIND_VR, ZYDIS_REGKIND_VR ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE), ZYAN_FALSE ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) },
{ ZYDIS_MNEMONIC_UCOMISS ZYDIS_NOTMIN(3) ZYDIS_NOTMIN(2) ZYDIS_NOTMIN(0xE3A), 0, 0 ZYDIS_NOTMIN(0x33), ZYAN_FALSE, ZYAN_FALSE ZYDIS_NOTMIN(ZYDIS_CATEGORY_SSE) ZYDIS_NOTMIN(ZYDIS_ISA_SET_SSE) ZYDIS_NOTMIN(ZYDIS_ISA_EXT_SSE) ZYDIS_NOTMIN(ZYDIS_BRANCH_TYPE_NONE) ZYDIS_NOTMIN(ZYDIS_EXCEPTION_CLASS_SSE3), ZYDIS_REGKIND_VR, ZYDIS_MEMOP_TYPE_MEM ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYAN_TRUE) ZYDIS_NOTMIN(ZYAN_FALSE), ZYAN_FALSE ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) },
{ ZYDIS_MNEMONIC_UD0 ZYDIS_NOTMIN(0) ZYDIS_NOTMIN(0) ZYDIS_NOTMIN(0x0), 0, 0 ZYDIS_NOTMIN(0x0), ZYAN_FALSE, ZYAN_FALSE ZYDIS_NOTMIN(ZYDIS_CATEGORY_MISC) ZYDIS_NOTMIN(ZYDIS_ISA_SET_PPRO) ZYDIS_NOTMIN(ZYDIS_ISA_EXT_BASE) ZYDIS_NOTMIN(ZYDIS_BRANCH_TYPE_NONE) ZYDIS_NOTMIN(ZYDIS_EXCEPTION_CLASS_NONE), 0, 0 ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE), ZYAN_FALSE ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) },
{ ZYDIS_MNEMONIC_UD0 ZYDIS_NOTMIN(2) ZYDIS_NOTMIN(2) ZYDIS_NOTMIN(0x10BC), 0, 0 ZYDIS_NOTMIN(0x0), ZYAN_FALSE, ZYAN_FALSE ZYDIS_NOTMIN(ZYDIS_CATEGORY_MISC) ZYDIS_NOTMIN(ZYDIS_ISA_SET_PPRO) ZYDIS_NOTMIN(ZYDIS_ISA_EXT_BASE) ZYDIS_NOTMIN(ZYDIS_BRANCH_TYPE_NONE) ZYDIS_NOTMIN(ZYDIS_EXCEPTION_CLASS_NONE), ZYDIS_REGKIND_GPR, ZYDIS_REGKIND_GPR ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE), ZYAN_FALSE ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) },
{ ZYDIS_MNEMONIC_UD0 ZYDIS_NOTMIN(2) ZYDIS_NOTMIN(2) ZYDIS_NOTMIN(0x10BF), 0, 0 ZYDIS_NOTMIN(0x0), ZYAN_FALSE, ZYAN_FALSE ZYDIS_NOTMIN(ZYDIS_CATEGORY_MISC) ZYDIS_NOTMIN(ZYDIS_ISA_SET_PPRO) ZYDIS_NOTMIN(ZYDIS_ISA_EXT_BASE) ZYDIS_NOTMIN(ZYDIS_BRANCH_TYPE_NONE) ZYDIS_NOTMIN(ZYDIS_EXCEPTION_CLASS_NONE), ZYDIS_REGKIND_GPR, ZYDIS_MEMOP_TYPE_MEM ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYAN_TRUE) ZYDIS_NOTMIN(ZYAN_FALSE), ZYAN_FALSE ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) },
{ ZYDIS_MNEMONIC_UD1 ZYDIS_NOTMIN(2) ZYDIS_NOTMIN(2) ZYDIS_NOTMIN(0x10BC), 0, 0 ZYDIS_NOTMIN(0x0), ZYAN_FALSE, ZYAN_FALSE ZYDIS_NOTMIN(ZYDIS_CATEGORY_MISC) ZYDIS_NOTMIN(ZYDIS_ISA_SET_PPRO) ZYDIS_NOTMIN(ZYDIS_ISA_EXT_BASE) ZYDIS_NOTMIN(ZYDIS_BRANCH_TYPE_NONE) ZYDIS_NOTMIN(ZYDIS_EXCEPTION_CLASS_NONE), ZYDIS_REGKIND_GPR, ZYDIS_REGKIND_GPR ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYDIS_RW_ACTION_NONE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE), ZYAN_FALSE ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) ZYDIS_NOTMIN(ZYAN_FALSE) },
Expand Down

0 comments on commit cb7c691

Please sign in to comment.