From cf8d1be15fd1fcd6125551e45a2eec677aff7d1f Mon Sep 17 00:00:00 2001 From: Alexis Engelke Date: Tue, 23 Mar 2021 13:25:30 +0100 Subject: [PATCH] encode: Fix erroneous encoding of SREG push/pop --- encode.c | 6 ++++-- tests/test_encode.c | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/encode.c b/encode.c index 24c5d4d..dca28e8 100644 --- a/encode.c +++ b/encode.c @@ -348,6 +348,10 @@ fe_enc64_impl(uint8_t** restrict buf, uint64_t mnem, FeOp op0, FeOp op1, opc |= OPC_67; if (UNLIKELY(mnem & FE_SEG_MASK)) opc |= (mnem & FE_SEG_MASK) << (OPC_SEG_IDX - 16); + if (UNLIKELY(desc->enc == ENC_S)) { + if ((op_reg_idx(op0) << 3 & 0x20) != (opc & 0x20)) goto next; + opc |= op_reg_idx(op0) << 3; + } if (ei->immctl > 0) { imm = ops[ei->immidx]; @@ -372,8 +376,6 @@ fe_enc64_impl(uint8_t** restrict buf, uint64_t mnem, FeOp op0, FeOp op1, if (enc_mr(buf, opc, ops[ei->modrm^3], modreg, desc->immsz)) goto fail; } else if (ei->modreg) { if (enc_o(buf, opc, ops[ei->modreg^3])) goto fail; - } else if (UNLIKELY(desc->enc == ENC_S)) { - if (enc_opc(buf, opc | (op_reg_idx(op0) << 3))) goto fail; } else { if (enc_opc(buf, opc)) goto fail; } diff --git a/tests/test_encode.c b/tests/test_encode.c index 26eef16..d823501 100644 --- a/tests/test_encode.c +++ b/tests/test_encode.c @@ -70,6 +70,14 @@ main(int argc, char** argv) TEST("\x54", FE_PUSHr, FE_SP); TEST("\x41\x57", FE_PUSHr, FE_R15); TEST("\x41\x50", FE_PUSHr, FE_R8); + TEST("", FE_PUSHr, FE_ES); + TEST("", FE_PUSH16r, FE_ES); + TEST("", FE_PUSHr, FE_CS); + TEST("", FE_PUSH16r, FE_CS); + TEST("", FE_PUSHr, FE_SS); + TEST("", FE_PUSH16r, FE_SS); + TEST("", FE_PUSHr, FE_DS); + TEST("", FE_PUSH16r, FE_DS); TEST("\x0f\xa0", FE_PUSHr, FE_FS); TEST("\x66\x0f\xa0", FE_PUSH16r, FE_FS); TEST("\x0f\xa8", FE_PUSHr, FE_GS);