From 616cd00ec80d904f06463fe113c01a4020820571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20H=C3=B6ner?= Date: Mon, 23 Jan 2017 19:21:15 +0100 Subject: [PATCH] Encoder support for rIP relative addressing --- src/Encoder.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/Encoder.c b/src/Encoder.c index 2562c38..48e58f1 100644 --- a/src/Encoder.c +++ b/src/Encoder.c @@ -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'));