From e89f56289ddc81a1127ac08efd7c983c24e8a619 Mon Sep 17 00:00:00 2001 From: Andrei Vlad LUTAS Date: Tue, 17 Nov 2020 10:36:26 +0200 Subject: [PATCH] As per Intel SDM version 73 released in November 2020, make sure we don't decode 32-bit EVEX instructions that have EVEX.V' cleared, and 64-bit EVEX instructions that don't use EVEX.V' field, but have it cleared. --- bddisasm/bddisasm.c | 17 +++++++++++++---- inc/disasmstatus.h | 1 + inc/version.h | 2 +- pybddisasm/setup.py | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/bddisasm/bddisasm.c b/bddisasm/bddisasm.c index 60decb4..e87445c 100644 --- a/bddisasm/bddisasm.c +++ b/bddisasm/bddisasm.c @@ -640,7 +640,7 @@ NdFetchEvex( // Do EVEX validations outside 64 bits mode. if (ND_CODE_64 != Instrux->DefCode) { - // Evex.R and Evex.X must be 1. If they're not, we have BOUND instruction. This is checkked in the + // Evex.R and Evex.X must be 1. If they're not, we have BOUND instruction. This is checked in the // first if. Note that they are inverted inside the Evex prefix. Instrux->Exs.r = 0; Instrux->Exs.x = 0; @@ -654,8 +654,11 @@ NdFetchEvex( // High bit inside Evex.VVVV is ignored, so we force it to 0. Instrux->Exs.v &= 0x7; - // Evex.V' is ignored. - Instrux->Exs.vp = 0; + // Evex.V' must be 1 (negated to 0) in 32-bit mode. + if (Instrux->Exs.vp == 1) + { + return ND_STATUS_BAD_EVEX_V_PRIME; + } } // Update Instrux length & offset, and make sure we don't exceed 15 bytes. @@ -3775,12 +3778,18 @@ NdValidateInstruction( // VEX/EVEX validations. if (ND_ENCM_LEGACY != Instrux->EncMode) { - // Instructions that don't use VEX/XOP vvvv field must set it to 1111b/0, otherwise a #UD will be generated. + // Instructions that don't use VEX/XOP/EVEX vvvv field must set it to 1111b/0, otherwise a #UD will be generated. if ((0 == (Instrux->OperandsEncodingMap & (1 << ND_OPE_V))) && (0 != Instrux->Exs.v)) { return ND_STATUS_VEX_VVVV_MUST_BE_ZERO; } + // Instruction that don't use EVEX.V' field must set to to 1b/0, otherwise a #UD will be generated. + if ((0 == (Instrux->OperandsEncodingMap & (1 << ND_OPE_V))) && !ND_HAS_VSIB(Instrux) && (0 != Instrux->Exs.vp)) + { + return ND_STATUS_BAD_EVEX_V_PRIME; + } + // Some instructions don't support 128 bit vectors. if ((ND_VECM_128 == Instrux->EfVecMode) && (0 != (Instrux->Attributes & ND_FLAG_NOL0))) { diff --git a/inc/disasmstatus.h b/inc/disasmstatus.h index 38e45e7..8d4609b 100644 --- a/inc/disasmstatus.h +++ b/inc/disasmstatus.h @@ -43,6 +43,7 @@ typedef unsigned int NDSTATUS; #define ND_STATUS_ZEROING_ON_MEMORY 0x80000037 // Zeroing on memory. #define ND_STATUS_ZEROING_NO_MASK 0x80000038 // Zeroing without masking. #define ND_STATUS_BROADCAST_NOT_SUPPORTED 0x80000039 // Broadcast not supported. +#define ND_STATUS_BAD_EVEX_V_PRIME 0x80000040 // EVEX.V' field must be one (negated 0). // Not encoding specific. #define ND_STATUS_INVALID_PARAMETER 0x80000100 // An invalid parameter was provided. diff --git a/inc/version.h b/inc/version.h index e2673c4..2be1746 100644 --- a/inc/version.h +++ b/inc/version.h @@ -7,6 +7,6 @@ #define DISASM_VERSION_MAJOR 1 #define DISASM_VERSION_MINOR 31 -#define DISASM_VERSION_REVISION 3 +#define DISASM_VERSION_REVISION 4 #endif // DISASM_VER_H diff --git a/pybddisasm/setup.py b/pybddisasm/setup.py index 6388350..7f32fbd 100644 --- a/pybddisasm/setup.py +++ b/pybddisasm/setup.py @@ -12,7 +12,7 @@ from setuptools import find_packages, setup, Command, Extension, Distribution from codecs import open VERSION = (0, 1, 3) -LIBRARY_VERSION = (1, 31, 3) +LIBRARY_VERSION = (1, 31, 4) LIBRARY_INSTRUX_SIZE = 864 packages = ['pybddisasm']