mirror of https://github.com/x64dbg/zydis
				
				
				
			Improved decoding of XOP/VEX/EVEX/MVEX instructions
Decoding of XOP/VEX/EVEX/MVEX instructions without a NDS register encoded in .vvvv will now fail, if the .vvvv value is != 1111b
This commit is contained in:
		
							parent
							
								
									e7a7be70e9
								
							
						
					
					
						commit
						55400e9206
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -644,6 +644,10 @@ enum ZydisMaskPolicies | |||
|     uint16_t operandReference               ZYDIS_BITFIELD(15); \ | ||||
|     uint8_t operandSizeMap                  ZYDIS_BITFIELD( 3) | ||||
| 
 | ||||
| #define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR \ | ||||
|     ZYDIS_INSTRUCTION_DEFINITION_BASE; \ | ||||
|     ZydisBool hasNDSOperand                 ZYDIS_BITFIELD( 1) | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief   Defines the @c ZydisInstructionDefinition struct. | ||||
|  */ | ||||
|  | @ -669,23 +673,23 @@ typedef struct ZydisInstructionDefinitionDEFAULT_ | |||
| 
 | ||||
| typedef struct ZydisInstructionDefinition3DNOW_ | ||||
| { | ||||
|     ZydisInstructionDefinition base; | ||||
|     ZYDIS_INSTRUCTION_DEFINITION_BASE; | ||||
| } ZydisInstructionDefinition3DNOW; | ||||
| 
 | ||||
| typedef struct ZydisInstructionDefinitionXOP_ | ||||
| { | ||||
|     ZydisInstructionDefinition base; | ||||
|     ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; | ||||
| } ZydisInstructionDefinitionXOP; | ||||
| 
 | ||||
| typedef struct ZydisInstructionDefinitionVEX_ | ||||
| { | ||||
|     ZYDIS_INSTRUCTION_DEFINITION_BASE; | ||||
|     ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; | ||||
|     ZydisVEXStaticBroadcast broadcast       ZYDIS_BITFIELD(3); | ||||
| } ZydisInstructionDefinitionVEX; | ||||
| 
 | ||||
| typedef struct ZydisInstructionDefinitionEVEX_ | ||||
| { | ||||
|     ZYDIS_INSTRUCTION_DEFINITION_BASE; | ||||
|     ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; | ||||
|     ZydisInternalVectorLength vectorLength  ZYDIS_BITFIELD(2); | ||||
|     ZydisEVEXTupleType tupleType            ZYDIS_BITFIELD(4); | ||||
|     ZydisInternalElementSize elementSize    ZYDIS_BITFIELD(4); | ||||
|  | @ -696,7 +700,7 @@ typedef struct ZydisInstructionDefinitionEVEX_ | |||
| 
 | ||||
| typedef struct ZydisInstructionDefinitionMVEX_ | ||||
| { | ||||
|     ZYDIS_INSTRUCTION_DEFINITION_BASE; | ||||
|     ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; | ||||
|     ZydisMVEXFunctionality functionality    ZYDIS_BITFIELD(5); | ||||
|     ZydisMaskPolicy maskPolicy              ZYDIS_BITFIELD(2); | ||||
|     ZydisBool hasElementGranularity         ZYDIS_BITFIELD(1); | ||||
|  |  | |||
|  | @ -641,6 +641,7 @@ static ZydisStatus ZydisReadDisplacement(ZydisDecoderContext* context, ZydisInst | |||
|     default: | ||||
|         ZYDIS_UNREACHABLE; | ||||
|     } | ||||
| 
 | ||||
|     // TODO: Fix endianess on big-endian systems   
 | ||||
| 
 | ||||
|     return ZYDIS_STATUS_SUCCESS; | ||||
|  | @ -3762,6 +3763,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns | |||
|                 ZydisGetOptionalInstructionParts(node, &optionalParts); | ||||
|                 ZYDIS_CHECK(ZydisDecodeOptionalInstructionParts(context, info, optionalParts)); | ||||
| 
 | ||||
|                 ZydisBool hasNDSOperand = ZYDIS_FALSE; | ||||
|                 ZydisMaskPolicy maskPolicy = ZYDIS_MASK_POLICY_INVALID; | ||||
|                 switch (info->encoding) | ||||
|                 { | ||||
|  | @ -3786,23 +3788,40 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns | |||
|                     break; | ||||
|                 } | ||||
|                 case ZYDIS_INSTRUCTION_ENCODING_XOP: | ||||
|                 case ZYDIS_INSTRUCTION_ENCODING_VEX: | ||||
|                 { | ||||
|                     const ZydisInstructionDefinitionXOP* def =  | ||||
|                         (const ZydisInstructionDefinitionXOP*)definition; | ||||
|                     hasNDSOperand = def->hasNDSOperand; | ||||
|                     break; | ||||
|                 } | ||||
|                 case ZYDIS_INSTRUCTION_ENCODING_VEX: | ||||
|                 { | ||||
|                     const ZydisInstructionDefinitionVEX* def =  | ||||
|                         (const ZydisInstructionDefinitionVEX*)definition; | ||||
|                     hasNDSOperand = def->hasNDSOperand; | ||||
|                     break; | ||||
|                 } | ||||
|                 case ZYDIS_INSTRUCTION_ENCODING_EVEX: | ||||
|                 { | ||||
|                     const ZydisInstructionDefinitionEVEX* def =  | ||||
|                         (const ZydisInstructionDefinitionEVEX*)definition; | ||||
|                     hasNDSOperand = def->hasNDSOperand; | ||||
|                     maskPolicy = def->maskPolicy; | ||||
| 
 | ||||
|                     // TODO: Check for invalid .vvvv value
 | ||||
|                     break; | ||||
|                 } | ||||
|                 case ZYDIS_INSTRUCTION_ENCODING_MVEX: | ||||
|                 { | ||||
|                     const ZydisInstructionDefinitionMVEX* def =  | ||||
|                         (const ZydisInstructionDefinitionMVEX*)definition; | ||||
|                     hasNDSOperand = def->hasNDSOperand; | ||||
|                     maskPolicy = def->maskPolicy; | ||||
|                      | ||||
|                     // Check for invalid MVEX.vvvv value
 | ||||
|                     if (!def->hasNDSOperand && context->cache.v_vvvv) | ||||
|                     { | ||||
|                         return ZYDIS_STATUS_DECODING_ERROR; | ||||
|                     } | ||||
| 
 | ||||
|                     // Check for invalid MVEX.SSS values
 | ||||
|                     static const uint8_t lookup[25][8] = | ||||
|                     { | ||||
|  | @ -3869,6 +3888,12 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisIns | |||
|                     ZYDIS_UNREACHABLE; | ||||
|                 } | ||||
| 
 | ||||
|                 // Check for invalid EVEX.vvvv value
 | ||||
|                 if (!hasNDSOperand && context->cache.v_vvvv) | ||||
|                 { | ||||
|                     return ZYDIS_STATUS_DECODING_ERROR; | ||||
|                 } | ||||
| 
 | ||||
|                 // Check for invalid MASK registers
 | ||||
|                 switch (maskPolicy) | ||||
|                 { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue