From 73069b8e390559585d68d14cfb3124d3c1ba1ded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:34:14 +0300 Subject: [PATCH] Give the encode table an explicit operand index for control flow target --- zasm/src/zasm/src/encoder/encoder.cpp | 64 +++++++++++++++------------ 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/zasm/src/zasm/src/encoder/encoder.cpp b/zasm/src/zasm/src/encoder/encoder.cpp index 579dfd9..4f123ee 100644 --- a/zasm/src/zasm/src/encoder/encoder.cpp +++ b/zasm/src/zasm/src/encoder/encoder.cpp @@ -33,11 +33,19 @@ namespace zasm static constexpr std::int32_t kHintRequiresSize = -1; + static constexpr auto kAllowedEncodingX86 = static_cast( + ZYDIS_ENCODABLE_ENCODING_LEGACY | ZYDIS_ENCODABLE_ENCODING_3DNOW); + + static constexpr auto kAllowedEncodingX64 = static_cast( + ZYDIS_ENCODABLE_ENCODING_LEGACY | ZYDIS_ENCODABLE_ENCODING_3DNOW | ZYDIS_ENCODABLE_ENCODING_XOP + | ZYDIS_ENCODABLE_ENCODING_VEX | ZYDIS_ENCODABLE_ENCODING_EVEX); + struct EncodeVariantsInfo { bool isControlFlow{}; std::int8_t encodeSizeRel8{ -1 }; std::int8_t encodeSizeRel32{ -1 }; + std::int8_t cfOperandIndex{ -1 }; constexpr bool canEncodeRel8() const noexcept { @@ -55,32 +63,30 @@ namespace zasm std::array data{}; // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers) - data[ZYDIS_MNEMONIC_JMP] = EncodeVariantsInfo{ true, 2, 5 }; - data[ZYDIS_MNEMONIC_JB] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JBE] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JCXZ] = EncodeVariantsInfo{ true, 2, -1 }; - data[ZYDIS_MNEMONIC_JECXZ] = EncodeVariantsInfo{ true, 2, -1 }; - data[ZYDIS_MNEMONIC_JKNZD] = EncodeVariantsInfo{ true, 2, 5 }; - data[ZYDIS_MNEMONIC_JKZD] = EncodeVariantsInfo{ true, 2, 5 }; - data[ZYDIS_MNEMONIC_JRCXZ] = EncodeVariantsInfo{ true, 2, -1 }; - data[ZYDIS_MNEMONIC_JL] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JLE] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JNB] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JNBE] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JNL] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JNLE] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JNO] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JNP] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JNS] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JNZ] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JO] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JP] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JS] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_JZ] = EncodeVariantsInfo{ true, 2, 6 }; - data[ZYDIS_MNEMONIC_LOOP] = EncodeVariantsInfo{ true, 2, -1 }; - data[ZYDIS_MNEMONIC_LOOPE] = EncodeVariantsInfo{ true, 2, -1 }; - data[ZYDIS_MNEMONIC_LOOPNE] = EncodeVariantsInfo{ true, 2, -1 }; - data[ZYDIS_MNEMONIC_CALL] = EncodeVariantsInfo{ true, -1, 5 }; + data[ZYDIS_MNEMONIC_JMP] = EncodeVariantsInfo{ true, 2, 5, 0 }; + data[ZYDIS_MNEMONIC_JB] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JBE] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JCXZ] = EncodeVariantsInfo{ true, 2, -1, 0 }; + data[ZYDIS_MNEMONIC_JECXZ] = EncodeVariantsInfo{ true, 2, -1, 0 }; + data[ZYDIS_MNEMONIC_JRCXZ] = EncodeVariantsInfo{ true, 2, -1, 0 }; + data[ZYDIS_MNEMONIC_JL] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JLE] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JNB] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JNBE] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JNL] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JNLE] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JNO] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JNP] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JNS] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JNZ] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JO] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JP] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JS] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_JZ] = EncodeVariantsInfo{ true, 2, 6, 0 }; + data[ZYDIS_MNEMONIC_LOOP] = EncodeVariantsInfo{ true, 2, -1, 0 }; + data[ZYDIS_MNEMONIC_LOOPE] = EncodeVariantsInfo{ true, 2, -1, 0 }; + data[ZYDIS_MNEMONIC_LOOPNE] = EncodeVariantsInfo{ true, 2, -1, 0 }; + data[ZYDIS_MNEMONIC_CALL] = EncodeVariantsInfo{ true, -1, 5, 0 }; // NOLINTEND(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers) return data; @@ -234,7 +240,7 @@ namespace zasm } // Check if this operand is used as the control flow target. - if (state.operandIndex == 0 && encodeInfo.isControlFlow) + if (encodeInfo.isControlFlow && state.operandIndex == encodeInfo.cfOperandIndex) { const auto targetAddress = labelVA.has_value() ? *labelVA : immValue; @@ -289,7 +295,7 @@ namespace zasm // Check if this operand is used as the control flow target. const auto& encodeInfo = getEncodeVariantInfo(state.req.mnemonic); - if (state.operandIndex == 0 && encodeInfo.isControlFlow) + if (encodeInfo.isControlFlow && state.operandIndex == encodeInfo.cfOperandIndex) { const auto targetAddress = immValue; const auto [addrRel, branchType] = processRelAddress(encodeInfo, ctx, targetAddress); @@ -533,10 +539,12 @@ namespace zasm if (mode == MachineMode::AMD64) { req.machine_mode = ZYDIS_MACHINE_MODE_LONG_64; + req.allowed_encodings = kAllowedEncodingX64; } else if (mode == MachineMode::I386) { req.machine_mode = ZYDIS_MACHINE_MODE_LONG_COMPAT_32; + req.allowed_encodings = kAllowedEncodingX86; } req.mnemonic = static_cast(mnemonic.value()); req.prefixes = getAttribs(attribs);