Skip to content

Commit

Permalink
Improved size prediction for multiple BND scenarios
Browse files Browse the repository at this point in the history
  • Loading branch information
mappzor authored and athre0z committed Dec 5, 2023
1 parent 7694f90 commit 0068617
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 14 deletions.
4 changes: 4 additions & 0 deletions include/Zydis/Internal/EncoderData.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ typedef struct ZydisEncoderRelInfo_
* True if instruction accepts branch hint prefixes.
*/
ZyanBool accepts_branch_hints;
/**
* True if instruction accepts bound (`BND`) prefix.
*/
ZyanBool accepts_bound;
} ZydisEncoderRelInfo;

/**
Expand Down
16 changes: 13 additions & 3 deletions src/Encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -4373,10 +4373,20 @@ ZYDIS_EXPORT ZyanStatus ZydisEncoderEncodeInstructionAbsolute(ZydisEncoderReques
}
if ((rel_info->accepts_branch_hints) &&
(request->prefixes & (ZYDIS_ATTRIB_HAS_BRANCH_NOT_TAKEN |
ZYDIS_ATTRIB_HAS_BRANCH_TAKEN |
ZYDIS_ATTRIB_HAS_BND)))
ZYDIS_ATTRIB_HAS_BRANCH_TAKEN)))
{
extra_length = 1;
extra_length += 1;
}
if ((rel_info->accepts_bound) && (request->prefixes & ZYDIS_ATTRIB_HAS_BND))
{
extra_length += 1;
// `BND` prefix is not accepted for short `JMP` (Intel SDM Vol. 1)
if ((request->mnemonic == ZYDIS_MNEMONIC_JMP) &&
(request->branch_type == ZYDIS_BRANCH_TYPE_NONE) &&
(request->branch_width == ZYDIS_BRANCH_WIDTH_NONE))
{
start_offset = 1;
}
}
if (request->branch_width == ZYDIS_BRANCH_WIDTH_NONE)
{
Expand Down
18 changes: 9 additions & 9 deletions src/Generated/GetRelInfo.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ const ZydisEncoderRelInfo *ZydisGetRelInfo(ZydisMnemonic mnemonic)
{
static const ZydisEncoderRelInfo info_lookup[9] =
{
{ { { 0, 3, 6 }, { 0, 4, 5 }, { 0, 0, 5 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE },
{ { { 2, 4, 7 }, { 2, 5, 6 }, { 2, 0, 6 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_TRUE },
{ { { 2, 0, 0 }, { 3, 0, 0 }, { 0, 0, 0 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE },
{ { { 3, 0, 0 }, { 2, 0, 0 }, { 3, 0, 0 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE },
{ { { 0, 0, 0 }, { 0, 0, 0 }, { 5, 0, 7 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE },
{ { { 2, 3, 6 }, { 2, 4, 5 }, { 2, 0, 5 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE },
{ { { 0, 0, 0 }, { 0, 0, 0 }, { 2, 0, 0 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE },
{ { { 2, 0, 0 }, { 2, 0, 0 }, { 2, 0, 0 } }, ZYDIS_SIZE_HINT_ASZ, ZYAN_FALSE },
{ { { 0, 4, 7 }, { 0, 5, 6 }, { 0, 5, 6 } }, ZYDIS_SIZE_HINT_OSZ, ZYAN_FALSE },
{ { { 0, 3, 6 }, { 0, 4, 5 }, { 0, 0, 5 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE, ZYAN_TRUE },
{ { { 2, 4, 7 }, { 2, 5, 6 }, { 2, 0, 6 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_TRUE, ZYAN_TRUE },
{ { { 2, 0, 0 }, { 3, 0, 0 }, { 0, 0, 0 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE, ZYAN_FALSE },
{ { { 3, 0, 0 }, { 2, 0, 0 }, { 3, 0, 0 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE, ZYAN_FALSE },
{ { { 0, 0, 0 }, { 0, 0, 0 }, { 5, 0, 7 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE, ZYAN_FALSE },
{ { { 2, 3, 6 }, { 2, 4, 5 }, { 2, 0, 5 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE, ZYAN_TRUE },
{ { { 0, 0, 0 }, { 0, 0, 0 }, { 2, 0, 0 } }, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE, ZYAN_FALSE },
{ { { 2, 0, 0 }, { 2, 0, 0 }, { 2, 0, 0 } }, ZYDIS_SIZE_HINT_ASZ, ZYAN_FALSE, ZYAN_FALSE },
{ { { 0, 4, 7 }, { 0, 5, 6 }, { 0, 5, 6 } }, ZYDIS_SIZE_HINT_OSZ, ZYAN_FALSE, ZYAN_FALSE },
};

switch (mnemonic)
Expand Down
11 changes: 9 additions & 2 deletions tools/ZydisTestEncoderAbsolute.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,14 @@ static ZyanBool RunBranchingTests(void)
0,
ZYDIS_ATTRIB_HAS_BRANCH_TAKEN,
ZYDIS_ATTRIB_HAS_BND,
ZYDIS_ATTRIB_HAS_BRANCH_NOT_TAKEN | ZYDIS_ATTRIB_HAS_BND,
};
static const char *str_prefixes[] =
{
"P00",
"PBT",
"PBN",
"PBD",
"PBN+PBD",
};
static const ZydisAddressSizeHint address_hints[] =
{
Expand Down Expand Up @@ -285,7 +287,12 @@ static ZyanBool RunBranchingTests(void)

const ZydisEncoderRelInfo *rel_info = ZydisGetRelInfo(mnemonic);
ZYAN_ASSERT(rel_info);
if (!rel_info->accepts_branch_hints && iter_branches[5].value != 0)
if ((!rel_info->accepts_branch_hints) && (prefix & (ZYDIS_ATTRIB_HAS_BRANCH_TAKEN |
ZYDIS_ATTRIB_HAS_BRANCH_NOT_TAKEN)))
{
continue;
}
if ((!rel_info->accepts_bound) && (prefix & ZYDIS_ATTRIB_HAS_BND))
{
continue;
}
Expand Down

0 comments on commit 0068617

Please sign in to comment.