From 8063cb7401ae068d3a3a261a33178674646ab6fa Mon Sep 17 00:00:00 2001 From: Alexis Engelke Date: Mon, 31 Dec 2018 13:19:28 +0100 Subject: [PATCH] Decode additional segment prefixes This is mainly needed to handle the new control flow enforcement extensions, making 3E a "notrack" prefix for indirect calls and jumps. This is not (yet) modeled, and requires additional information on the order of the prefixes, as 3E_66 (16-bit in ds segment) has a different meaning than 66_3E (16-bit notrack). Before implementing this, an analysis of the performance impact when decoding more prefix information is probably required to avoid degrading overall performance for very few and (as of now) seldomly used corner cases. --- README.md | 1 + decode.c | 20 ++++++++++++++++++++ decode.h | 2 ++ 3 files changed, 23 insertions(+) diff --git a/README.md b/README.md index 87c9e2a..753e516 100644 --- a/README.md +++ b/README.md @@ -14,5 +14,6 @@ Currently, decoding 32-bit assembly required the `ARCH_386` macro to be defined - The layout of entries in the tables can be improved to improve usage of caches. (Help needed.) - Low test coverage. (Help needed.) - No benchmarking has been performed yet. (Help needed.) +- Prefixes for indirect jumps and calls are not properly decoded, e.g. `notrack`, `bnd`. This requires additional information on the prefix ordering, which is currently not decoded. (Analysis of performance impact and help needed.) If you find any other issues, please report a bug. Or, even better, send a patch fixing the issue. diff --git a/decode.c b/decode.c index df931d4..97bbd99 100644 --- a/decode.c +++ b/decode.c @@ -65,6 +65,14 @@ decode_prefixes(const uint8_t* buffer, int len, PrefixSet* out_prefixes, { prefixes |= PREFIX_SEG_CS; } + else if (prefix == 0x26) + { + prefixes |= PREFIX_SEG_ES; + } + else if (prefix == 0x3E) + { + prefixes |= PREFIX_SEG_DS; + } else if (prefix == 0x64) { prefixes |= PREFIX_SEG_FS; @@ -511,6 +519,18 @@ decode(const uint8_t* buffer, int len, Instr* instr) { instr->segment = RI_GS; } + else if (prefixes & PREFIX_SEG_CS) + { + instr->segment = RI_CS; + } + else if (prefixes & PREFIX_SEG_DS) + { + instr->segment = RI_DS; + } + else if (prefixes & PREFIX_SEG_ES) + { + instr->segment = RI_ES; + } else { instr->segment = RI_DS; diff --git a/decode.h b/decode.h index a8b3172..848fbe0 100644 --- a/decode.h +++ b/decode.h @@ -75,6 +75,8 @@ enum PrefixSet PREFIX_SEG_FS = 1 << 0, PREFIX_SEG_GS = 1 << 1, PREFIX_SEG_CS = 1 << 12, + PREFIX_SEG_DS = 1 << 17, + PREFIX_SEG_ES = 1 << 18, PREFIX_OPSZ = 1 << 2, PREFIX_ADDRSZ = 1 << 3, PREFIX_LOCK = 1 << 4,