mirror of https://github.com/x64dbg/zydis
Added semantic decoding of implicit memory operands
This commit is contained in:
parent
1db4db9ec2
commit
44792f2338
|
@ -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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -642,11 +642,11 @@ 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
|
||||
{
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue