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 enum ZydisImplicitMemBase
{ {
ZYDIS_IMPLMEM_BASE_ASI, ZYDIS_IMPLMEM_BASE_ABX,
ZYDIS_IMPLMEM_BASE_ADI,
ZYDIS_IMPLMEM_BASE_ABP, 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 * 0 = 16 bit, 1 = 32 bit, 2 = 64 bit
*/ */
uint8_t eoszIndex; 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. * @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(operand);
ZYDIS_ASSERT(definition); 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(info);
ZYDIS_ASSERT(definition); ZYDIS_ASSERT(definition);
(void)context;
uint8_t immId = 0; uint8_t immId = 0;
const ZydisOperandDefinition* operand; const ZydisOperandDefinition* operand;
info->operandCount = ZydisGetOperandDefinitions(definition, &operand); info->operandCount = ZydisGetOperandDefinitions(definition, &operand);
@ -1290,6 +1328,16 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
default: default:
break; 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 // Register operands
ZydisRegisterClass registerClass = ZYDIS_REGCLASS_INVALID; ZydisRegisterClass registerClass = ZYDIS_REGCLASS_INVALID;
@ -1457,6 +1505,9 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
// TODO: Always override size for register operands? // TODO: Always override size for register operands?
info->operands[i].size = operand->size[context->eoszIndex] * 8; info->operands[i].size = operand->size[context->eoszIndex] * 8;
} }
++operand;
continue;
} }
// Memory operands // Memory operands
@ -1562,6 +1613,9 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
{ {
info->operands[i].mem.disp.value.sqword *= info->avx.compressedDisp8Scale; info->operands[i].mem.disp.value.sqword *= info->avx.compressedDisp8Scale;
} }
++operand;
continue;
} }
// Immediate operands // Immediate operands
@ -1572,6 +1626,7 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
case ZYDIS_SEMANTIC_OPTYPE_IMM: case ZYDIS_SEMANTIC_OPTYPE_IMM:
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;
//ZYDIS_ASSERT(operand->size[context->eoszIndex]);
info->operands[i].size = operand->size[context->eoszIndex] * 8; 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;
@ -1581,6 +1636,7 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, ZydisInstru
default: default:
break; break;
} }
ZYDIS_ASSERT(info->operands[i].type == ZYDIS_OPERAND_TYPE_IMMEDIATE);
++operand; ++operand;
} }
@ -1737,6 +1793,21 @@ static void ZydisSetEffectiveAddressWidth(ZydisDecoderContext* context, ZydisIns
default: default:
ZYDIS_UNREACHABLE; 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, ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE,
" {%s}", reg)); " {%s}", reg));
}
if (info->avx.maskMode == ZYDIS_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}"));
} }
}
} else } else
{ {
if (info->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY) if (info->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY)
@ -782,7 +782,7 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
if (bufPreOperand == *buffer) 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 = bufRestore;
*buffer[0] = 0; *buffer[0] = 0;
} else } else