diff --git a/src/Decoder.c b/src/Decoder.c index 40fecf7..726085f 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -524,7 +524,7 @@ static ZydisStatus ZydisDecodeOperandImmediate(ZydisInstructionDecoder* decoder, case 32: { uint32_t data[4] = { 0, 0, 0, 0 }; - for (int i = sizeof(data) / sizeof(data[0]); i > 0; --i) + for (int i = ZYDIS_ARRAY_SIZE(data); i > 0; --i) { ZYDIS_CHECK(ZydisInputNext(decoder, info, (uint8_t*)&data[i - 1])); } @@ -1255,6 +1255,7 @@ static ZydisStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, ZydisIns case ZYDIS_SEM_OPERAND_TYPE_REL8: info->attributes |= ZYDIS_ATTRIB_IS_RELATIVE; operand->imm.isRelative = ZYDIS_TRUE; + // Intentional fallthrough. case ZYDIS_SEM_OPERAND_TYPE_IMM8: operand->size = 8; operand->imm.isSigned = ZYDIS_TRUE; @@ -1266,6 +1267,7 @@ static ZydisStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, ZydisIns case ZYDIS_SEM_OPERAND_TYPE_REL16: info->attributes |= ZYDIS_ATTRIB_IS_RELATIVE; operand->imm.isRelative = ZYDIS_TRUE; + // Intentional fallthrough. case ZYDIS_SEM_OPERAND_TYPE_IMM16: operand->size = 16; operand->imm.isSigned = ZYDIS_TRUE; @@ -1280,6 +1282,7 @@ static ZydisStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, ZydisIns case ZYDIS_SEM_OPERAND_TYPE_REL64: info->attributes |= ZYDIS_ATTRIB_IS_RELATIVE; operand->imm.isRelative = ZYDIS_TRUE; + // Intentional fallthrough. case ZYDIS_SEM_OPERAND_TYPE_IMM64: operand->size = 64; operand->imm.isSigned = ZYDIS_TRUE; @@ -2383,6 +2386,16 @@ ZydisStatus ZydisDecoderDecodeInstructionEx(ZydisInstructionDecoder* decoder, } } + // For relative operands, apply instruction length offset. + for (size_t i = 0; i < info->operandCount; ++i) + { + if (info->operands[i].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && + info->operands[i].imm.isRelative) + { + info->operands[i].imm.value.sqword += info->length; + } + } + // Replace XCHG rAX, rAX with NOP alias if (info->mnemonic == ZYDIS_MNEMONIC_XCHG) {