From dde61f76f6fa80555fc0e867695302ffa90dbc39 Mon Sep 17 00:00:00 2001 From: mappzor <34216645+mappzor@users.noreply.github.com> Date: Wed, 6 Nov 2024 01:01:29 +0100 Subject: [PATCH] Fixed `movdiri` (APX) and compressed disp8 handling --- src/Encoder.c | 13 +++++++++++-- src/Generated/EncoderTables.inc | 1 - tests/crash_tool.py | 13 +++++++++---- tests/re_enc_test_cases.json | 25 +++++++++++++++++++++++++ tests/zydis_encoder_types.py | 16 ---------------- 5 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/Encoder.c b/src/Encoder.c index c114aa26..4778ac2e 100644 --- a/src/Encoder.c +++ b/src/Encoder.c @@ -1729,7 +1729,16 @@ static ZyanBool ZydisCheckVectorMemorySize(ZydisEncoderInstructionMatch *match, ZyanU16 allowed_mem_size = def_op->size[eosz_index]; if (allowed_mem_size || (match->definition->encoding == ZYDIS_INSTRUCTION_ENCODING_VEX)) { - return user_op->mem.size == allowed_mem_size; + if (user_op->mem.size == allowed_mem_size) + { + return ZYAN_TRUE; + } + if (!match->eosz64_forbidden && (eosz_index == 2)) + { + ZYAN_ASSERT(def_op->size[0] == def_op->size[1]); + return user_op->mem.size == def_op->size[1]; + } + return ZYAN_FALSE; } ZYAN_ASSERT((match->definition->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || (match->definition->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)); @@ -2123,7 +2132,7 @@ static ZyanBool ZydisIsMemoryOperandCompatible(ZydisEncoderInstructionMatch *mat reg_index_class); } } - else if (disp_size != 8 || !match->cd8_scale) + else { const ZyanU8 addr_size = ZydisGetMaxAddressSize(match->request); if (disp_size > addr_size) diff --git a/src/Generated/EncoderTables.inc b/src/Generated/EncoderTables.inc index a5ec6868..8c5cf814 100644 --- a/src/Generated/EncoderTables.inc +++ b/src/Generated/EncoderTables.inc @@ -11746,4 +11746,3 @@ const ZydisEncodableInstruction encoder_instructions[] = { 0x07A3, 0x0000, 0x01, 0xE8, ZYDIS_INSTRUCTION_ENCODING_LEGACY, ZYDIS_OPCODE_MAP_0F, ZYDIS_WIDTH_16 | ZYDIS_WIDTH_32 | ZYDIS_WIDTH_64, ZYDIS_WIDTH_16 | ZYDIS_WIDTH_32 | ZYDIS_WIDTH_64, ZYDIS_WIDTH_16 | ZYDIS_WIDTH_32 | ZYDIS_WIDTH_64, ZYDIS_MANDATORY_PREFIX_F2, ZYAN_FALSE, ZYAN_FALSE, ZYAN_FALSE, ZYAN_FALSE, ZYAN_FALSE, ZYDIS_VECTOR_LENGTH_INVALID, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE }, { 0x07A4, 0x0000, 0x01, 0xD6, ZYDIS_INSTRUCTION_ENCODING_LEGACY, ZYDIS_OPCODE_MAP_0F, ZYDIS_WIDTH_16 | ZYDIS_WIDTH_32 | ZYDIS_WIDTH_64, ZYDIS_WIDTH_16 | ZYDIS_WIDTH_32 | ZYDIS_WIDTH_64, ZYDIS_WIDTH_16 | ZYDIS_WIDTH_32 | ZYDIS_WIDTH_64, ZYDIS_MANDATORY_PREFIX_NONE, ZYAN_FALSE, ZYAN_FALSE, ZYAN_FALSE, ZYAN_FALSE, ZYAN_FALSE, ZYDIS_VECTOR_LENGTH_INVALID, ZYDIS_SIZE_HINT_NONE, ZYAN_FALSE }, }; - diff --git a/tests/crash_tool.py b/tests/crash_tool.py index 6e340a20..c718258b 100644 --- a/tests/crash_tool.py +++ b/tests/crash_tool.py @@ -50,12 +50,16 @@ def get_combined_flags(flag_str, enum_class): return functools.reduce(lambda x, y: x | y, [enum_class[v] for v in flag_str.split('|')]) -def get_disasm(zydis_info, machine_mode, stack_width, payload): +def get_disasm(zydis_info, machine_mode, stack_width, payload, knc=False): if not zydis_info: return '' arg_machine_mode = '-' + get_width_from_enum(machine_mode) arg_stack_width = '-' + get_width_from_enum(stack_width) - proc = Popen([zydis_info, arg_machine_mode, arg_stack_width, payload[:30]], stdout=PIPE, stderr=PIPE) + args = [zydis_info, arg_machine_mode, arg_stack_width] + if knc: + args.append('-knc') + args.append(payload[:30]) + proc = Popen(args, stdout=PIPE, stderr=PIPE) out = proc.communicate()[0].decode('utf-8') if proc.returncode != 0: return '' @@ -176,13 +180,14 @@ def convert_re_enc_crash_to_json(crash, zydis_info, return_dict=False): stack_width = ZydisStackWidth(reader.read_uint32()) decoder_mode = reader.read_uint32() payload = reader.read_bytes().hex().upper() + is_knc = (decoder_mode & ZYDIS_DECODER_MODE_KNC) != 0 test_case = { 'machine_mode': machine_mode.name, 'stack_width': stack_width.name, 'payload': payload, - 'description': get_disasm(zydis_info, machine_mode, stack_width, payload), + 'description': get_disasm(zydis_info, machine_mode, stack_width, payload, is_knc), } - if decoder_mode & ZYDIS_DECODER_MODE_KNC: + if is_knc: test_case['knc'] = True if return_dict: return test_case diff --git a/tests/re_enc_test_cases.json b/tests/re_enc_test_cases.json index 55acd690..f5f856cc 100644 --- a/tests/re_enc_test_cases.json +++ b/tests/re_enc_test_cases.json @@ -913,5 +913,30 @@ "stack_width": "ZYDIS_STACK_WIDTH_64", "payload": "D51087C02300", "description": "xchg r16d, eax" + }, + { + "machine_mode": "ZYDIS_MACHINE_MODE_LONG_64", + "stack_width": "ZYDIS_STACK_WIDTH_64", + "payload": "676262794BBE0C6500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00006F", + "description": "vfnmsub231ps zmm25 {k3}, zmm0, xmmword ptr ds:[0xFFFFFF00] {uint8}", + "knc": true + }, + { + "machine_mode": "ZYDIS_MACHINE_MODE_LONG_64", + "stack_width": "ZYDIS_STACK_WIDTH_64", + "payload": "62DC7C08F90500000002", + "description": "movdiri dword ptr ds:[0x000000000200000A], eax" + }, + { + "machine_mode": "ZYDIS_MACHINE_MODE_LONG_COMPAT_16", + "stack_width": "ZYDIS_STACK_WIDTH_16", + "payload": "C4C3F961E1C4", + "description": "vpcmpestri xmm4, xmm1, 0xC4" + }, + { + "machine_mode": "ZYDIS_MACHINE_MODE_LONG_64", + "stack_width": "ZYDIS_STACK_WIDTH_64", + "payload": "F3660FA7C86239F6", + "description": "rep xcrypt_ecb <- TODO: Remove 0x66 byte after fixing OSIZE handling for XCRYPT" } ] \ No newline at end of file diff --git a/tests/zydis_encoder_types.py b/tests/zydis_encoder_types.py index 3b286eef..176d7bd9 100644 --- a/tests/zydis_encoder_types.py +++ b/tests/zydis_encoder_types.py @@ -2430,22 +2430,6 @@ 'ZYDIS_REGISTER_BND3', 'ZYDIS_REGISTER_BNDCFG', 'ZYDIS_REGISTER_BNDSTATUS', - 'ZYDIS_REGISTER_DFV0', - 'ZYDIS_REGISTER_DFV1', - 'ZYDIS_REGISTER_DFV2', - 'ZYDIS_REGISTER_DFV3', - 'ZYDIS_REGISTER_DFV4', - 'ZYDIS_REGISTER_DFV5', - 'ZYDIS_REGISTER_DFV6', - 'ZYDIS_REGISTER_DFV7', - 'ZYDIS_REGISTER_DFV8', - 'ZYDIS_REGISTER_DFV9', - 'ZYDIS_REGISTER_DFV10', - 'ZYDIS_REGISTER_DFV11', - 'ZYDIS_REGISTER_DFV12', - 'ZYDIS_REGISTER_DFV13', - 'ZYDIS_REGISTER_DFV14', - 'ZYDIS_REGISTER_DFV15', 'ZYDIS_REGISTER_MXCSR', 'ZYDIS_REGISTER_PKRU', 'ZYDIS_REGISTER_XCR0',