Correctly handle mis-placed REX prefix
This commit is contained in:
26
decode.c
26
decode.c
@@ -81,6 +81,8 @@ decode_prefixes(const uint8_t* buffer, int len, DecodeMode mode,
|
|||||||
{
|
{
|
||||||
int off = 0;
|
int off = 0;
|
||||||
PrefixSet prefixes = 0;
|
PrefixSet prefixes = 0;
|
||||||
|
PrefixSet rex_prefix = 0;
|
||||||
|
int rex_off = -1;
|
||||||
|
|
||||||
uint8_t rep = 0;
|
uint8_t rep = 0;
|
||||||
*out_mandatory = 0;
|
*out_mandatory = 0;
|
||||||
@@ -111,18 +113,16 @@ decode_prefixes(const uint8_t* buffer, int len, DecodeMode mode,
|
|||||||
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45:
|
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45:
|
||||||
case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b:
|
case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b:
|
||||||
case 0x4c: case 0x4d: case 0x4e: case 0x4f:
|
case 0x4c: case 0x4d: case 0x4e: case 0x4f:
|
||||||
if (mode == DECODE_64)
|
if (mode != DECODE_64)
|
||||||
{
|
|
||||||
prefixes |= PREFIX_REX;
|
|
||||||
prefixes |= prefix & 0x1 ? PREFIX_REXB : 0;
|
|
||||||
prefixes |= prefix & 0x2 ? PREFIX_REXX : 0;
|
|
||||||
prefixes |= prefix & 0x4 ? PREFIX_REXR : 0;
|
|
||||||
prefixes |= prefix & 0x8 ? PREFIX_REXW : 0;
|
|
||||||
off++;
|
|
||||||
}
|
|
||||||
// If in 64-bit mode, the REX prefix is always the last prefix. In
|
|
||||||
// 32-bit mode these are regular opcodes, so exit without consuming.
|
|
||||||
goto out;
|
goto out;
|
||||||
|
rex_prefix |= PREFIX_REX;
|
||||||
|
rex_prefix |= prefix & 0x1 ? PREFIX_REXB : 0;
|
||||||
|
rex_prefix |= prefix & 0x2 ? PREFIX_REXX : 0;
|
||||||
|
rex_prefix |= prefix & 0x4 ? PREFIX_REXR : 0;
|
||||||
|
rex_prefix |= prefix & 0x8 ? PREFIX_REXW : 0;
|
||||||
|
rex_off = off;
|
||||||
|
off++;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 0xc4: case 0xc5: // VEX
|
case 0xc4: case 0xc5: // VEX
|
||||||
if (UNLIKELY(off + 1 >= len))
|
if (UNLIKELY(off + 1 >= len))
|
||||||
@@ -169,6 +169,10 @@ decode_prefixes(const uint8_t* buffer, int len, DecodeMode mode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
// REX prefix is only considered if it is the last prefix.
|
||||||
|
if (rex_off == off - 1)
|
||||||
|
prefixes |= rex_prefix;
|
||||||
|
|
||||||
// If there is no REP/REPNZ prefix and implied opcode extension from a VEX
|
// If there is no REP/REPNZ prefix and implied opcode extension from a VEX
|
||||||
// prefix, offer 66h as mandatory prefix. If there is a REP prefix, then the
|
// prefix, offer 66h as mandatory prefix. If there is a REP prefix, then the
|
||||||
// 66h prefix is ignored when evaluating mandatory prefixes.
|
// 66h prefix is ignored when evaluating mandatory prefixes.
|
||||||
|
|||||||
Reference in New Issue
Block a user