decode: Don't walk escape opcodes in tables
This commit is contained in:
34
decode.c
34
decode.c
@@ -83,7 +83,7 @@ decode_prefixes(const uint8_t* buffer, int len, DecodeMode mode,
|
||||
uint8_t rep = 0;
|
||||
*out_mandatory = 0;
|
||||
*out_segment = FD_REG_NONE;
|
||||
*out_opcode_escape = -1;
|
||||
*out_opcode_escape = 0;
|
||||
|
||||
while (LIKELY(off < len))
|
||||
{
|
||||
@@ -373,24 +373,28 @@ fd_decode(const uint8_t* buffer, size_t len_sz, int mode_int, uintptr_t address,
|
||||
|
||||
uint32_t kind = ENTRY_TABLE_ROOT;
|
||||
|
||||
if (LIKELY(!(prefixes & PREFIX_VEX)))
|
||||
if (UNLIKELY(prefixes & PREFIX_VEX))
|
||||
{
|
||||
// "Legacy" walk through table and escape opcodes
|
||||
ENTRY_UNPACK(table, kind, table[0]);
|
||||
if (kind == ENTRY_TABLE256 && LIKELY(off < len))
|
||||
ENTRY_UNPACK(table, kind, table[buffer[off++]]);
|
||||
if (UNLIKELY(kind == ENTRY_TABLE256) && LIKELY(off < len))
|
||||
ENTRY_UNPACK(table, kind, table[buffer[off++]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// VEX/EVEX compact escapes; the prefix precedes the single opcode byte
|
||||
if (opcode_escape < 0 || opcode_escape > 3)
|
||||
return FD_ERR_UD;
|
||||
ENTRY_UNPACK(table, kind, table[4 | opcode_escape]);
|
||||
if (LIKELY(off < len))
|
||||
ENTRY_UNPACK(table, kind, table[buffer[off++]]);
|
||||
opcode_escape |= 4;
|
||||
}
|
||||
else if (buffer[off] == 0x0f)
|
||||
{
|
||||
if (UNLIKELY(off + 1 >= len))
|
||||
return FD_ERR_PARTIAL;
|
||||
if (buffer[off + 1] == 0x38)
|
||||
opcode_escape = 2;
|
||||
else if (buffer[off + 1] == 0x3a)
|
||||
opcode_escape = 3;
|
||||
else
|
||||
opcode_escape = 1;
|
||||
off += opcode_escape >= 2 ? 2 : 1;
|
||||
}
|
||||
|
||||
ENTRY_UNPACK(table, kind, table[opcode_escape]);
|
||||
if (LIKELY(off < len))
|
||||
ENTRY_UNPACK(table, kind, table[buffer[off++]]);
|
||||
|
||||
// Then, walk through ModR/M-encoded opcode extensions.
|
||||
if ((kind == ENTRY_TABLE8 || kind == ENTRY_TABLE72) && LIKELY(off < len))
|
||||
|
||||
@@ -214,16 +214,11 @@ def parse_opcode(opcode_string):
|
||||
opcode = []
|
||||
opcode_bytes = unhexlify(match.group("opcode"))
|
||||
|
||||
# root table, VEX prefix already consumes escape opcode bytes
|
||||
idx = [b"", b"\x0f", b"\x0f\x38", b"\x0f\x3a"].index(opcode_bytes[:-1])
|
||||
if match.group("vex"):
|
||||
idx = [b"", b"\x0f", b"\x0f\x38", b"\x0f\x3a"].index(opcode_bytes[:-1])
|
||||
opcode.append((EntryKind.TABLE_ROOT, [4 | idx]))
|
||||
opcode_bytes = opcode_bytes[-1:]
|
||||
else:
|
||||
opcode.append((EntryKind.TABLE_ROOT, [0]))
|
||||
|
||||
# normal opcode bytes
|
||||
opcode += [(EntryKind.TABLE256, [x]) for x in opcode_bytes]
|
||||
idx |= 4
|
||||
opcode.append((EntryKind.TABLE_ROOT, [idx]))
|
||||
opcode.append((EntryKind.TABLE256, [opcode_bytes[-1]]))
|
||||
|
||||
opcext = match.group("modrm")
|
||||
if opcext:
|
||||
|
||||
Reference in New Issue
Block a user