From 03ef968413663ade22d105616e21343114a80a53 Mon Sep 17 00:00:00 2001 From: flobernd Date: Wed, 26 Jul 2017 18:17:59 +0200 Subject: [PATCH 1/4] `REX.R` and `REX.B` is ignored for non-GPR/VR/CR/DR registers --- src/Decoder.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/Decoder.c b/src/Decoder.c index 272a3d9..6c47043 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -920,9 +920,21 @@ static uint8_t ZydisCalcRegisterId(ZydisDecoderContext* context, { ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); uint8_t value = instruction->raw.modrm.reg; - if (registerClass != ZYDIS_REGCLASS_MASK) + switch (registerClass) { - value |= (context->cache.R << 3); + case ZYDIS_REGCLASS_GPR8: + case ZYDIS_REGCLASS_GPR16: + case ZYDIS_REGCLASS_GPR32: + case ZYDIS_REGCLASS_GPR64: + case ZYDIS_REGCLASS_XMM: + case ZYDIS_REGCLASS_YMM: + case ZYDIS_REGCLASS_ZMM: + case ZYDIS_REGCLASS_CONTROL: + case ZYDIS_REGCLASS_DEBUG: + value |= (context->cache.R << 3); + break; + default: + break; } // R' only exists for EVEX and MVEX. No encoding check needed switch (registerClass) @@ -954,9 +966,21 @@ static uint8_t ZydisCalcRegisterId(ZydisDecoderContext* context, { ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); uint8_t value = instruction->raw.modrm.rm; - if (registerClass != ZYDIS_REGCLASS_MASK) + switch (registerClass) { - value |= (context->cache.B << 3); + case ZYDIS_REGCLASS_GPR8: + case ZYDIS_REGCLASS_GPR16: + case ZYDIS_REGCLASS_GPR32: + case ZYDIS_REGCLASS_GPR64: + case ZYDIS_REGCLASS_XMM: + case ZYDIS_REGCLASS_YMM: + case ZYDIS_REGCLASS_ZMM: + case ZYDIS_REGCLASS_CONTROL: + case ZYDIS_REGCLASS_DEBUG: + value |= (context->cache.B << 3); + break; + default: + break; } // We have to check the instruction-encoding, because the extension by X is only valid // for EVEX and MVEX instructions From a525342b4216fb85439b6d6970aae09aa1ffc6ba Mon Sep 17 00:00:00 2001 From: flobernd Date: Wed, 9 Aug 2017 17:25:45 +0200 Subject: [PATCH 2/4] Fixed README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e5d223b..ae3ddf4 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ int main() ZydisDecodedInstruction instruction; char buffer[256]; while (ZYDIS_SUCCESS( - ZydisDecoderDecodeBuffer(decoder, data, length, instructionPointer, &instruction))) + ZydisDecoderDecodeBuffer(&decoder, &data[0], length, instructionPointer, &instruction))) { data += instruction.length; length -= instruction.length; From 705f0ed5cd4afc22ecfbb69cc93ab3b913d1af3f Mon Sep 17 00:00:00 2001 From: flobernd Date: Sat, 12 Aug 2017 04:33:02 +0200 Subject: [PATCH 3/4] Minor changes to the performance test tool --- examples/ZydisPerfTest.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/ZydisPerfTest.c b/examples/ZydisPerfTest.c index 7b5445a..271bab7 100644 --- a/examples/ZydisPerfTest.c +++ b/examples/ZydisPerfTest.c @@ -156,7 +156,7 @@ void testPerformance(const char* buffer, size_t length, ZydisDecodeGranularity g { count += processBuffer(buffer, length, granularity, format); } - printf("Granularity %d, Formatting %d, Instructions: ~%6.2fM, Time: %8.2f msec\n", + printf("Granularity %d, Formatting %d, Instructions: %6.2fM, Time: %8.2f msec\n", granularity, format, (double)count / 1000000, GetCounter()); } @@ -171,9 +171,9 @@ void generateTestData(FILE* file, uint8_t encoding) } uint8_t last = 0; - double size = 0; + uint32_t count = 0; ZydisDecodedInstruction instruction; - while (size < 1024 * 1024) + while (count < 100000) { uint8_t data[ZYDIS_MAX_INSTRUCTION_LENGTH]; for (int i = 0; i < ZYDIS_MAX_INSTRUCTION_LENGTH; ++i) @@ -235,13 +235,13 @@ void generateTestData(FILE* file, uint8_t encoding) if (b) { fwrite(&instruction.data[0], 1, instruction.length, file); - size += instruction.length; + ++count; - double p = (size / (1024 * 1024) * 100); - if (last < (uint8_t)p) + uint8_t p = (uint8_t)((double)count / 100000 * 100); + if (last < p) { - last = (uint8_t)p; - printf("%3.0f%%\n", p); + last = p; + printf("%3.0d%%\n", p); } } From 74484aec2e253462c43b50f450d034f3b5ebaf53 Mon Sep 17 00:00:00 2001 From: flobernd Date: Mon, 14 Aug 2017 17:10:24 +0200 Subject: [PATCH 4/4] Removed trailing whitespace after mnemonic for instructions without visible operands --- src/Formatter.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Formatter.c b/src/Formatter.c index 061febb..0f16935 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -857,11 +857,6 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte ZYDIS_CHECK(formatter->funcPrintMnemonic(formatter, buffer, bufEnd - *buffer, instruction)); char* bufRestore = *buffer; - if (instruction->operandCount > 0) - { - ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, 0, " ")); - } - for (uint8_t i = 0; i < instruction->operandCount; ++i) { if (instruction->operands[i].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN) @@ -869,7 +864,10 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte break; } - if (i != 0) + if (i == 0) + { + ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, 0, " ")); + } else { bufRestore = *buffer; ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, 0, ", "));