* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE.
/** * Defines the `ZydisDecoderState` struct.
*/ typedefstruct ZydisDecoderState_
{ /** * A pointer to the `ZydisDecoder` instance.
*/ const ZydisDecoder* decoder; /** * A pointer to the `ZydisDecoderContext` struct.
*/
ZydisDecoderContext* context; /** * The input buffer.
*/ const ZyanU8* buffer; /** * The input buffer length.
*/
ZyanUSize buffer_len; /** * Prefix information.
*/ struct
{ /** * Signals, if the instruction has a `LOCK` prefix (`F0`). * * This prefix originally belongs to group 1, but separating it from the other ones makes * parsing easier for us later.
*/
ZyanBool has_lock; /** * The effective prefix of group 1 (either `F2` or `F3`).
*/
ZyanU8 group1; /** * The effective prefix of group 2 (`2E`, `36`, `3E`, `26`, `64` or `65`).
*/
ZyanU8 group2; /** * The effective segment prefix.
*/
ZyanU8 effective_segment; /** * The prefix that should be treated as the mandatory-prefix, if the * current instruction needs one. * * The last `F3`/`F2` prefix has precedence over previous ones and * `F3`/`F2` in general have precedence over `66`.
*/
ZyanU8 mandatory_candidate; /** * The offset of the effective `LOCK` prefix.
*/
ZyanU8 offset_lock; /** * The offset of the effective prefix in group 1.
*/
ZyanU8 offset_group1; /** * The offset of the effective prefix in group 2.
*/
ZyanU8 offset_group2; /** * The offset of the operand-size override prefix (`66`). * * This is the only prefix in group 3.
*/
ZyanU8 offset_osz_override; /** * The offset of the address-size override prefix (`67`). * * This is the only prefix in group 4.
*/
ZyanU8 offset_asz_override; /** * The offset of the effective segment prefix.
*/
ZyanU8 offset_segment; /** * The offset of the mandatory-candidate prefix.
*/
ZyanU8 offset_mandatory; /** * The offset of a possible `CET` `no-lock` prefix.
*/
ZyanI8 offset_notrack;
} prefixes;
} ZydisDecoderState;
/** * Defines the `ZydisRegisterEncoding` enum.
*/ typedefenum ZydisRegisterEncoding_
{
ZYDIS_REG_ENCODING_INVALID, /** * The register-id is encoded as part of the opcode (bits [3..0]). * * Possible extension by: * - `REX.B`
*/
ZYDIS_REG_ENCODING_OPCODE, /** * The register-id is encoded in `modrm.reg`. * * Possible extension by: * - `.R` * - `.R'` (vector only, EVEX/MVEX)
*/
ZYDIS_REG_ENCODING_REG, /** * The register-id is encoded in `.vvvv`. * * Possible extension by: * - `.v'` (vector only, EVEX/MVEX).
*/
ZYDIS_REG_ENCODING_NDSNDD, /** * The register-id is encoded in `modrm.rm`. * * Possible extension by: * - `.B` * - `.X` (vector only, EVEX/MVEX)`
*/
ZYDIS_REG_ENCODING_RM, /** * The register-id is encoded in `modrm.rm` or `sib.base` (if `SIB` is present). * * Possible extension by: * - `.B`
*/
ZYDIS_REG_ENCODING_BASE, /** * The register-id is encoded in `sib.index`. * * Possible extension by: * - `.X`
*/
ZYDIS_REG_ENCODING_INDEX, /** * The register-id is encoded in `sib.index`. * * Possible extension by: * - `.X` * - `.V'` (vector only, EVEX/MVEX)
*/
ZYDIS_REG_ENCODING_VIDX, /** * The register-id is encoded in an additional 8-bit immediate value. * * Bits [7:4] in 64-bit mode with possible extension by bit [3] (vector only), bits [7:5] for * all other modes.
*/
ZYDIS_REG_ENCODING_IS4, /** * The register-id is encoded in `EVEX.aaa/MVEX.kkk`.
*/
ZYDIS_REG_ENCODING_MASK,
/** * Maximum value of this enum.
*/
ZYDIS_REG_ENCODING_MAX_VALUE = ZYDIS_REG_ENCODING_MASK, /** * The minimum number of bits required to represent all values of this enum.
*/
ZYDIS_REG_ENCODING_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_REG_ENCODING_MAX_VALUE)
} ZydisRegisterEncoding;
/** * Reads one byte from the current read-position of the input data-source. * * @param state A pointer to the `ZydisDecoderState` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param value A pointer to the memory that receives the byte from the input data-source. * * @return A zyan status code. * * This function may fail, if the `ZYDIS_MAX_INSTRUCTION_LENGTH` limit got exceeded, or no more * data is available.
*/ static ZyanStatus ZydisInputPeek(ZydisDecoderState* state,
ZydisDecodedInstruction* instruction, ZyanU8* value)
{
ZYAN_ASSERT(state);
ZYAN_ASSERT(instruction);
ZYAN_ASSERT(value);
if (instruction->length >= ZYDIS_MAX_INSTRUCTION_LENGTH)
{ return ZYDIS_STATUS_INSTRUCTION_TOO_LONG;
}
/** * Increases the read-position of the input data-source by one byte. * * @param state A pointer to the `ZydisDecoderState` instance * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * * This function is supposed to get called ONLY after a successful call of `ZydisInputPeek`. * * This function increases the `length` field of the `ZydisDecodedInstruction` struct by one.
*/ staticvoid ZydisInputSkip(ZydisDecoderState* state, ZydisDecodedInstruction* instruction)
{
ZYAN_ASSERT(state);
ZYAN_ASSERT(instruction);
ZYAN_ASSERT(instruction->length < ZYDIS_MAX_INSTRUCTION_LENGTH);
/** * Reads one byte from the current read-position of the input data-source and increases * the read-position by one byte afterwards. * * @param state A pointer to the `ZydisDecoderState` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param value A pointer to the memory that receives the byte from the input data-source. * * @return A zyan status code. * * This function acts like a subsequent call of `ZydisInputPeek` and `ZydisInputSkip`.
*/ static ZyanStatus ZydisInputNext(ZydisDecoderState* state,
ZydisDecodedInstruction* instruction, ZyanU8* value)
{
ZYAN_ASSERT(state);
ZYAN_ASSERT(instruction);
ZYAN_ASSERT(value);
if (instruction->length >= ZYDIS_MAX_INSTRUCTION_LENGTH)
{ return ZYDIS_STATUS_INSTRUCTION_TOO_LONG;
}
/** * Reads a variable amount of bytes from the current read-position of the input * data-source and increases the read-position by specified amount of bytes afterwards. * * @param state A pointer to the `ZydisDecoderState` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param value A pointer to the memory that receives the byte from the input * data-source. * @param number_of_bytes The number of bytes to read from the input data-source. * * @return A zyan status code. * * This function acts like a subsequent call of `ZydisInputPeek` and `ZydisInputSkip`.
*/ static ZyanStatus ZydisInputNextBytes(ZydisDecoderState* state,
ZydisDecodedInstruction* instruction, ZyanU8* value, ZyanU8 number_of_bytes)
{
ZYAN_ASSERT(state);
ZYAN_ASSERT(instruction);
ZYAN_ASSERT(value);
if (instruction->length + number_of_bytes > ZYDIS_MAX_INSTRUCTION_LENGTH)
{ return ZYDIS_STATUS_INSTRUCTION_TOO_LONG;
}
if (state->buffer_len >= number_of_bytes)
{
instruction->length += number_of_bytes;
/** * Decodes the `REX`-prefix. * * @param context A pointer to the `ZydisDecoderContext` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param data The `REX` byte.
*/ staticvoid ZydisDecodeREX(ZydisDecoderContext* context, ZydisDecodedInstruction* instruction,
ZyanU8 data)
{
ZYAN_ASSERT(instruction);
ZYAN_ASSERT((data & 0xF0) == 0x40);
if ((instruction->raw.xop.m_mmmm < 0x08) || (instruction->raw.xop.m_mmmm > 0x0A))
{ // Invalid according to the AMD documentation return ZYDIS_STATUS_INVALID_MAP;
}
// Map 0 is only valid for some KNC instructions #ifdef ZYDIS_DISABLE_KNC if ((instruction->raw.vex.m_mmmm == 0) || (instruction->raw.vex.m_mmmm > 0x03)) #else if (instruction->raw.vex.m_mmmm > 0x03) #endif
{ // Invalid according to the intel documentation return ZYDIS_STATUS_INVALID_MAP;
}
if (!instruction->raw.evex.V2 && (instruction->machine_mode != ZYDIS_MACHINE_MODE_LONG_64))
{ return ZYDIS_STATUS_MALFORMED_EVEX;
} if (!instruction->raw.evex.b && (context->vector_unified.LL == 3))
{ // LL = 3 is only valid for instructions with embedded rounding control return ZYDIS_STATUS_MALFORMED_EVEX;
}
return ZYAN_STATUS_SUCCESS;
} #endif
#ifndef ZYDIS_DISABLE_KNC /** * Decodes the `MVEX`-prefix. * * @param context A pointer to the `ZydisDecoderContext` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param data The `MVEX` bytes. * * @return A zyan status code.
*/ static ZyanStatus ZydisDecodeMVEX(ZydisDecoderContext* context,
ZydisDecodedInstruction* instruction, const ZyanU8 data[4])
{
ZYAN_ASSERT(instruction);
ZYAN_ASSERT(data[0] == 0x62);
ZYAN_ASSERT(instruction->raw.mvex.offset == instruction->length - 4);
if (instruction->machine_mode != ZYDIS_MACHINE_MODE_LONG_64)
{ // MVEX is only valid in 64-bit mode return ZYDIS_STATUS_DECODING_ERROR;
}
/** * Reads a displacement value. * * @param state A pointer to the `ZydisDecoderState` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param size The physical size of the displacement value. * * @return A zyan status code.
*/ static ZyanStatus ZydisReadDisplacement(ZydisDecoderState* state,
ZydisDecodedInstruction* instruction, ZyanU8 size)
{
ZYAN_ASSERT(state);
ZYAN_ASSERT(instruction);
ZYAN_ASSERT(instruction->raw.disp.size == 0);
/** * Reads an immediate value. * * @param state A pointer to the `ZydisDecoderState` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param id The immediate id (either `0` or `1`). * @param size The physical size of the immediate value. * @param is_signed Signals, if the immediate value is signed. * @param is_relative Signals, if the immediate value is a relative offset. * * @return A zyan status code.
*/ static ZyanStatus ZydisReadImmediate(ZydisDecoderState* state,
ZydisDecodedInstruction* instruction, ZyanU8 id, ZyanU8 size, ZyanBool is_signed,
ZyanBool is_relative)
{
ZYAN_ASSERT(state);
ZYAN_ASSERT(instruction);
ZYAN_ASSERT((id == 0) || (id == 1));
ZYAN_ASSERT(is_signed || !is_relative);
ZYAN_ASSERT(instruction->raw.imm[id].size == 0);
#ifndef ZYDIS_MINIMAL_MODE /** * Calculates the register-id for a specific register-encoding and register-class. * * @param context A pointer to the `ZydisDecoderContext` struct. * @param instruction A pointer to the ` ZydisDecodedInstruction` struct. * @param encoding The register-encoding. * @param register_class The register-class. * * @return A zyan status code. * * This function calculates the register-id by combining different fields and flags of previously * decoded structs.
*/ static ZyanU8 ZydisCalcRegisterId(const ZydisDecoderContext* context, const ZydisDecodedInstruction* instruction, ZydisRegisterEncoding encoding,
ZydisRegisterClass register_class)
{
ZYAN_ASSERT(context);
ZYAN_ASSERT(instruction);
// TODO: Combine OPCODE and IS4 in `ZydisPopulateRegisterIds` and get rid of this // TODO: function entirely
switch (encoding)
{ case ZYDIS_REG_ENCODING_REG: return context->reg_info.id_reg; case ZYDIS_REG_ENCODING_NDSNDD: return context->reg_info.id_ndsndd; case ZYDIS_REG_ENCODING_RM: return context->reg_info.id_rm; case ZYDIS_REG_ENCODING_BASE: return context->reg_info.id_base; case ZYDIS_REG_ENCODING_INDEX: case ZYDIS_REG_ENCODING_VIDX: return context->reg_info.id_index; case ZYDIS_REG_ENCODING_OPCODE:
{
ZYAN_ASSERT((register_class == ZYDIS_REGCLASS_GPR8) ||
(register_class == ZYDIS_REGCLASS_GPR16) ||
(register_class == ZYDIS_REGCLASS_GPR32) ||
(register_class == ZYDIS_REGCLASS_GPR64));
ZyanU8 value = (instruction->opcode & 0x0F); if (value > 7)
{
value = value - 8;
} if (instruction->machine_mode != ZYDIS_MACHINE_MODE_LONG_64)
{ return value;
} return value | (context->vector_unified.B << 3);
} case ZYDIS_REG_ENCODING_IS4:
{ if (instruction->machine_mode != ZYDIS_MACHINE_MODE_LONG_64)
{ return (instruction->raw.imm[0].value.u >> 4) & 0x07;
}
ZyanU8 value = (instruction->raw.imm[0].value.u >> 4) & 0x0F; // We have to check the instruction-encoding, because the extension by bit [3] is only // valid for EVEX and MVEX instructions if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX))
{ switch (register_class)
{ case ZYDIS_REGCLASS_XMM: case ZYDIS_REGCLASS_YMM: case ZYDIS_REGCLASS_ZMM:
value |= ((instruction->raw.imm[0].value.u & 0x08) << 1); default: break;
}
} return value;
} case ZYDIS_REG_ENCODING_MASK: return context->vector_unified.mask; default:
ZYAN_UNREACHABLE;
}
} #endif
#ifndef ZYDIS_MINIMAL_MODE /** * Sets the operand-size and element-specific information for the given operand. * * @param context A pointer to the `ZydisDecoderContext` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param operand A pointer to the `ZydisDecodedOperand` struct. * @param definition A pointer to the `ZydisOperandDefinition` struct.
*/ staticvoid ZydisSetOperandSizeAndElementInfo(const ZydisDecoderContext* context, const ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand, const ZydisOperandDefinition* definition)
{
ZYAN_ASSERT(context);
ZYAN_ASSERT(instruction);
ZYAN_ASSERT(operand);
ZYAN_ASSERT(definition);
// Operand size switch (operand->type)
{ case ZYDIS_OPERAND_TYPE_REGISTER:
{ if (definition->size[context->eosz_index])
{
operand->size = definition->size[context->eosz_index] * 8;
} else
{
operand->size = ZydisRegisterGetWidth(instruction->machine_mode,
operand->reg.value);
}
operand->element_type = ZYDIS_ELEMENT_TYPE_INT;
operand->element_size = operand->size; break;
} case ZYDIS_OPERAND_TYPE_MEMORY: switch (instruction->encoding)
{ case ZYDIS_INSTRUCTION_ENCODING_LEGACY: case ZYDIS_INSTRUCTION_ENCODING_3DNOW: case ZYDIS_INSTRUCTION_ENCODING_XOP: case ZYDIS_INSTRUCTION_ENCODING_VEX: if (operand->mem.type == ZYDIS_MEMOP_TYPE_AGEN)
{
ZYAN_ASSERT(definition->size[context->eosz_index] == 0);
operand->size = instruction->address_width;
operand->element_type = ZYDIS_ELEMENT_TYPE_INT;
} else
{
ZYAN_ASSERT(definition->size[context->eosz_index] ||
(instruction->meta.category == ZYDIS_CATEGORY_AMX_TILE));
operand->size = definition->size[context->eosz_index] * 8;
} break; case ZYDIS_INSTRUCTION_ENCODING_EVEX: #ifndef ZYDIS_DISABLE_AVX512 if (definition->size[context->eosz_index])
{ // Operand size is hardcoded
operand->size = definition->size[context->eosz_index] * 8;
} else
{ // Operand size depends on the tuple-type, the element-size and the number of // elements
ZYAN_ASSERT(instruction->avx.vector_length);
ZYAN_ASSERT(context->evex.element_size); switch (context->evex.tuple_type)
{ case ZYDIS_TUPLETYPE_FV: if (instruction->avx.broadcast.mode)
{
operand->size = context->evex.element_size;
} else
{
operand->size = instruction->avx.vector_length;
} break; case ZYDIS_TUPLETYPE_HV: if (instruction->avx.broadcast.mode)
{
operand->size = context->evex.element_size;
} else
{
operand->size = (ZyanU16)instruction->avx.vector_length / 2;
} break; case ZYDIS_TUPLETYPE_QUARTER: if (instruction->avx.broadcast.mode)
{
operand->size = context->evex.element_size;
} else
{
operand->size = (ZyanU16)instruction->avx.vector_length / 4;
} break; default:
ZYAN_UNREACHABLE;
}
}
ZYAN_ASSERT(operand->size); #else
ZYAN_UNREACHABLE; #endif break; case ZYDIS_INSTRUCTION_ENCODING_MVEX: #ifndef ZYDIS_DISABLE_KNC if (definition->size[context->eosz_index])
{ // Operand size is hardcoded
operand->size = definition->size[context->eosz_index] * 8;
} else
{
ZYAN_ASSERT(definition->element_type == ZYDIS_IELEMENT_TYPE_VARIABLE);
ZYAN_ASSERT(instruction->avx.vector_length == 512);
switch (instruction->avx.conversion.mode)
{ case ZYDIS_CONVERSION_MODE_INVALID:
operand->size = 512; switch (context->mvex.functionality)
{ case ZYDIS_MVEX_FUNC_SF_32: case ZYDIS_MVEX_FUNC_SF_32_BCST_4TO16: case ZYDIS_MVEX_FUNC_UF_32: case ZYDIS_MVEX_FUNC_DF_32:
operand->element_type = ZYDIS_ELEMENT_TYPE_FLOAT32;
operand->element_size = 32; break; case ZYDIS_MVEX_FUNC_SF_32_BCST:
operand->size = 256;
operand->element_type = ZYDIS_ELEMENT_TYPE_FLOAT32;
operand->element_size = 32; break; case ZYDIS_MVEX_FUNC_SI_32: case ZYDIS_MVEX_FUNC_SI_32_BCST_4TO16: case ZYDIS_MVEX_FUNC_UI_32: case ZYDIS_MVEX_FUNC_DI_32:
operand->element_type = ZYDIS_ELEMENT_TYPE_INT;
operand->element_size = 32; break; case ZYDIS_MVEX_FUNC_SI_32_BCST:
operand->size = 256;
operand->element_type = ZYDIS_ELEMENT_TYPE_INT;
operand->element_size = 32; break; case ZYDIS_MVEX_FUNC_SF_64: case ZYDIS_MVEX_FUNC_UF_64: case ZYDIS_MVEX_FUNC_DF_64:
operand->element_type = ZYDIS_ELEMENT_TYPE_FLOAT64;
operand->element_size = 64; break; case ZYDIS_MVEX_FUNC_SI_64: case ZYDIS_MVEX_FUNC_UI_64: case ZYDIS_MVEX_FUNC_DI_64:
operand->element_type = ZYDIS_ELEMENT_TYPE_INT;
operand->element_size = 64; break; default:
ZYAN_UNREACHABLE;
} break; case ZYDIS_CONVERSION_MODE_FLOAT16:
operand->size = 256;
operand->element_type = ZYDIS_ELEMENT_TYPE_FLOAT16;
operand->element_size = 16; break; case ZYDIS_CONVERSION_MODE_SINT16:
operand->size = 256;
operand->element_type = ZYDIS_ELEMENT_TYPE_INT;
operand->element_size = 16; break; case ZYDIS_CONVERSION_MODE_UINT16:
operand->size = 256;
operand->element_type = ZYDIS_ELEMENT_TYPE_UINT;
operand->element_size = 16; break; case ZYDIS_CONVERSION_MODE_SINT8:
operand->size = 128;
operand->element_type = ZYDIS_ELEMENT_TYPE_INT;
operand->element_size = 8; break; case ZYDIS_CONVERSION_MODE_UINT8:
operand->size = 128;
operand->element_type = ZYDIS_ELEMENT_TYPE_UINT;
operand->element_size = 8; break; default:
ZYAN_UNREACHABLE;
}
switch (instruction->avx.broadcast.mode)
{ case ZYDIS_BROADCAST_MODE_INVALID: // Nothing to do here break; case ZYDIS_BROADCAST_MODE_1_TO_8: case ZYDIS_BROADCAST_MODE_1_TO_16:
operand->size = operand->element_size; break; case ZYDIS_BROADCAST_MODE_4_TO_8: case ZYDIS_BROADCAST_MODE_4_TO_16:
operand->size = operand->element_size * 4; break; default:
ZYAN_UNREACHABLE;
}
} #else
ZYAN_UNREACHABLE; #endif break; default:
ZYAN_UNREACHABLE;
} break; case ZYDIS_OPERAND_TYPE_POINTER:
ZYAN_ASSERT((instruction->raw.imm[0].size == 16) ||
(instruction->raw.imm[0].size == 32));
ZYAN_ASSERT( instruction->raw.imm[1].size == 16);
operand->size = instruction->raw.imm[0].size + instruction->raw.imm[1].size; break; case ZYDIS_OPERAND_TYPE_IMMEDIATE:
operand->size = definition->size[context->eosz_index] * 8; break; default:
ZYAN_UNREACHABLE;
}
// Element-type and -size if (definition->element_type && (definition->element_type != ZYDIS_IELEMENT_TYPE_VARIABLE))
{
ZydisGetElementInfo(definition->element_type, &operand->element_type,
&operand->element_size); if (!operand->element_size)
{ // The element size is the same as the operand size. This is used for single element // scaling operands
operand->element_size = operand->size;
}
}
#ifndef ZYDIS_MINIMAL_MODE /** * Decodes a memory operand. * * @param context A pointer to the `ZydisDecoderContext` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param operand A pointer to the `ZydisDecodedOperand` struct. * @param vidx_register_class The register-class to use as the index register-class for * instructions with `VSIB` addressing. * * @return A zyan status code.
*/ static ZyanStatus ZydisDecodeOperandMemory(const ZydisDecoderContext* context, const ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand,
ZydisRegisterClass vidx_register_class)
{
ZYAN_ASSERT(context);
ZYAN_ASSERT(instruction);
ZYAN_ASSERT(operand);
ZYAN_ASSERT(instruction->attributes & ZYDIS_ATTRIB_HAS_MODRM);
ZYAN_ASSERT(instruction->raw.modrm.mod != 3);
ZYAN_ASSERT(!vidx_register_class || ((instruction->raw.modrm.rm == 4) &&
((instruction->address_width == 32) || (instruction->address_width == 64))));
#ifndef ZYDIS_MINIMAL_MODE /** * Decodes an implicit register operand. * * @param decoder A pointer to the `ZydisDecoder` instance. * @param context A pointer to the `ZydisDecoderContext` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param operand A pointer to the `ZydisDecodedOperand` struct. * @param definition A pointer to the `ZydisOperandDefinition` struct.
*/ staticvoid ZydisDecodeOperandImplicitRegister(const ZydisDecoder* decoder, const ZydisDecoderContext* context, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand, const ZydisOperandDefinition* definition)
{
ZYAN_ASSERT(context);
ZYAN_ASSERT(instruction);
ZYAN_ASSERT(operand);
ZYAN_ASSERT(definition);
#ifndef ZYDIS_MINIMAL_MODE /** * Decodes an implicit memory operand. * * @param decoder A pointer to the `ZydisDecoder` instance. * @param context A pointer to the `ZydisDecoderContext` struct. * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param operand A pointer to the `ZydisDecodedOperand` struct. * @param definition A pointer to the `ZydisOperandDefinition` struct.
*/ staticvoid ZydisDecodeOperandImplicitMemory(const ZydisDecoder* decoder, const ZydisDecoderContext* context, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand, const ZydisOperandDefinition* definition)
{
ZYAN_ASSERT(context);
ZYAN_ASSERT(operand);
ZYAN_ASSERT(definition);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.