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
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue