From e7dec7baa9c6649d71e1b349d93dce6b0cd588bf Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 19 Dec 2021 11:23:18 -0800 Subject: fix incorrect memory size for f30f1e-style nop not only did the instruction have wrong data, but if displayed, the formatter would panic. --- CHANGELOG | 2 ++ src/long_mode/mod.rs | 1 + src/protected_mode/mod.rs | 1 + src/real_mode/mod.rs | 1 + test/long_mode/mod.rs | 1 + test/protected_mode/mod.rs | 1 + test/real_mode/mod.rs | 1 + 7 files changed, 8 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 3d65e60..69974fe 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ * fix reachable unsoundness via `RegSpec` helper functions - helpers should only permit creating valid `RegSpec` structs, but three helpers would permit out-of-range register numbers - when displaying an invalid `RegSpec`, for some out-of-range mask registers, the displayed register name could be chosen as arbitrary const data interpreted as a pointer/length pair +* fix incorrect (non-present!) memory size for f30f1e-style `nop`. + - this would decode without error, but produce an instruction with memory operand and memory size of `0`. if formatted, yaxpeax-x86 panics. ## 1.1.2 * fix panic when evex instructions with compressed displacements are decoded in diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 7e8dff7..44cf992 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -8854,6 +8854,7 @@ fn unlikely_operands< }; instruction.operands[1] = OperandSpec::RegRRR; instruction.operands[0] = read_E(words, instruction, modrm, sz, sink)?; + instruction.mem_size = sz; instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, instruction.prefixes.rex_unchecked().r(), bank); instruction.operand_count = 2; diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index 9c03faf..040a23e 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -8800,6 +8800,7 @@ fn unlikely_operands< }; instruction.operands[1] = OperandSpec::RegRRR; instruction.operands[0] = read_E(words, instruction, modrm, sz, sink)?; + instruction.mem_size = sz; instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, bank); instruction.operand_count = 2; diff --git a/src/real_mode/mod.rs b/src/real_mode/mod.rs index 74e1c37..0a66ab9 100644 --- a/src/real_mode/mod.rs +++ b/src/real_mode/mod.rs @@ -8804,6 +8804,7 @@ fn unlikely_operands< }; instruction.operands[1] = OperandSpec::RegRRR; instruction.operands[0] = read_E(words, instruction, modrm, sz, sink)?; + instruction.mem_size = sz; instruction.regs[0] = RegSpec::from_parts((modrm >> 3) & 7, bank); instruction.operand_count = 2; diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index 0bef224..97e9a74 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -3396,6 +3396,7 @@ fn from_reports() { // negative compressed evex displacements should not overflow and panic test_display(&[0x62, 0xf2, 0x6d, 0xac, 0x00, 0x59, 0xa7], "vpshufb ymm3{k4}{z}, ymm2, ymmword [rcx - 0xb20]"); test_display(&[0x62, 0xf2, 0xfd, 0x0f, 0x8a, 0x62, 0xf2], "vcompresspd xmmword [rdx - 0x70]{k7}, xmm4"); + test_display(&[0xf3, 0x0f, 0x1e, 0x0f], "nop dword [rdi], ecx"); } mod reg_masks { diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index 9f34019..744d006 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -3083,6 +3083,7 @@ fn from_reports() { // negative compressed evex displacements should not overflow and panic test_display(&[0x62, 0xf2, 0x6d, 0xac, 0x00, 0x59, 0xa7], "vpshufb ymm3{k4}{z}, ymm2, ymmword [ecx - 0xb20]"); test_display(&[0x62, 0xf2, 0xfd, 0x0f, 0x8a, 0x62, 0xf2], "vcompresspd xmmword [edx - 0x70]{k7}, xmm4"); + test_display(&[0xf3, 0x0f, 0x1e, 0x0f], "nop dword [edi], ecx"); } mod reg_masks { diff --git a/test/real_mode/mod.rs b/test/real_mode/mod.rs index bf2ae8c..60f4c47 100644 --- a/test/real_mode/mod.rs +++ b/test/real_mode/mod.rs @@ -18368,6 +18368,7 @@ fn from_reports() { // negative compressed evex displacements should not overflow and panic test_display(&[0x62, 0xf2, 0x6d, 0xac, 0x00, 0x59, 0xa7], "vpshufb ymm3{k4}{z}, ymm2, ymmword [bx + di - 0xb20]"); test_display(&[0x62, 0xf2, 0xfd, 0x0f, 0x8a, 0x62, 0xf2], "vcompresspd xmmword [bp + si - 0x70]{k7}, xmm4"); + test_display(&[0xf3, 0x0f, 0x1e, 0x0f], "nop word [bx], cx"); } mod reg_masks { -- cgit v1.1