From 4165c3b9b27920e39618f1572fb06a3c4094a7e2 Mon Sep 17 00:00:00 2001 From: flobernd Date: Wed, 11 Jan 2017 11:20:24 +0100 Subject: [PATCH] Removed Input-struct. The input buffer is now directly passed to the ZydisDecodeInstruction function. --- examples/FormatterHooks.c | 10 +- include/Zydis/Decoder.h | 105 +++++++-------------- include/Zydis/Formatter.h | 4 +- include/Zydis/Input.h | 177 ----------------------------------- include/Zydis/Status.h | 1 + include/Zydis/Zydis.h | 1 - src/Decoder.c | 191 +++++++++++--------------------------- src/Input.c | 98 ------------------- src/Register.c | 2 +- 9 files changed, 97 insertions(+), 492 deletions(-) delete mode 100644 include/Zydis/Input.h delete mode 100644 src/Input.c diff --git a/examples/FormatterHooks.c b/examples/FormatterHooks.c index 0fc95d1..a3011d2 100644 --- a/examples/FormatterHooks.c +++ b/examples/FormatterHooks.c @@ -173,12 +173,8 @@ static ZydisStatus ZydisFormatterFormatOperandImm(ZydisInstructionFormatter* for void disassembleBuffer(uint8_t* data, size_t length, ZydisBool installHooks) { - ZydisMemoryInput input; - ZydisInputInitMemoryInput(&input, data, length); - ZydisInstructionDecoder decoder; - ZydisDecoderInitInstructionDecoderEx(&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT, - (ZydisCustomInput*)&input, ZYDIS_DECODER_FLAG_SKIP_DATA); + ZydisDecoderInitInstructionDecoder(&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT); ZydisDecoderSetInstructionPointer(&decoder, 0x007FFFFFFF400000); ZydisInstructionFormatter formatter; @@ -198,8 +194,10 @@ void disassembleBuffer(uint8_t* data, size_t length, ZydisBool installHooks) ZydisInstructionInfo info; char buffer[256]; - while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info))) + while (ZYDIS_SUCCESS(ZydisDecoderDecodeInstruction(&decoder, data, length, &info))) { + data += info.length; + length -= info.length; printf("%016" PRIX64 " ", info.instrAddress); ZydisFormatterFormatInstruction(&formatter, &info, &buffer[0], sizeof(buffer)); printf(" %s\n", &buffer[0]); diff --git a/include/Zydis/Decoder.h b/include/Zydis/Decoder.h index 1e4d0f0..dd47360 100644 --- a/include/Zydis/Decoder.h +++ b/include/Zydis/Decoder.h @@ -30,7 +30,6 @@ #include #include #include -#include #include #ifdef __cplusplus @@ -46,15 +45,7 @@ extern "C" { */ typedef uint32_t ZydisDecoderFlags; -/** - * @brief Set this flag if you do not want @c ZydisDecoderDecodeNextInstruction to fail with - * @c ZYDIS_STATUS_DECODING_ERROR, if an invalid instruction was found. - * - * If this flag is set, @c ZydisDecoderDecodeNextInstruction just skips one byte and - * returns @c ZYDIS_STATUS_SUCCESS. The returned @c ZydisInstructionInfo struct will - * have one of the @c ZYDIS_INSTRFLAG_ERROR_MASK flags set. - */ -#define ZYDIS_DECODER_FLAG_SKIP_DATA 0x00000001 +// TODO: Add flags to enable/disable certain decoding-steps like operands, affected flags, .. /* ---------------------------------------------------------------------------------------------- */ @@ -67,14 +58,16 @@ typedef struct ZydisInstructionDecoder_ * @brief The current disassembler-mode. */ ZydisDisassemblerMode disassemblerMode; + // TODO: Remove from this struct and pass as argument /** - * @brief A pointer to the current input data-source. + * @brief The current input buffer. */ - ZydisCustomInput* input; - /** - * @brief Decoder flags. - */ - ZydisDecoderFlags flags; + struct + { + uint8_t* buffer; + size_t bufferLen; + } input; + // TODO: (Maybe) remove from this struct and pass as argument /** * @brief The current instruction-pointer value. */ @@ -106,16 +99,6 @@ typedef struct ZydisInstructionDecoder_ * @brief Internal field. Contains the latest (significant) segment prefix. */ uint8_t lastSegmentPrefix; - /** - * @brief Internal buffer. - */ - struct - { - uint8_t data[30]; - uint8_t count; - uint8_t posRead; - uint8_t posWrite; - } buffer; } ZydisInstructionDecoder; /* ---------------------------------------------------------------------------------------------- */ @@ -129,50 +112,11 @@ typedef struct ZydisInstructionDecoder_ * * @param decoder A pointer to the @c ZydisInstructionDecoder instance. * @param disassemblerMode The desired disassembler-mode. - * @param input A pointer to the input data-source. * * @return A zydis status code. */ ZYDIS_EXPORT ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder, - ZydisDisassemblerMode disassemblerMode, ZydisCustomInput* input); - -/** - * @brief Initializes the given @c ZydisInstructionDecoder instance. - * - * @param decoder A pointer to the @c ZydisInstructionDecoder instance. - * @param disassemblerMode The desired disassembler-mode. - * @param input A pointer to the input data-source. - * @param flags Additional flags for the instruction-decoder. - * - * @return A zydis status code. - */ -ZYDIS_EXPORT ZydisStatus ZydisDecoderInitInstructionDecoderEx(ZydisInstructionDecoder* decoder, - ZydisDisassemblerMode disassemblerMode, ZydisCustomInput* input, ZydisDecoderFlags flags); - -/** - * @brief Returns the current input data-source of the given @c ZydisInstructionDecoder - * instance. - * - * @param decoder A pointer to the @c ZydisInstructionDecoder instance. - * @param input A pointer to the memory that receives the current input data-source pointer. - * - * @return A zydis status code. - */ -ZYDIS_EXPORT ZydisStatus ZydisDecoderGetInput(const ZydisInstructionDecoder* decoder, - ZydisCustomInput** input); - -/** - * @brief Changes the input data-source of the given @c ZydisInstructionDecoder instance. - * - * @param decoder A pointer to the @c ZydisInstructionDecoder instance. - * @param input A pointer to the new input data-source. - * - * @return A zydis status code. - * - * This function flushes the internal input-buffer. - */ -ZYDIS_EXPORT ZydisStatus ZydisDecoderSetInput(ZydisInstructionDecoder* decoder, - ZydisCustomInput* input); + ZydisDisassemblerMode disassemblerMode); /** * @brief Returns the current instruction-pointer of the given @c ZydisInstructionDecoder @@ -199,16 +143,33 @@ ZYDIS_EXPORT ZydisStatus ZydisDecoderSetInstructionPointer(ZydisInstructionDecod uint64_t instructionPointer); /** - * @brief Decodes the next instruction from the decoders input data-source. + * @brief Decodes the instruction in the given input @c buffer. * - * @param decoder A pointer to the @c ZydisInstructionDecoder instance. - * @param info A pointer to the @c ZydisInstructionInfo struct, that receives the details - * about the decoded instruction. + * @param decoder A pointer to the @c ZydisInstructionDecoder instance. + * @param buffer A pointer to the input buffer. + * @param bufferLen The length of the input buffer. + * @param info A pointer to the @c ZydisInstructionInfo struct, that receives the details + * about the decoded instruction. * * @return A zydis status code. */ -ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder, - ZydisInstructionInfo* info); +ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeInstruction(ZydisInstructionDecoder* decoder, + const void* buffer, size_t bufferLen, ZydisInstructionInfo* info); + +/** + * @brief Decodes the instruction in the given input @c buffer. + * + * @param decoder A pointer to the @c ZydisInstructionDecoder instance. + * @param buffer A pointer to the input buffer. + * @param bufferLen The length of the input buffer. + * @param flags Additional decoding flags. + * @param info A pointer to the @c ZydisInstructionInfo struct, that receives the details + * about the decoded instruction. + * + * @return A zydis status code. + */ +ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeInstructionEx(ZydisInstructionDecoder* decoder, + const void* buffer, size_t bufferLen, ZydisDecoderFlags flags, ZydisInstructionInfo* info); /* ============================================================================================== */ diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index e692e61..a15dc7d 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -451,8 +451,8 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* format * * @param formatter A pointer to the @c ZydisInstructionFormatter instance. * @param info A pointer to the @c ZydisInstructionInfo struct. - * @param buffer A pointer to the string-buffer buffer. - * @param bufferLen The length of the string-buffer. + * @param buffer A pointer to the output buffer. + * @param bufferLen The length of the output buffer. * * @return A zydis status code. */ diff --git a/include/Zydis/Input.h b/include/Zydis/Input.h deleted file mode 100644 index 7ddf744..0000000 --- a/include/Zydis/Input.h +++ /dev/null @@ -1,177 +0,0 @@ -/*************************************************************************************************** - - Zyan Disassembler Library (Zydis) - - Original Author : Florian Bernd - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - -***************************************************************************************************/ - -#ifndef ZYDIS_INPUT_H -#define ZYDIS_INPUT_H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* ============================================================================================== */ -/* Custom input */ -/* ============================================================================================== */ - -/* ---------------------------------------------------------------------------------------------- */ -/* Enums and types */ -/* ---------------------------------------------------------------------------------------------- */ - -typedef struct ZydisCustomInput_ ZydisCustomInput; - -/** - * @brief Defines the @c ZydisInputNextFunc function pointer used in the @c ZydisCustomInput - * struct. - * - * @param input The @c ZydisCustomInput instance. - * @param data A pointer to the memory that receives the input byte. - * - * @return Return @c TRUE, fi the function succeeded or @c FALSE, if the input data-source has no - * more data available - * - * This function should return the byte at the current input-position and increase the position - * by one. - */ -typedef ZydisBool (*ZydisInputNextFunc)(ZydisCustomInput* input, uint8_t* data); - -/** - * @brief Defines the zydis custom input struct. - */ -struct ZydisCustomInput_ -{ - /** - * @brief The @c ZydisInputNextFunc callback. - */ - ZydisInputNextFunc inputNext; -}; - -/* ---------------------------------------------------------------------------------------------- */ - -/* ============================================================================================== */ -/* Memory input */ -/* ============================================================================================== */ - -/* ---------------------------------------------------------------------------------------------- */ -/* Enums and types */ -/* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Defines the zydis memory input struct. - */ -typedef struct ZydisMemoryInput_ -{ - /** - * @brief The @c ZydisCustomInput base struct. - * - * This has to be the first element in every custom input data-source struct to ensure we - * can safely downcast it. - */ - ZydisCustomInput input; - /** - * @brief A pointer to the memory buffer. - */ - const uint8_t* inputBuffer; - /** - * @brief The length of the memory buffer. - */ - size_t inputBufferLen; - /** - * @brief The current input position. - */ - size_t inputBufferPos; -} ZydisMemoryInput; - -/* ---------------------------------------------------------------------------------------------- */ -/* Exported functions */ -/* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Initializes the given @c ZydisMemoryInput instance. - * - * @param input A pointer to the input data-source instance. - * @param buffer The memory buffer to use. - * @param length The length of the memory buffer. - * - * @return A zydis status code. - */ -ZYDIS_EXPORT ZydisStatus ZydisInputInitMemoryInput(ZydisMemoryInput* input, const void* buffer, - size_t length); - -/* ---------------------------------------------------------------------------------------------- */ - -/* ============================================================================================== */ -/* File input */ -/* ============================================================================================== */ - -/* ---------------------------------------------------------------------------------------------- */ -/* Enums and types */ -/* ---------------------------------------------------------------------------------------------- */ - -/** -* @brief Defines the zydis file input struct. -*/ -typedef struct ZydisFileInput_ -{ - /** - * @brief The @c ZydisCustomInput base struct. - * - * This has to be the first element in every custom input data-source struct to ensure we can - * safely downcast it. - */ - ZydisCustomInput input; - /** - * @brief The input file. - */ - FILE* file; -} ZydisFileInput; - -/* ---------------------------------------------------------------------------------------------- */ -/* Exported functions */ -/* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Initializes the given @c ZydisFileInput instance. - * - * @param input A pointer to the input data-source instance. - * @param file The file to use. You may freely `fseek` around after creation of the source. - * - * @return A zydis status code. - */ -ZYDIS_EXPORT ZydisStatus ZydisInputInitFileInput(ZydisFileInput* input, FILE* file); - -/* ---------------------------------------------------------------------------------------------- */ - -/* ============================================================================================== */ - -#ifdef __cplusplus -} -#endif - -#endif /* ZYDIS_INPUT_H */ diff --git a/include/Zydis/Status.h b/include/Zydis/Status.h index 76e9eb4..4bf3318 100644 --- a/include/Zydis/Status.h +++ b/include/Zydis/Status.h @@ -108,6 +108,7 @@ enum ZydisStatusCode */ ZYDIS_STATUS_MALFORMED_EVEX, // TODO: + ZYDIS_STATUS_INVALID_MASK, ZYDIS_STATUS_INVALID_VSIB, /* ------------------------------------------------------------------------------------------ */ diff --git a/include/Zydis/Zydis.h b/include/Zydis/Zydis.h index eefcdbe..ef9d7dd 100644 --- a/include/Zydis/Zydis.h +++ b/include/Zydis/Zydis.h @@ -33,7 +33,6 @@ #include #include #include -#include #include #include diff --git a/src/Decoder.c b/src/Decoder.c index 5ee1532..7d3d86b 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -85,27 +84,13 @@ static ZydisStatus ZydisInputPeek(ZydisInstructionDecoder* decoder, ZydisInstruc return ZYDIS_STATUS_INSTRUCTION_TOO_LONG; } - if (decoder->buffer.count > 0) + if (decoder->input.bufferLen > 0) { - ZYDIS_ASSERT(decoder->buffer.posRead < sizeof(decoder->buffer.data)); - *value = decoder->buffer.data[decoder->buffer.posRead]; + *value = decoder->input.buffer[0]; return ZYDIS_STATUS_SUCCESS; } - if (!decoder->input->inputNext((void*)decoder->input, value)) - { - return ZYDIS_STATUS_NO_MORE_DATA; - } - - ZYDIS_ASSERT(decoder->buffer.count < sizeof(decoder->buffer.data)); - decoder->buffer.data[decoder->buffer.posWrite++] = *value; - if (decoder->buffer.posWrite == sizeof(decoder->buffer.data)) - { - decoder->buffer.posWrite = 0; - } - ++decoder->buffer.count; - - return ZYDIS_STATUS_SUCCESS; + return ZYDIS_STATUS_NO_MORE_DATA; } /** @@ -128,12 +113,8 @@ static void ZydisInputSkip(ZydisInstructionDecoder* decoder, ZydisInstructionInf ZYDIS_ASSERT(info); ZYDIS_ASSERT(info->length < ZYDIS_MAX_INSTRUCTION_LENGTH); - info->data[info->length++] = decoder->buffer.data[decoder->buffer.posRead++]; - if (decoder->buffer.posRead == sizeof(decoder->buffer.data)) - { - decoder->buffer.posRead = 0; - } - --decoder->buffer.count; + info->data[info->length++] = decoder->input.buffer++[0]; + --decoder->input.bufferLen; } /** @@ -151,9 +132,24 @@ static void ZydisInputSkip(ZydisInstructionDecoder* decoder, ZydisInstructionInf static ZydisStatus ZydisInputNext(ZydisInstructionDecoder* decoder, ZydisInstructionInfo* info, uint8_t* value) { - ZYDIS_CHECK(ZydisInputPeek(decoder, info, value)); - ZydisInputSkip(decoder, info); - return ZYDIS_STATUS_SUCCESS; + ZYDIS_ASSERT(decoder); + ZYDIS_ASSERT(info); + ZYDIS_ASSERT(value); + + if (info->length >= ZYDIS_MAX_INSTRUCTION_LENGTH) + { + return ZYDIS_STATUS_INSTRUCTION_TOO_LONG; + } + + if (decoder->input.bufferLen > 0) + { + *value = decoder->input.buffer++[0]; + info->data[info->length++] = *value; + --decoder->input.bufferLen; + return ZYDIS_STATUS_SUCCESS; + } + + return ZYDIS_STATUS_NO_MORE_DATA; } /* ---------------------------------------------------------------------------------------------- */ @@ -1736,8 +1732,7 @@ static ZydisStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decoder, { uint8_t nextInput; ZYDIS_CHECK(ZydisInputPeek(decoder, info, &nextInput)); - if ((decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT) || - ((nextInput & 0xF0) >= 0xC0)) + if ((nextInput & 0xF0) >= 0xC0) { if (info->attributes & ZYDIS_ATTRIB_HAS_REX) { @@ -2183,22 +2178,16 @@ static ZydisStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder, if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW) { // Save input-buffer state and decode dummy operands - uint8_t bufferPosRead = decoder->buffer.posRead; + uint8_t* buffer = decoder->input.buffer; + size_t bufferLen = decoder->input.bufferLen; uint8_t length = info->length; ZYDIS_ASSERT(operandCount == 2); ZYDIS_CHECK(ZydisDecodeOperands(decoder, info, operands, operandCount)); // Read actual 3dnow opcode ZYDIS_CHECK(ZydisInputNext(decoder, info, &info->opcode)); // Restore input-buffer state - if (decoder->buffer.posWrite >= bufferPosRead) - { - decoder->buffer.count = decoder->buffer.posWrite - bufferPosRead; - } else - { - decoder->buffer.count = - decoder->buffer.posWrite + (sizeof(decoder->buffer.data) - bufferPosRead); - } - decoder->buffer.posRead = bufferPosRead; + decoder->input.buffer = buffer; + decoder->input.bufferLen = bufferLen; info->length = length; node = ZydisInstructionTableGetRootNode(); node = ZydisInstructionTableGetChildNode(node, 0x0F); @@ -2296,13 +2285,7 @@ static ZydisStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder, /* ============================================================================================== */ ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder, - ZydisDisassemblerMode disassemblerMode, ZydisCustomInput* input) -{ - return ZydisDecoderInitInstructionDecoderEx(decoder, disassemblerMode, input, 0); -} - -ZydisStatus ZydisDecoderInitInstructionDecoderEx(ZydisInstructionDecoder* decoder, - ZydisDisassemblerMode disassemblerMode, ZydisCustomInput* input, ZydisDecoderFlags flags) + ZydisDisassemblerMode disassemblerMode) { if (!decoder || ( (disassemblerMode != ZYDIS_DISASSEMBLER_MODE_16BIT) && @@ -2312,39 +2295,11 @@ ZydisStatus ZydisDecoderInitInstructionDecoderEx(ZydisInstructionDecoder* decode return ZYDIS_STATUS_INVALID_PARAMETER; } decoder->disassemblerMode = disassemblerMode; - decoder->input = input; - decoder->flags = flags; - decoder->buffer.count = 0; - decoder->buffer.posRead = 0; - decoder->buffer.posWrite = 0; + decoder->input.buffer = NULL; + decoder->input.bufferLen = 0; return ZYDIS_STATUS_SUCCESS; } -ZydisStatus ZydisDecoderGetInput(const ZydisInstructionDecoder* decoder, - ZydisCustomInput** input) -{ - if (!decoder || !input) - { - return ZYDIS_STATUS_INVALID_PARAMETER; - } - *input = decoder->input; - return ZYDIS_STATUS_SUCCESS; -} - -ZydisStatus ZydisDecoderSetInput(ZydisInstructionDecoder* decoder, - ZydisCustomInput* input) -{ - if (!decoder) - { - return ZYDIS_STATUS_INVALID_PARAMETER; - } - decoder->input = input; - decoder->buffer.count = 0; - decoder->buffer.posRead = 0; - decoder->buffer.posWrite = 0; - return ZYDIS_STATUS_SUCCESS; -} - ZydisStatus ZydisDecoderGetInstructionPointer(const ZydisInstructionDecoder* decoder, uint64_t* instructionPointer) { @@ -2367,18 +2322,28 @@ ZydisStatus ZydisDecoderSetInstructionPointer(ZydisInstructionDecoder* decoder, return ZYDIS_STATUS_SUCCESS; } -ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder, - ZydisInstructionInfo* info) +ZydisStatus ZydisDecoderDecodeInstruction(ZydisInstructionDecoder* decoder, + const void* buffer, size_t bufferLen, ZydisInstructionInfo* info) { + return ZydisDecoderDecodeInstructionEx(decoder, buffer, bufferLen, 0, info); +} + +ZydisStatus ZydisDecoderDecodeInstructionEx(ZydisInstructionDecoder* decoder, + const void* buffer, size_t bufferLen, ZydisDecoderFlags flags, ZydisInstructionInfo* info) +{ + (void)flags; + if (!decoder) { return ZYDIS_STATUS_INVALID_PARAMETER; } - if (!decoder->input) + if (!buffer || (bufferLen == 0)) { return ZYDIS_STATUS_NO_MORE_DATA; } + decoder->input.buffer = (uint8_t*)buffer; + decoder->input.bufferLen = bufferLen; decoder->hasUnusedPrefix66 = 0; decoder->hasUnusedPrefixF2F3 = 0; decoder->lastSegmentPrefix = 0; @@ -2399,19 +2364,11 @@ ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder, } info->userData = userData[5]; - uint8_t bufferPosRead = decoder->buffer.posRead; - - ZydisStatus status = ZydisCollectOptionalPrefixes(decoder, info); - if (status != ZYDIS_STATUS_SUCCESS) - { - goto DecodeError; - } - status = ZydisDecodeOpcode(decoder, info); - if (status != ZYDIS_STATUS_SUCCESS) - { - goto DecodeError; - } + ZYDIS_CHECK(ZydisCollectOptionalPrefixes(decoder, info)); + ZYDIS_CHECK(ZydisDecodeOpcode(decoder, info)); + // TODO: The index, dest and mask regs for AVX2 gathers must be different. + // TODO: More EVEX UD conditions (page 81) // Set AVX-512 info if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) { @@ -2447,23 +2404,27 @@ ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder, case ZYDIS_AVX512_MASKPOLICY_MASK_REQUIRED: if (info->details.evex.aaa == 0) { - return ZYDIS_STATUS_INVALID_REGISTER; + return ZYDIS_STATUS_INVALID_MASK; } info->avx.maskRegister = ZYDIS_REGISTER_K0 + info->details.evex.aaa; break; case ZYDIS_AVX512_MASKPOLICY_MASK_FORBIDDEN: if (info->details.evex.aaa != 0) { - return ZYDIS_STATUS_INVALID_REGISTER; + return ZYDIS_STATUS_INVALID_MASK; } info->avx.maskRegister = ZYDIS_REGISTER_K0; break; default: ZYDIS_UNREACHABLE; } - if (definition->evexZeroMaskAccepted && info->details.evex.z) + if (info->details.evex.z) { - info->avx.maskMode = ZYDIS_AVX512_MASKMODE_ZERO; + if (!definition->evexZeroMaskAccepted) + { + return ZYDIS_STATUS_INVALID_MASK; + } + info->avx.maskMode = ZYDIS_AVX512_MASKMODE_MERGE; } else { info->avx.maskMode = ZYDIS_AVX512_MASKMODE_MERGE; @@ -2490,46 +2451,6 @@ ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder, info->instrPointer = decoder->instructionPointer; return ZYDIS_STATUS_SUCCESS; - -DecodeError: -{ - uint8_t firstByte = info->data[0]; - uint64_t instrAddress = info->instrAddress; - memset(info, 0, sizeof(*info)); - - if (decoder->buffer.posWrite >= bufferPosRead) - { - decoder->buffer.count = decoder->buffer.posWrite - bufferPosRead; - } else - { - decoder->buffer.count = - decoder->buffer.posWrite + (sizeof(decoder->buffer.data) - bufferPosRead); - } - decoder->buffer.posRead = bufferPosRead; - if (status == ZYDIS_STATUS_NO_MORE_DATA) - { - return status; - } - --decoder->buffer.count; - ++decoder->buffer.posRead; - if (decoder->buffer.posRead == sizeof(decoder->buffer.data)) - { - decoder->buffer.posRead = 0; - } - - ++decoder->instructionPointer; - info->mode = decoder->disassemblerMode; - info->length = 1; - info->data[0] = firstByte; - info->instrAddress = instrAddress; - info->instrPointer = decoder->instructionPointer; - - if (!decoder->flags & ZYDIS_DECODER_FLAG_SKIP_DATA) - { - return ZYDIS_STATUS_DECODING_ERROR; - } -} - return ZYDIS_STATUS_SUCCESS; } /* ============================================================================================== */ diff --git a/src/Input.c b/src/Input.c deleted file mode 100644 index 7a7af5a..0000000 --- a/src/Input.c +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************************************** - - Zyan Disassembler Library (Zydis) - - Original Author : Florian Bernd - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - -***************************************************************************************************/ - -#include - -/* ============================================================================================== */ -/* Memory input */ -/* ============================================================================================== */ - -/* ---------------------------------------------------------------------------------------------- */ -/* Internal functions */ -/* ---------------------------------------------------------------------------------------------- */ - -static ZydisBool ZydisMemoryInputNext(ZydisMemoryInput* input, uint8_t* data) -{ - if (input->inputBufferPos >= input->inputBufferLen) - { - return ZYDIS_FALSE; - } - *data = input->inputBuffer[input->inputBufferPos++]; - return ZYDIS_TRUE; -} - -/* ---------------------------------------------------------------------------------------------- */ -/* Exported functions */ -/* ---------------------------------------------------------------------------------------------- */ - -ZydisStatus ZydisInputInitMemoryInput(ZydisMemoryInput* input, const void* buffer, size_t length) -{ - if (!input || !buffer || (length == 0)) - { - return ZYDIS_STATUS_INVALID_PARAMETER; - } - input->input.inputNext = (ZydisInputNextFunc)&ZydisMemoryInputNext; - input->inputBuffer = (uint8_t*)buffer; - input->inputBufferLen = length; - input->inputBufferPos = 0; - return ZYDIS_STATUS_SUCCESS; -} - -/* ---------------------------------------------------------------------------------------------- */ - -/* ============================================================================================== */ -/* File input */ -/* ============================================================================================== */ - -/* ---------------------------------------------------------------------------------------------- */ -/* Internal functions */ -/* ---------------------------------------------------------------------------------------------- */ - -static ZydisBool ZydisFileInputNext(ZydisFileInput* input, uint8_t* data) -{ - int c = fgetc(input->file); - *data = (uint8_t)c; - return (c != EOF); -} - -/* ---------------------------------------------------------------------------------------------- */ -/* Exported functions */ -/* ---------------------------------------------------------------------------------------------- */ - -ZydisStatus ZydisInputInitFileInput(ZydisFileInput* input, FILE* file) -{ - if (!file) - { - return ZYDIS_STATUS_INVALID_PARAMETER; - } - input->input.inputNext = (ZydisInputNextFunc)&ZydisFileInputNext; - input->file = file; - return ZYDIS_STATUS_SUCCESS; -} - -/* ---------------------------------------------------------------------------------------------- */ - -/* ============================================================================================== */ diff --git a/src/Register.c b/src/Register.c index 69ff10f..c001169 100644 --- a/src/Register.c +++ b/src/Register.c @@ -111,7 +111,7 @@ const char* registerStrings[] = "dr12", "dr13", "dr14", "dr15", // Mask registers "k0", "k1", "k2", "k3", - "k4", "k5", "k6", "k7", + "k4", "k5", "k6", "k7", // Bounds registers "bnd0", "bnd1", "bnd2", "bnd3", "bndcfg", "bndstatus"