Encoder support for rIP relative addressing

This commit is contained in:
Joel Höner 2017-01-23 19:21:15 +01:00
parent 0862398940
commit 616cd00ec8
1 changed files with 36 additions and 3 deletions

View File

@ -541,6 +541,13 @@ static ZydisBool ZydisIsSPReg(ZydisRegister reg)
reg == ZYDIS_REGISTER_RSP;
}
static ZydisBool ZydisIsIPReg(ZydisRegister reg)
{
return reg == ZYDIS_REGISTER_IP ||
reg == ZYDIS_REGISTER_EIP ||
reg == ZYDIS_REGISTER_RIP;
}
static ZydisBool ZydisIsStackReg(ZydisRegister reg)
{
return ZydisIsSPReg(reg) || ZydisIsBPReg(reg);
@ -572,9 +579,7 @@ static ZydisStatus ZydisPrepareMemoryOperand(ZydisEncoderContext* ctx,
ZYDIS_ASSERT(operand);
ZYDIS_ASSERT(tableEntry);
// TODO: RIP relative addressing
// Absolute memory access?
// Absolute memory access? Special case.
if (operand->mem.base == ZYDIS_REGISTER_NONE)
{
ctx->disp = operand->mem.disp.value.sdword;
@ -600,6 +605,34 @@ static ZydisStatus ZydisPrepareMemoryOperand(ZydisEncoderContext* ctx,
return ZYDIS_STATUS_SUCCESS;
}
// rIP relative addressing? Special case.
if (ZydisIsIPReg(operand->mem.base))
{
// rIP addressing is only available since AMD64.
if (ctx->info->mode != ZYDIS_DISASSEMBLER_MODE_64BIT)
{
return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO
}
// Only available with either EIP or RIP, not with IP.
if (operand->mem.base == ZYDIS_REGISTER_IP)
{
return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO
}
ctx->disp = operand->mem.disp.value.sdword;
ctx->dispBitSize = 32;
ctx->info->details.modrm.mod = 0x00;
ctx->info->details.modrm.rm = 0x05 /* RIP relative mem */;
if (operand->mem.base == ZYDIS_REGISTER_EIP)
{
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_ADDRESSSIZE;
}
return ZYDIS_STATUS_SUCCESS;
}
// Process base register.
ZYDIS_CHECK(ZydisPrepareRegOperand(ctx, operand->mem.base, 'B'));