From ded9d0e513a7a10e9e2636df6167d783cbe4b14d Mon Sep 17 00:00:00 2001 From: flobernd Date: Mon, 25 Sep 2017 17:59:14 +0200 Subject: [PATCH] Minor refactorings - `ZydisUtilsCalcAbsoluteTargetAddress` is now called `ZydisCalcAbsoluteAddress` - `ZydisCalcAbsoluteAddress` does now handle `MEM` operands with absolute displacement values --- include/Zydis/DecoderTypes.h | 5 ++--- include/Zydis/Utils.h | 17 +++++++++------ src/Formatter.c | 41 ++++++------------------------------ src/Utils.c | 20 +++++++++++++++++- 4 files changed, 39 insertions(+), 44 deletions(-) diff --git a/include/Zydis/DecoderTypes.h b/include/Zydis/DecoderTypes.h index b51aab2..89dad8b 100644 --- a/include/Zydis/DecoderTypes.h +++ b/include/Zydis/DecoderTypes.h @@ -157,7 +157,7 @@ typedef struct ZydisDecodedOperand_ ZydisBool isSigned; /** * @brief Signals, if the immediate value contains a relative offset. You can use - * @c ZydisUtilsCalcAbsoluteTargetAddress to determine the absolute address value. + * @c ZydisCalcAbsoluteAddress to determine the absolute address value. */ ZydisBool isRelative; /** @@ -1251,8 +1251,7 @@ typedef struct ZydisDecodedInstruction_ ZydisBool isSigned; /** * @brief Signals, if the immediate value contains a relative offset. You can use - * @c ZydisUtilsCalcAbsoluteTargetAddress to determine the absolute address - * value. + * @c ZydisCalcAbsoluteAddress to determine the absolute address value. */ ZydisBool isRelative; /** diff --git a/include/Zydis/Utils.h b/include/Zydis/Utils.h index a699c77..9ee8fad 100644 --- a/include/Zydis/Utils.h +++ b/include/Zydis/Utils.h @@ -45,17 +45,22 @@ extern "C" { /* ============================================================================================== */ /** - * @brief Calculates the absolute target-address of an relative instruction operand. + * @brief Calculates the absolute target-address for the given instruction operand. * * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param operand A pointer to the @c ZydisDecodedOperand struct. * @param address A pointer to the memory that receives the absolute target-address. * - * @return A zydis status code + * @return A zydis status code. + * + * You should use this function in the following cases: + * - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...) + * - `MEM` operands with RIP/EIP-relative address (e.g. `MOV RAX, [RIP+0x12345678]`) + * - `MEM` operands with absolute address (e.g. `MOV RAX, [0x12345678]`) + * - The displacement needs to get truncated and zero extended */ -ZYDIS_EXPORT ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress( - const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, - uint64_t* address); +ZYDIS_EXPORT ZydisStatus ZydisCalcAbsoluteAddress(const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand, uint64_t* address); /* ============================================================================================== */ /* Flags */ @@ -68,7 +73,7 @@ ZYDIS_EXPORT ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress( * @param action The CPU-flag action. * @param flags A pointer to the variable that receives the flag mask. * - * @return A zydis status code + * @return A zydis status code. */ ZYDIS_EXPORT ZydisStatus ZydisGetAccessedFlagsByAction(const ZydisDecodedInstruction* instruction, ZydisCPUFlagAction action, ZydisCPUFlagMask* flags); diff --git a/src/Formatter.c b/src/Formatter.c index 26b56c8..bf1dafe 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -157,40 +157,13 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for (operand->mem.base == ZYDIS_REGISTER_RIP)) && (operand->mem.index == ZYDIS_REGISTER_NONE) && (operand->mem.scale == 0)) { - // Address operand - uint64_t address = 0; - ZydisBool absolute = ZYDIS_TRUE; - if (operand->mem.base == ZYDIS_REGISTER_NONE) - { - // MOFFS8/16/32/64 - address = (uint64_t)operand->mem.disp.value; - switch (instruction->addressWidth) - { - case 16: - address &= 0xFFFF; - break; - case 32: - address &= 0xFFFFFFFF; - break; - case 64: - break; - default: - return ZYDIS_STATUS_INVALID_PARAMETER; - } - } else - { - // EIP/RIP-relative - if ((formatter->addressFormat == ZYDIS_FORMATTER_ADDR_DEFAULT) || - (formatter->addressFormat == ZYDIS_FORMATTER_ADDR_ABSOLUTE)) - { - ZYDIS_CHECK(ZydisUtilsCalcAbsoluteTargetAddress(instruction, operand, &address)); - } else - { - absolute = ZYDIS_FALSE; - } - } - if (absolute) + // EIP/RIP-relative or absolute-displacement address operand + if ((formatter->addressFormat == ZYDIS_FORMATTER_ADDR_DEFAULT) || + (formatter->addressFormat == ZYDIS_FORMATTER_ADDR_ABSOLUTE) || + (operand->mem.base == ZYDIS_REGISTER_NONE)) { + uint64_t address; + ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address)); ZYDIS_CHECK(formatter->funcPrintAddress(formatter, buffer, bufEnd - *buffer, instruction, operand, address)); } else @@ -275,7 +248,7 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for case ZYDIS_FORMATTER_ADDR_ABSOLUTE: { uint64_t address; - ZYDIS_CHECK(ZydisUtilsCalcAbsoluteTargetAddress(instruction, operand, &address)); + ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address)); return formatter->funcPrintAddress(formatter, buffer, bufferLen, instruction, operand, address); } diff --git a/src/Utils.c b/src/Utils.c index 14c01c5..f1dcfd5 100644 --- a/src/Utils.c +++ b/src/Utils.c @@ -34,7 +34,7 @@ /* Exported functions */ /* ---------------------------------------------------------------------------------------------- */ -ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisDecodedInstruction* instruction, +ZydisStatus ZydisCalcAbsoluteAddress(const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, uint64_t* address) { if (!instruction || !operand || !address) @@ -59,6 +59,24 @@ ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisDecodedInstruction* i *address = (uint64_t)(instruction->instrPointer + operand->mem.disp.value); return ZYDIS_STATUS_SUCCESS; } + if ((operand->mem.base == ZYDIS_REGISTER_NONE) && + (operand->mem.index == ZYDIS_REGISTER_NONE)) + { + switch (instruction->addressWidth) + { + case 16: + *address = (uint64_t)operand->mem.disp.value & 0x000000000000FFFF; + return ZYDIS_STATUS_SUCCESS; + case 32: + *address = (uint64_t)operand->mem.disp.value & 0x00000000FFFFFFFF; + return ZYDIS_STATUS_SUCCESS; + case 64: + *address = (uint64_t)operand->mem.disp.value; + return ZYDIS_STATUS_SUCCESS; + default: + return ZYDIS_STATUS_INVALID_PARAMETER; + } + } break; case ZYDIS_OPERAND_TYPE_IMMEDIATE: if (operand->imm.isSigned && operand->imm.isRelative)