Added semantic decoding of implicit memory operands

This commit is contained in:
flobernd 2017-06-16 16:27:37 +02:00
parent 1db4db9ec2
commit 44792f2338
3 changed files with 83 additions and 12 deletions

View File

@ -248,10 +248,10 @@ enum ZydisImplicitRegisterType
enum ZydisImplicitMemBase
{
ZYDIS_IMPLMEM_BASE_ASI,
ZYDIS_IMPLMEM_BASE_ADI,
ZYDIS_IMPLMEM_BASE_ABX,
ZYDIS_IMPLMEM_BASE_ABP,
ZYDIS_IMPLMEM_BASE_ABX
ZYDIS_IMPLMEM_BASE_ASI,
ZYDIS_IMPLMEM_BASE_ADI
};
/* ---------------------------------------------------------------------------------------------- */

View File

@ -71,6 +71,12 @@ typedef struct ZydisDecoderContext_
* 0 = 16 bit, 1 = 32 bit, 2 = 64 bit
*/
uint8_t eoszIndex;
/**
* @brief Contains the effective address-size index.
*
* 0 = 16 bit, 1 = 32 bit, 2 = 64 bit
*/
uint8_t easzIndex;
/**
* @brief Contains some cached REX/XOP/VEX/EVEX/MVEX values to provide uniform access.
*/
@ -1249,6 +1255,40 @@ static void ZydisDecodeOperandImplicitMemory(ZydisDecoderContext* context,
ZYDIS_ASSERT(operand);
ZYDIS_ASSERT(definition);
static const ZydisRegisterClass lookup[3] =
{
ZYDIS_REGCLASS_GPR16,
ZYDIS_REGCLASS_GPR32,
ZYDIS_REGCLASS_GPR64
};
operand->type = ZYDIS_OPERAND_TYPE_MEMORY;
// TODO: Base action
switch (definition->op.mem.base)
{
case ZYDIS_IMPLMEM_BASE_ABX:
operand->mem.base = ZydisRegisterEncode(lookup[context->easzIndex], 3);
break;
case ZYDIS_IMPLMEM_BASE_ABP:
operand->mem.base = ZydisRegisterEncode(lookup[context->easzIndex], 5);
break;
case ZYDIS_IMPLMEM_BASE_ASI:
operand->mem.base = ZydisRegisterEncode(lookup[context->easzIndex], 6);
break;
case ZYDIS_IMPLMEM_BASE_ADI:
operand->mem.base = ZydisRegisterEncode(lookup[context->easzIndex], 7);
break;
default:
ZYDIS_UNREACHABLE;
}
if (definition->op.mem.seg)
{
operand->mem.segment =
ZydisRegisterEncode(ZYDIS_REGCLASS_SEGMENT, definition->op.mem.seg - 1);
ZYDIS_ASSERT(operand->mem.segment);
}
}
/**
@ -1267,8 +1307,6 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
ZYDIS_ASSERT(info);
ZYDIS_ASSERT(definition);
(void)context;
uint8_t immId = 0;
const ZydisOperandDefinition* operand;
info->operandCount = ZydisGetOperandDefinitions(definition, &operand);
@ -1290,6 +1328,16 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
default:
break;
}
if (info->operands[i].type)
{
if (info->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
//ZYDIS_ASSERT(operand->size[context->eoszIndex]);
info->operands[i].size = operand->size[context->eoszIndex] * 8;
}
++operand;
continue;
}
// Register operands
ZydisRegisterClass registerClass = ZYDIS_REGCLASS_INVALID;
@ -1457,6 +1505,9 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
// TODO: Always override size for register operands?
info->operands[i].size = operand->size[context->eoszIndex] * 8;
}
++operand;
continue;
}
// Memory operands
@ -1562,6 +1613,9 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
{
info->operands[i].mem.disp.value.sqword *= info->avx.compressedDisp8Scale;
}
++operand;
continue;
}
// Immediate operands
@ -1572,6 +1626,7 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
case ZYDIS_SEMANTIC_OPTYPE_IMM:
ZYDIS_ASSERT((immId == 0) || (immId == 1));
info->operands[i].type = ZYDIS_OPERAND_TYPE_IMMEDIATE;
//ZYDIS_ASSERT(operand->size[context->eoszIndex]);
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.isSigned = info->details.imm[immId].isSigned;
@ -1581,6 +1636,7 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
default:
break;
}
ZYDIS_ASSERT(info->operands[i].type == ZYDIS_OPERAND_TYPE_IMMEDIATE);
++operand;
}
@ -1737,6 +1793,21 @@ static void ZydisSetEffectiveAddressWidth(ZydisDecoderContext* context, ZydisIns
default:
ZYDIS_UNREACHABLE;
}
switch (info->addressWidth)
{
case 16:
context->easzIndex = 0;
break;
case 32:
context->easzIndex = 1;
break;
case 64:
context->easzIndex = 2;
break;
default:
ZYDIS_UNREACHABLE;
}
}
/**

View File

@ -642,12 +642,12 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter*
}
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE,
" {%s}", reg));
}
if (info->avx.maskMode == ZYDIS_MASKMODE_ZERO)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
}
if (info->avx.maskMode == ZYDIS_MASKMODE_ZERO)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
}
}
} else
{
if (info->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY)
@ -782,7 +782,7 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
if (bufPreOperand == *buffer)
{
// Omit whole operands, if the buffer did not change during the formatting-callback
// Omit whole operand, if the buffer did not change during the formatting-callback
*buffer = bufRestore;
*buffer[0] = 0;
} else