Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed xsha1/xsha256 workaround #537

Merged
merged 2 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion include/Zydis/Internal/EncoderData.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,25 @@ typedef enum ZydisSizeHint_
ZYDIS_SIZE_HINT_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SIZE_HINT_MAX_VALUE)
} ZydisSizeHint;

/**
* Used in encoder's table to indicate `REX2` prefix support type.
*/
typedef enum ZydisRex2Type_
{
ZYDIS_REX2_TYPE_FORBIDDEN,
ZYDIS_REX2_TYPE_ALLOWED,
ZYDIS_REX2_TYPE_MANDATORY,

/**
* Maximum value of this enum.
*/
ZYDIS_REX2_TYPE_MAX_VALUE = ZYDIS_REX2_TYPE_MANDATORY,
/**
* The minimum number of bits required to represent all values of this enum.
*/
ZYDIS_REX2_TYPE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_REX2_TYPE_MAX_VALUE)
} ZydisRex2Type;

/**
* Used in encoder's primary lookup table which allows to access a set of instruction definitions
* for specified mnemonic in constant time.
Expand Down Expand Up @@ -183,7 +202,7 @@ typedef struct ZydisEncodableInstruction_
/**
* True if `REX2` prefix is required for this definition.
*/
ZyanU8 rex2 ZYAN_BITFIELD(1);
ZyanU8 rex2 ZYAN_BITFIELD(ZYDIS_REX2_TYPE_REQUIRED_BITS);
/**
* True if `EEVEX.ND` is required for this definition.
*/
Expand Down
60 changes: 3 additions & 57 deletions src/Encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,59 +721,6 @@ static ZyanBool ZydisCheckAsz(ZydisEncoderInstructionMatch *match, ZydisRegister
return match->easz == (ZyanU8)reg_width ? ZYAN_TRUE : ZYAN_FALSE;
}

/**
* Checks if opcode is allowed to use `REX2` prefix.
*
* @param match A pointer to `ZydisEncoderInstructionMatch` struct.
*
* @return True if `REX2` prefix can be used, false otherwise.
*/
static ZyanBool ZydisIsRex2Allowed(ZydisEncoderInstructionMatch *match)
{
// TODO: Remove this function, use `no_rex2` filter
const ZydisOpcodeMap opcode_map = match->definition->opcode_map;
if ((opcode_map != ZYDIS_OPCODE_MAP_DEFAULT) &&
(opcode_map != ZYDIS_OPCODE_MAP_0F))
{
return ZYAN_FALSE;
}
switch (match->request->mnemonic)
{
case ZYDIS_MNEMONIC_XRSTOR:
case ZYDIS_MNEMONIC_XRSTOR64:
case ZYDIS_MNEMONIC_XRSTORS:
case ZYDIS_MNEMONIC_XRSTORS64:
case ZYDIS_MNEMONIC_XSAVE:
case ZYDIS_MNEMONIC_XSAVE64:
case ZYDIS_MNEMONIC_XSAVEC:
case ZYDIS_MNEMONIC_XSAVEC64:
case ZYDIS_MNEMONIC_XSAVEOPT:
case ZYDIS_MNEMONIC_XSAVEOPT64:
case ZYDIS_MNEMONIC_XSAVES:
case ZYDIS_MNEMONIC_XSAVES64:
return ZYAN_FALSE;
default:
break;
}
static const ZyanBool is_rex2_allowed[2][16] =
{
{
ZYAN_TRUE, ZYAN_TRUE, ZYAN_TRUE, ZYAN_TRUE,
ZYAN_FALSE, ZYAN_TRUE, ZYAN_TRUE, ZYAN_FALSE,
ZYAN_TRUE, ZYAN_TRUE, ZYAN_FALSE, ZYAN_TRUE,
ZYAN_TRUE, ZYAN_TRUE, ZYAN_FALSE, ZYAN_TRUE,
},
{
ZYAN_TRUE, ZYAN_TRUE, ZYAN_TRUE, ZYAN_FALSE,
ZYAN_TRUE, ZYAN_TRUE, ZYAN_TRUE, ZYAN_TRUE,
ZYAN_FALSE, ZYAN_TRUE, ZYAN_TRUE, ZYAN_TRUE,
ZYAN_TRUE, ZYAN_TRUE, ZYAN_TRUE, ZYAN_TRUE,
},
};
const ZyanU8 row = (match->definition->opcode & 0xF0) >> 4;
return is_rex2_allowed[opcode_map][row];
}

/**
* Returns the id of the specified register as used in physical encoding.
*
Expand Down Expand Up @@ -833,7 +780,7 @@ static ZyanBool ZydisIsRegisterAllowed(ZydisEncoderInstructionMatch *match, Zydi
case ZYDIS_REGCLASS_GPR16:
case ZYDIS_REGCLASS_GPR32:
case ZYDIS_REGCLASS_GPR64:
return ZydisIsRex2Allowed(match) ||
return (match->definition->rex2 != ZYDIS_REX2_TYPE_FORBIDDEN) ||
(ZydisGetPhysicalId(reg, reg_class) < 16);
default:
return reg_id < 16;
Expand Down Expand Up @@ -989,8 +936,7 @@ static ZyanBool ZydisIsValidAddressingClass(ZydisEncoderInstructionMatch *match,
switch (match->definition->encoding)
{
case ZYDIS_INSTRUCTION_ENCODING_LEGACY:
result &=
ZydisIsRex2Allowed(match);
result &= (match->definition->rex2 != ZYDIS_REX2_TYPE_FORBIDDEN);
break;
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
break;
Expand Down Expand Up @@ -4157,7 +4103,7 @@ static ZyanStatus ZydisBuildInstruction(ZydisEncoderInstructionMatch *match,
{
instruction->attributes |= ZYDIS_ATTRIB_HAS_MODRM;
}
if (match->definition->rex2)
if (match->definition->rex2 == ZYDIS_REX2_TYPE_MANDATORY)
{
instruction->attributes |= ZYDIS_ATTRIB_HAS_REX2;
}
Expand Down
Loading
Loading