mirror of https://github.com/x64dbg/zydis
Implemented segment prefix encoding, refactoring
- Moved memory operand encoding into dedicated function
This commit is contained in:
parent
87e80346f4
commit
b3c8d44bda
|
@ -415,6 +415,7 @@ static ZydisStatus ZydisPrepareRegOperand(ZydisEncoderContext* ctx,
|
|||
ZydisRegister reg, char topBitLoc)
|
||||
{
|
||||
int16_t regID = ZydisRegisterGetId(reg);
|
||||
//ZydisRegisterClass clazz = ZydisRegisterGetClass(reg);
|
||||
if (regID == -1) return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
|
||||
uint8_t lowerBits = (regID & 0x07) >> 0;
|
||||
|
@ -479,33 +480,22 @@ static ZydisStatus ZydisPrepareRegOperand(ZydisEncoderContext* ctx,
|
|||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisPrepareOperand(ZydisEncoderContext* ctx,
|
||||
static ZydisBool ZydisIsStackReg(ZydisRegister reg)
|
||||
{
|
||||
return reg == ZYDIS_REGISTER_SP ||
|
||||
reg == ZYDIS_REGISTER_ESP ||
|
||||
reg == ZYDIS_REGISTER_RSP ||
|
||||
reg == ZYDIS_REGISTER_BP ||
|
||||
reg == ZYDIS_REGISTER_EBP ||
|
||||
reg == ZYDIS_REGISTER_RBP;
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisPrepareMemoryOperand(ZydisEncoderContext* ctx,
|
||||
ZydisOperandInfo* operand, const ZydisEncoderTableOperand* tableEntry)
|
||||
{
|
||||
switch (tableEntry->encoding)
|
||||
{
|
||||
case ZYDIS_OPERAND_ENCODING_NONE:
|
||||
break; // Nothing to do.
|
||||
case ZYDIS_OPERAND_ENCODING_REG:
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrepareRegOperand(ctx, operand->reg, 'R'));
|
||||
} break;
|
||||
case ZYDIS_OPERAND_ENCODING_RM:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD2:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD4:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD8:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD16:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD32:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD64:
|
||||
{
|
||||
// TODO: MMX registers
|
||||
// TODO: rBP
|
||||
// TODO: RIP relative addressing
|
||||
// TODO: Segment prefixes
|
||||
|
||||
// Memory operand?
|
||||
if (operand->type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
// Absolute memory access?
|
||||
if (operand->mem.base == ZYDIS_REGISTER_NONE)
|
||||
{
|
||||
|
@ -529,13 +519,43 @@ static ZydisStatus ZydisPrepareOperand(ZydisEncoderContext* ctx,
|
|||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SIB;
|
||||
}
|
||||
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_MODRM;
|
||||
break;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Base register?
|
||||
// Process base register.
|
||||
ZYDIS_CHECK(ZydisPrepareRegOperand(ctx, operand->mem.base, 'B'));
|
||||
|
||||
// Segment prefix required?
|
||||
switch (operand->mem.segment)
|
||||
{
|
||||
case ZYDIS_REGISTER_ES:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_ES;
|
||||
break;
|
||||
case ZYDIS_REGISTER_SS:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_SS;
|
||||
break;
|
||||
case ZYDIS_REGISTER_CS:
|
||||
if (!ZydisIsStackReg(operand->mem.base))
|
||||
{
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_CS;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_REGISTER_DS:
|
||||
if (ZydisIsStackReg(operand->mem.base))
|
||||
{
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_DS;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_REGISTER_FS:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_FS;
|
||||
break;
|
||||
case ZYDIS_REGISTER_GS:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_GS;
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO: Better status.
|
||||
}
|
||||
|
||||
// SIB byte required?
|
||||
if (operand->mem.index || operand->mem.scale)
|
||||
{
|
||||
|
@ -603,6 +623,33 @@ static ZydisStatus ZydisPrepareOperand(ZydisEncoderContext* ctx,
|
|||
{
|
||||
ctx->info->details.modrm.mod = 0x00 /* no disp */;
|
||||
}
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisPrepareOperand(ZydisEncoderContext* ctx,
|
||||
ZydisOperandInfo* operand, const ZydisEncoderTableOperand* tableEntry)
|
||||
{
|
||||
switch (tableEntry->encoding)
|
||||
{
|
||||
case ZYDIS_OPERAND_ENCODING_NONE:
|
||||
break; // Nothing to do.
|
||||
case ZYDIS_OPERAND_ENCODING_REG:
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrepareRegOperand(ctx, operand->reg, 'R'));
|
||||
} break;
|
||||
case ZYDIS_OPERAND_ENCODING_RM:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD2:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD4:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD8:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD16:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD32:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD64:
|
||||
{
|
||||
// Memory operand?
|
||||
if (operand->type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrepareMemoryOperand(ctx, operand, tableEntry));
|
||||
}
|
||||
// Nope, register.
|
||||
else if (operand->type == ZYDIS_OPERAND_TYPE_REGISTER)
|
||||
|
|
Loading…
Reference in New Issue