Added semantic decoding of implicit register operands

This commit is contained in:
flobernd 2017-06-16 03:25:39 +02:00
parent 6caa68b674
commit 1db4db9ec2
9 changed files with 674 additions and 497 deletions

View File

@ -818,11 +818,11 @@ typedef uint16_t ZydisBroadcastMode;
*/ */
enum ZydisBroadcastModes enum ZydisBroadcastModes
{ {
ZYDIS_BROADCAST_MODE_INVALID, ZYDIS_BCSTMODE_INVALID,
ZYDIS_BROADCAST_MODE_1_TO_2, ZYDIS_BCSTMODE_1_TO_2,
ZYDIS_BROADCAST_MODE_1_TO_4, ZYDIS_BCSTMODE_1_TO_4,
ZYDIS_BROADCAST_MODE_1_TO_8, ZYDIS_BCSTMODE_1_TO_8,
ZYDIS_BROADCAST_MODE_1_TO_16 ZYDIS_BCSTMODE_1_TO_16
}; };
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */

View File

@ -63,9 +63,6 @@ typedef uint16_t ZydisInstructionTreeNodeValue;
/** /**
* @brief Defines the @c ZydisInstructionTreeNode struct. * @brief Defines the @c ZydisInstructionTreeNode struct.
*
* This struct is static for now, because its size is sufficient to encode up to 65535
* instruction filters (what is about 10 times more than we currently need).
*/ */
typedef struct ZydisInstructionTreeNode_ typedef struct ZydisInstructionTreeNode_
{ {
@ -220,7 +217,15 @@ typedef struct ZydisOperandDefinition_
union union
{ {
uint8_t encoding; uint8_t encoding;
ZydisRegister reg; struct
{
uint8_t type : 3;
union
{
ZydisRegister reg : 8;
uint8_t id : 6;
} reg;
} reg;
struct struct
{ {
uint8_t seg : 3; uint8_t seg : 3;
@ -230,6 +235,25 @@ typedef struct ZydisOperandDefinition_
} op; } op;
} ZydisOperandDefinition; } ZydisOperandDefinition;
enum ZydisImplicitRegisterType
{
ZYDIS_IMPLREG_TYPE_STATIC,
ZYDIS_IMPLREG_TYPE_GPR_OSZ,
ZYDIS_IMPLREG_TYPE_GPR_ASZ,
ZYDIS_IMPLREG_TYPE_GPR_SSZ,
ZYDIS_IMPLREG_TYPE_IP_ASZ,
ZYDIS_IMPLREG_TYPE_IP_SSZ,
ZYDIS_IMPLREG_TYPE_FLAGS_SSZ
};
enum ZydisImplicitMemBase
{
ZYDIS_IMPLMEM_BASE_ASI,
ZYDIS_IMPLMEM_BASE_ADI,
ZYDIS_IMPLMEM_BASE_ABP,
ZYDIS_IMPLMEM_BASE_ABX
};
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Instruction definition */ /* Instruction definition */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */

File diff suppressed because it is too large Load Diff

View File

@ -54,27 +54,27 @@ typedef uint8_t ZydisRegister;
enum ZydisRegisters enum ZydisRegisters
{ {
ZYDIS_REGISTER_NONE, ZYDIS_REGISTER_NONE,
// General purpose registers 64-bit
ZYDIS_REGISTER_RAX, ZYDIS_REGISTER_RCX, ZYDIS_REGISTER_RDX, ZYDIS_REGISTER_RBX,
ZYDIS_REGISTER_RSP, ZYDIS_REGISTER_RBP, ZYDIS_REGISTER_RSI, ZYDIS_REGISTER_RDI,
ZYDIS_REGISTER_R8, ZYDIS_REGISTER_R9, ZYDIS_REGISTER_R10, ZYDIS_REGISTER_R11,
ZYDIS_REGISTER_R12, ZYDIS_REGISTER_R13, ZYDIS_REGISTER_R14, ZYDIS_REGISTER_R15,
// General purpose registers 32-bit
ZYDIS_REGISTER_EAX, ZYDIS_REGISTER_ECX, ZYDIS_REGISTER_EDX, ZYDIS_REGISTER_EBX,
ZYDIS_REGISTER_ESP, ZYDIS_REGISTER_EBP, ZYDIS_REGISTER_ESI, ZYDIS_REGISTER_EDI,
ZYDIS_REGISTER_R8D, ZYDIS_REGISTER_R9D, ZYDIS_REGISTER_R10D, ZYDIS_REGISTER_R11D,
ZYDIS_REGISTER_R12D, ZYDIS_REGISTER_R13D, ZYDIS_REGISTER_R14D, ZYDIS_REGISTER_R15D,
// General purpose registers 16-bit
ZYDIS_REGISTER_AX, ZYDIS_REGISTER_CX, ZYDIS_REGISTER_DX, ZYDIS_REGISTER_BX,
ZYDIS_REGISTER_SP, ZYDIS_REGISTER_BP, ZYDIS_REGISTER_SI, ZYDIS_REGISTER_DI,
ZYDIS_REGISTER_R8W, ZYDIS_REGISTER_R9W, ZYDIS_REGISTER_R10W, ZYDIS_REGISTER_R11W,
ZYDIS_REGISTER_R12W, ZYDIS_REGISTER_R13W, ZYDIS_REGISTER_R14W, ZYDIS_REGISTER_R15W,
// General purpose registers 8-bit // General purpose registers 8-bit
ZYDIS_REGISTER_AL, ZYDIS_REGISTER_CL, ZYDIS_REGISTER_DL, ZYDIS_REGISTER_BL, ZYDIS_REGISTER_AL, ZYDIS_REGISTER_CL, ZYDIS_REGISTER_DL, ZYDIS_REGISTER_BL,
ZYDIS_REGISTER_AH, ZYDIS_REGISTER_CH, ZYDIS_REGISTER_DH, ZYDIS_REGISTER_BH, ZYDIS_REGISTER_AH, ZYDIS_REGISTER_CH, ZYDIS_REGISTER_DH, ZYDIS_REGISTER_BH,
ZYDIS_REGISTER_SPL, ZYDIS_REGISTER_BPL, ZYDIS_REGISTER_SIL, ZYDIS_REGISTER_DIL, ZYDIS_REGISTER_SPL, ZYDIS_REGISTER_BPL, ZYDIS_REGISTER_SIL, ZYDIS_REGISTER_DIL,
ZYDIS_REGISTER_R8B, ZYDIS_REGISTER_R9B, ZYDIS_REGISTER_R10B, ZYDIS_REGISTER_R11B, ZYDIS_REGISTER_R8B, ZYDIS_REGISTER_R9B, ZYDIS_REGISTER_R10B, ZYDIS_REGISTER_R11B,
ZYDIS_REGISTER_R12B, ZYDIS_REGISTER_R13B, ZYDIS_REGISTER_R14B, ZYDIS_REGISTER_R15B, ZYDIS_REGISTER_R12B, ZYDIS_REGISTER_R13B, ZYDIS_REGISTER_R14B, ZYDIS_REGISTER_R15B,
// General purpose registers 16-bit
ZYDIS_REGISTER_AX, ZYDIS_REGISTER_CX, ZYDIS_REGISTER_DX, ZYDIS_REGISTER_BX,
ZYDIS_REGISTER_SP, ZYDIS_REGISTER_BP, ZYDIS_REGISTER_SI, ZYDIS_REGISTER_DI,
ZYDIS_REGISTER_R8W, ZYDIS_REGISTER_R9W, ZYDIS_REGISTER_R10W, ZYDIS_REGISTER_R11W,
ZYDIS_REGISTER_R12W, ZYDIS_REGISTER_R13W, ZYDIS_REGISTER_R14W, ZYDIS_REGISTER_R15W,
// General purpose registers 32-bit
ZYDIS_REGISTER_EAX, ZYDIS_REGISTER_ECX, ZYDIS_REGISTER_EDX, ZYDIS_REGISTER_EBX,
ZYDIS_REGISTER_ESP, ZYDIS_REGISTER_EBP, ZYDIS_REGISTER_ESI, ZYDIS_REGISTER_EDI,
ZYDIS_REGISTER_R8D, ZYDIS_REGISTER_R9D, ZYDIS_REGISTER_R10D, ZYDIS_REGISTER_R11D,
ZYDIS_REGISTER_R12D, ZYDIS_REGISTER_R13D, ZYDIS_REGISTER_R14D, ZYDIS_REGISTER_R15D,
// General purpose registers 64-bit
ZYDIS_REGISTER_RAX, ZYDIS_REGISTER_RCX, ZYDIS_REGISTER_RDX, ZYDIS_REGISTER_RBX,
ZYDIS_REGISTER_RSP, ZYDIS_REGISTER_RBP, ZYDIS_REGISTER_RSI, ZYDIS_REGISTER_RDI,
ZYDIS_REGISTER_R8, ZYDIS_REGISTER_R9, ZYDIS_REGISTER_R10, ZYDIS_REGISTER_R11,
ZYDIS_REGISTER_R12, ZYDIS_REGISTER_R13, ZYDIS_REGISTER_R14, ZYDIS_REGISTER_R15,
// Floating point legacy registers // Floating point legacy registers
ZYDIS_REGISTER_ST0, ZYDIS_REGISTER_ST1, ZYDIS_REGISTER_ST2, ZYDIS_REGISTER_ST3, ZYDIS_REGISTER_ST0, ZYDIS_REGISTER_ST1, ZYDIS_REGISTER_ST2, ZYDIS_REGISTER_ST3,
ZYDIS_REGISTER_ST4, ZYDIS_REGISTER_ST5, ZYDIS_REGISTER_ST6, ZYDIS_REGISTER_ST7, ZYDIS_REGISTER_ST4, ZYDIS_REGISTER_ST5, ZYDIS_REGISTER_ST6, ZYDIS_REGISTER_ST7,

View File

@ -115,7 +115,6 @@ enum ZydisStatusCode
// TODO: // TODO:
ZYDIS_STATUS_INVALID_MASK, ZYDIS_STATUS_INVALID_MASK,
ZYDIS_STATUS_INVALID_VSIB,
/* ------------------------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------------------------ */
/* Formatter */ /* Formatter */

View File

@ -600,7 +600,7 @@ static ZydisStatus ZydisReadImmediate(ZydisDecoderContext* context, ZydisInstruc
ZYDIS_CHECK(ZydisInputNext(context, info, &value)); ZYDIS_CHECK(ZydisInputNext(context, info, &value));
if (isSigned) if (isSigned)
{ {
info->details.imm[id].value.sbyte = (int8_t)value; info->details.imm[id].value.sqword = (int8_t)value;
} else } else
{ {
info->details.imm[id].value.ubyte = value; info->details.imm[id].value.ubyte = value;
@ -615,7 +615,7 @@ static ZydisStatus ZydisReadImmediate(ZydisDecoderContext* context, ZydisInstruc
uint16_t value = (data[0] << 8) | data[1]; uint16_t value = (data[0] << 8) | data[1];
if (isSigned) if (isSigned)
{ {
info->details.imm[id].value.sword = (int16_t)value; info->details.imm[id].value.sqword = (int16_t)value;
} else } else
{ {
info->details.imm[id].value.uword = value; info->details.imm[id].value.uword = value;
@ -632,7 +632,7 @@ static ZydisStatus ZydisReadImmediate(ZydisDecoderContext* context, ZydisInstruc
uint32_t value = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; uint32_t value = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
if (isSigned) if (isSigned)
{ {
info->details.imm[id].value.sdword = (int32_t)value; info->details.imm[id].value.sqword = (int32_t)value;
} else } else
{ {
info->details.imm[id].value.udword = value; info->details.imm[id].value.udword = value;
@ -873,7 +873,7 @@ static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* cont
if (optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_IMM0) if (optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_IMM0)
{ {
if (optionalParts->imm[0].isSigned) if (optionalParts->imm[0].isRelative)
{ {
info->attributes |= ZYDIS_ATTRIB_IS_RELATIVE; info->attributes |= ZYDIS_ATTRIB_IS_RELATIVE;
} }
@ -1114,6 +1114,143 @@ static ZydisStatus ZydisDecodeOperandMemory(ZydisDecoderContext* context,
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
} }
/**
* @brief Decodes an implicit register operand.
*
* @param context A pointer to the @c ZydisDecoderContext instance.
* @param info A pointer to the @c ZydisInstructionInfo struct.
* @param operand A pointer to the @c ZydisOperandInfo struct.
* @param definition A pointer to the @c ZydisOperandDefinition struct.
*/
static void ZydisDecodeOperandImplicitRegister(ZydisDecoderContext* context,
ZydisInstructionInfo* info, ZydisOperandInfo* operand, const ZydisOperandDefinition* definition)
{
ZYDIS_ASSERT(context);
ZYDIS_ASSERT(info);
ZYDIS_ASSERT(operand);
ZYDIS_ASSERT(definition);
operand->type = ZYDIS_OPERAND_TYPE_REGISTER;
switch (definition->op.reg.type)
{
case ZYDIS_IMPLREG_TYPE_STATIC:
operand->reg = definition->op.reg.reg.reg;
break;
case ZYDIS_IMPLREG_TYPE_GPR_OSZ:
{
static const ZydisRegisterClass lookup[3] =
{
ZYDIS_REGCLASS_GPR16,
ZYDIS_REGCLASS_GPR32,
ZYDIS_REGCLASS_GPR64
};
operand->reg = ZydisRegisterEncode(lookup[context->eoszIndex], definition->op.reg.reg.id);
break;
}
case ZYDIS_IMPLREG_TYPE_GPR_ASZ:
switch (info->addressWidth)
{
case 16:
operand->reg = ZydisRegisterEncode(ZYDIS_REGCLASS_GPR16, definition->op.reg.reg.id);
break;
case 32:
operand->reg = ZydisRegisterEncode(ZYDIS_REGCLASS_GPR32, definition->op.reg.reg.id);
break;
case 64:
operand->reg = ZydisRegisterEncode(ZYDIS_REGCLASS_GPR64, definition->op.reg.reg.id);
break;
default:
ZYDIS_UNREACHABLE;
}
break;
case ZYDIS_IMPLREG_TYPE_GPR_SSZ:
switch (context->decoder->addressWidth)
{
case 16:
operand->reg = ZydisRegisterEncode(ZYDIS_REGCLASS_GPR16, definition->op.reg.reg.id);
break;
case 32:
operand->reg = ZydisRegisterEncode(ZYDIS_REGCLASS_GPR32, definition->op.reg.reg.id);
break;
case 64:
operand->reg = ZydisRegisterEncode(ZYDIS_REGCLASS_GPR64, definition->op.reg.reg.id);
break;
default:
ZYDIS_UNREACHABLE;
}
break;
case ZYDIS_IMPLREG_TYPE_IP_ASZ:
switch (info->addressWidth)
{
case 16:
operand->reg = ZYDIS_REGISTER_IP;
break;
case 32:
operand->reg = ZYDIS_REGISTER_EIP;
break;
case 64:
operand->reg = ZYDIS_REGISTER_RIP;
break;
default:
ZYDIS_UNREACHABLE;
}
break;
case ZYDIS_IMPLREG_TYPE_IP_SSZ:
switch (context->decoder->addressWidth)
{
case 16:
operand->reg = ZYDIS_REGISTER_IP;
break;
case 32:
operand->reg = ZYDIS_REGISTER_EIP;
break;
case 64:
operand->reg = ZYDIS_REGISTER_RIP;
break;
default:
ZYDIS_UNREACHABLE;
}
break;
case ZYDIS_IMPLREG_TYPE_FLAGS_SSZ:
switch (context->decoder->addressWidth)
{
case 16:
operand->reg = ZYDIS_REGISTER_FLAGS;
break;
case 32:
operand->reg = ZYDIS_REGISTER_EFLAGS;
break;
case 64:
operand->reg = ZYDIS_REGISTER_RFLAGS;
break;
default:
ZYDIS_UNREACHABLE;
}
break;
default:
ZYDIS_UNREACHABLE;
}
}
/**
* @brief Decodes an implicit memory operand.
*
* @param context A pointer to the @c ZydisDecoderContext instance.
* @param info A pointer to the @c ZydisInstructionInfo struct.
* @param operand A pointer to the @c ZydisOperandInfo struct.
* @param definition A pointer to the @c ZydisOperandDefinition struct.
*/
static void ZydisDecodeOperandImplicitMemory(ZydisDecoderContext* context,
ZydisInstructionInfo* info, ZydisOperandInfo* operand, const ZydisOperandDefinition* definition)
{
ZYDIS_ASSERT(context);
ZYDIS_ASSERT(info);
ZYDIS_ASSERT(operand);
ZYDIS_ASSERT(definition);
}
/** /**
* @brief Decodes the instruction operands. * @brief Decodes the instruction operands.
* *
@ -1141,6 +1278,19 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
info->operands[i].visibility = operand->visibility; info->operands[i].visibility = operand->visibility;
info->operands[i].action = operand->action; info->operands[i].action = operand->action;
// Implicit operands
switch (operand->type)
{
case ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_REG:
ZydisDecodeOperandImplicitRegister(context, info, &info->operands[i], operand);
break;
case ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_MEM:
ZydisDecodeOperandImplicitMemory(context, info, &info->operands[i], operand);
break;
default:
break;
}
// Register operands // Register operands
ZydisRegisterClass registerClass = ZYDIS_REGCLASS_INVALID; ZydisRegisterClass registerClass = ZYDIS_REGCLASS_INVALID;
switch (operand->type) switch (operand->type)
@ -1280,6 +1430,7 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
case ZYDIS_OPERAND_ENCODING_UIMM8_HI: case ZYDIS_OPERAND_ENCODING_UIMM8_HI:
switch (context->decoder->machineMode) switch (context->decoder->machineMode)
{ {
// TODO: 16?
case 32: case 32:
ZYDIS_CHECK(ZydisDecodeOperandRegister(info, &info->operands[i], registerClass, ZYDIS_CHECK(ZydisDecodeOperandRegister(info, &info->operands[i], registerClass,
(info->details.imm[0].value.ubyte >> 4) & 0x07)); (info->details.imm[0].value.ubyte >> 4) & 0x07));
@ -1344,14 +1495,9 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
{ {
if (vsibBaseRegister) if (vsibBaseRegister)
{ {
if (info->details.modrm.rm != 0x04) ZYDIS_ASSERT(info->details.modrm.rm == 0x04);
{
return ZYDIS_STATUS_INVALID_VSIB;
}
switch (info->addressWidth) switch (info->addressWidth)
{ {
case 16:
return ZYDIS_STATUS_INVALID_VSIB;
case 32: case 32:
info->operands[i].mem.index = info->operands[i].mem.index =
info->operands[i].mem.index - ZYDIS_REGISTER_EAX + vsibBaseRegister + info->operands[i].mem.index - ZYDIS_REGISTER_EAX + vsibBaseRegister +
@ -1424,10 +1570,9 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
case ZYDIS_SEMANTIC_OPTYPE_REL: case ZYDIS_SEMANTIC_OPTYPE_REL:
ZYDIS_ASSERT(info->details.imm[immId].isRelative); ZYDIS_ASSERT(info->details.imm[immId].isRelative);
case ZYDIS_SEMANTIC_OPTYPE_IMM: case ZYDIS_SEMANTIC_OPTYPE_IMM:
ZYDIS_ASSERT(!info->details.imm[immId].isRelative);
ZYDIS_ASSERT((immId == 0) || (immId == 1)); ZYDIS_ASSERT((immId == 0) || (immId == 1));
info->operands[i].type = ZYDIS_OPERAND_TYPE_IMMEDIATE; info->operands[i].type = ZYDIS_OPERAND_TYPE_IMMEDIATE;
info->operands[i].size = info->details.imm[immId].dataSize; info->operands[i].size = operand->size[context->eoszIndex] * 8;
info->operands[i].imm.value.uqword = info->details.imm[immId].value.uqword; info->operands[i].imm.value.uqword = info->details.imm[immId].value.uqword;
info->operands[i].imm.isSigned = info->details.imm[immId].isSigned; info->operands[i].imm.isSigned = info->details.imm[immId].isSigned;
info->operands[i].imm.isRelative = info->details.imm[immId].isRelative; info->operands[i].imm.isRelative = info->details.imm[immId].isRelative;
@ -1830,13 +1975,13 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
switch (info->avx.vectorLength) switch (info->avx.vectorLength)
{ {
case 128: case 128:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4; info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_4;
break; break;
case 256: case 256:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8; info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_8;
break; break;
case 512: case 512:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_16; info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_16;
break; break;
default: default:
ZYDIS_UNREACHABLE; ZYDIS_UNREACHABLE;
@ -1848,13 +1993,13 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
switch (info->avx.vectorLength) switch (info->avx.vectorLength)
{ {
case 128: case 128:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_2; info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_2;
break; break;
case 256: case 256:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_4; info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_4;
break; break;
case 512: case 512:
info->avx.broadcastMode = ZYDIS_BROADCAST_MODE_1_TO_8; info->avx.broadcastMode = ZYDIS_BCSTMODE_1_TO_8;
break; break;
default: default:
ZYDIS_UNREACHABLE; ZYDIS_UNREACHABLE;
@ -2053,7 +2198,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context,
} }
} else } else
{ {
// TODO: Add tuple type // TODO: Add tuple type to register-only definitions
ZYDIS_ASSERT(info->details.modrm.mod == 3); ZYDIS_ASSERT(info->details.modrm.mod == 3);
} }
@ -2825,6 +2970,8 @@ ZydisStatus ZydisDecoderDecodeBuffer(ZydisInstructionDecoder* decoder, const voi
ZYDIS_CHECK(ZydisCollectOptionalPrefixes(&context, info)); ZYDIS_CHECK(ZydisCollectOptionalPrefixes(&context, info));
ZYDIS_CHECK(ZydisDecodeInstruction(&context, info)); ZYDIS_CHECK(ZydisDecodeInstruction(&context, info));
info->instrPointer = info->instrAddress + info->length;
// TODO: The index, dest and mask regs for AVX2 gathers must be different. // TODO: The index, dest and mask regs for AVX2 gathers must be different.
// TODO: More EVEX UD conditions (page 81) // TODO: More EVEX UD conditions (page 81)

View File

@ -627,13 +627,15 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter*
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
/*const char* bufEnd = *buffer + bufferLen; const char* bufEnd = *buffer + bufferLen;
if (operand->id == 0) if (operand->id == 1)
{ {
if (info->avx.maskRegister) if ((operand->type == ZYDIS_OPERAND_TYPE_REGISTER) &&
(operand->encoding == ZYDIS_OPERAND_ENCODING_MASK) &&
(operand->reg != ZYDIS_REGISTER_K0))
{ {
const char* reg = ZydisRegisterGetString(info->avx.maskRegister); const char* reg = ZydisRegisterGetString(operand->reg);
if (!reg) if (!reg)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -641,7 +643,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter*
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE, ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE,
" {%s}", reg)); " {%s}", reg));
} }
if (info->avx.maskMode == ZYDIS_AVX512_MASKMODE_ZERO) if (info->avx.maskMode == ZYDIS_MASKMODE_ZERO)
{ {
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
@ -650,23 +652,23 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter*
{ {
if (info->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY) if (info->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY)
{ {
switch (info->avx.broadcast) switch (info->avx.broadcastMode)
{ {
case ZYDIS_AVX512_BCSTMODE_INVALID: case ZYDIS_BCSTMODE_INVALID:
break; break;
case ZYDIS_AVX512_BCSTMODE_2: case ZYDIS_BCSTMODE_1_TO_2:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
break; break;
case ZYDIS_AVX512_BCSTMODE_4: case ZYDIS_BCSTMODE_1_TO_4:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
break; break;
case ZYDIS_AVX512_BCSTMODE_8: case ZYDIS_BCSTMODE_1_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
break; break;
case ZYDIS_AVX512_BCSTMODE_16: case ZYDIS_BCSTMODE_1_TO_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
break; break;
@ -679,7 +681,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter*
((operand->id != (info->operandCount - 1)) && ((operand->id != (info->operandCount - 1)) &&
(info->operands[operand->id + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))) (info->operands[operand->id + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)))
{ {
switch (info->avx.roundingMode) /*switch (info->avx.roundingMode)
{ {
case ZYDIS_AVX_RNDMODE_INVALID: case ZYDIS_AVX_RNDMODE_INVALID:
if (info->avx.hasSAE) if (info->avx.hasSAE)
@ -706,9 +708,9 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter*
break; break;
default: default:
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
}
}
}*/ }*/
}
}
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
} }
@ -733,6 +735,11 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
for (uint8_t i = 0; i < info->operandCount; ++i) for (uint8_t i = 0; i < info->operandCount; ++i)
{ {
if (info->operands[i].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN)
{
break;
}
if (i != 0) if (i != 0)
{ {
bufRestore = *buffer; bufRestore = *buffer;
@ -816,6 +823,7 @@ ZydisStatus ZydisFormatterInitInstructionFormatterEx(
(displacementFormat != ZYDIS_FORMATTER_DISP_HEX_SIGNED) && (displacementFormat != ZYDIS_FORMATTER_DISP_HEX_SIGNED) &&
(displacementFormat != ZYDIS_FORMATTER_DISP_HEX_UNSIGNED)) || (displacementFormat != ZYDIS_FORMATTER_DISP_HEX_UNSIGNED)) ||
((immmediateFormat != ZYDIS_FORMATTER_IMM_DEFAULT) && ((immmediateFormat != ZYDIS_FORMATTER_IMM_DEFAULT) &&
(immmediateFormat != ZYDIS_FORMATTER_IMM_HEX_AUTO) &&
(immmediateFormat != ZYDIS_FORMATTER_IMM_HEX_SIGNED) && (immmediateFormat != ZYDIS_FORMATTER_IMM_HEX_SIGNED) &&
(immmediateFormat != ZYDIS_FORMATTER_IMM_HEX_UNSIGNED))) (immmediateFormat != ZYDIS_FORMATTER_IMM_HEX_UNSIGNED)))
{ {

View File

@ -33,27 +33,27 @@
const char* registerStrings[] = const char* registerStrings[] =
{ {
"none", "none",
// General purpose registers 64-bit
"rax", "rcx", "rdx", "rbx",
"rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11",
"r12", "r13", "r14", "r15",
// General purpose registers 32-bit
"eax", "ecx", "edx", "ebx",
"esp", "ebp", "esi", "edi",
"r8d", "r9d", "r10d", "r11d",
"r12d", "r13d", "r14d", "r15d",
// General purpose registers 16-bit
"ax", "cx", "dx", "bx",
"sp", "bp", "si", "di",
"r8w", "r9w", "r10w", "r11w",
"r12w", "r13w", "r14w", "r15w",
// General purpose registers 8-bit // General purpose registers 8-bit
"al", "cl", "dl", "bl", "al", "cl", "dl", "bl",
"ah", "ch", "dh", "bh", "ah", "ch", "dh", "bh",
"spl", "bpl", "sil", "dil", "spl", "bpl", "sil", "dil",
"r8b", "r9b", "r10b", "r11b", "r8b", "r9b", "r10b", "r11b",
"r12b", "r13b", "r14b", "r15b", "r12b", "r13b", "r14b", "r15b",
// General purpose registers 16-bit
"ax", "cx", "dx", "bx",
"sp", "bp", "si", "di",
"r8w", "r9w", "r10w", "r11w",
"r12w", "r13w", "r14w", "r15w",
// General purpose registers 32-bit
"eax", "ecx", "edx", "ebx",
"esp", "ebp", "esi", "edi",
"r8d", "r9d", "r10d", "r11d",
"r12d", "r13d", "r14d", "r15d",
// General purpose registers 64-bit
"rax", "rcx", "rdx", "rbx",
"rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11",
"r12", "r13", "r14", "r15",
// Floating point legacy registers // Floating point legacy registers
"st0", "st1", "st2", "st3", "st0", "st1", "st2", "st3",
"st4", "st5", "st6", "st7", "st4", "st5", "st6", "st7",

View File

@ -64,8 +64,7 @@ ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info
case ZYDIS_OPERAND_TYPE_IMMEDIATE: case ZYDIS_OPERAND_TYPE_IMMEDIATE:
if (operand->imm.isSigned && operand->imm.isRelative) if (operand->imm.isSigned && operand->imm.isRelative)
{ {
*address = *address = (uint64_t)((int64_t)info->instrPointer + operand->imm.value.sqword);
(uint64_t)((int64_t)info->instrPointer + info->length + operand->imm.value.sqword);
switch (info->machineMode) switch (info->machineMode)
{ {
case 16: case 16: