Removed Input-struct. The input buffer is now directly passed to the ZydisDecodeInstruction function.

This commit is contained in:
flobernd 2017-01-11 11:20:24 +01:00
parent b291c8a760
commit 4165c3b9b2
9 changed files with 97 additions and 492 deletions

View File

@ -173,12 +173,8 @@ static ZydisStatus ZydisFormatterFormatOperandImm(ZydisInstructionFormatter* for
void disassembleBuffer(uint8_t* data, size_t length, ZydisBool installHooks) void disassembleBuffer(uint8_t* data, size_t length, ZydisBool installHooks)
{ {
ZydisMemoryInput input;
ZydisInputInitMemoryInput(&input, data, length);
ZydisInstructionDecoder decoder; ZydisInstructionDecoder decoder;
ZydisDecoderInitInstructionDecoderEx(&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT, ZydisDecoderInitInstructionDecoder(&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT);
(ZydisCustomInput*)&input, ZYDIS_DECODER_FLAG_SKIP_DATA);
ZydisDecoderSetInstructionPointer(&decoder, 0x007FFFFFFF400000); ZydisDecoderSetInstructionPointer(&decoder, 0x007FFFFFFF400000);
ZydisInstructionFormatter formatter; ZydisInstructionFormatter formatter;
@ -198,8 +194,10 @@ void disassembleBuffer(uint8_t* data, size_t length, ZydisBool installHooks)
ZydisInstructionInfo info; ZydisInstructionInfo info;
char buffer[256]; 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); printf("%016" PRIX64 " ", info.instrAddress);
ZydisFormatterFormatInstruction(&formatter, &info, &buffer[0], sizeof(buffer)); ZydisFormatterFormatInstruction(&formatter, &info, &buffer[0], sizeof(buffer));
printf(" %s\n", &buffer[0]); printf(" %s\n", &buffer[0]);

View File

@ -30,7 +30,6 @@
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Types.h> #include <Zydis/Types.h>
#include <Zydis/Status.h> #include <Zydis/Status.h>
#include <Zydis/Input.h>
#include <Zydis/InstructionInfo.h> #include <Zydis/InstructionInfo.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -46,15 +45,7 @@ extern "C" {
*/ */
typedef uint32_t ZydisDecoderFlags; typedef uint32_t ZydisDecoderFlags;
/** // TODO: Add flags to enable/disable certain decoding-steps like operands, affected flags, ..
* @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
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -67,14 +58,16 @@ typedef struct ZydisInstructionDecoder_
* @brief The current disassembler-mode. * @brief The current disassembler-mode.
*/ */
ZydisDisassemblerMode disassemblerMode; 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; struct
/** {
* @brief Decoder flags. uint8_t* buffer;
*/ size_t bufferLen;
ZydisDecoderFlags flags; } input;
// TODO: (Maybe) remove from this struct and pass as argument
/** /**
* @brief The current instruction-pointer value. * @brief The current instruction-pointer value.
*/ */
@ -106,16 +99,6 @@ typedef struct ZydisInstructionDecoder_
* @brief Internal field. Contains the latest (significant) segment prefix. * @brief Internal field. Contains the latest (significant) segment prefix.
*/ */
uint8_t lastSegmentPrefix; uint8_t lastSegmentPrefix;
/**
* @brief Internal buffer.
*/
struct
{
uint8_t data[30];
uint8_t count;
uint8_t posRead;
uint8_t posWrite;
} buffer;
} ZydisInstructionDecoder; } ZydisInstructionDecoder;
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -129,50 +112,11 @@ typedef struct ZydisInstructionDecoder_
* *
* @param decoder A pointer to the @c ZydisInstructionDecoder instance. * @param decoder A pointer to the @c ZydisInstructionDecoder instance.
* @param disassemblerMode The desired disassembler-mode. * @param disassemblerMode The desired disassembler-mode.
* @param input A pointer to the input data-source.
* *
* @return A zydis status code. * @return A zydis status code.
*/ */
ZYDIS_EXPORT ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder, ZYDIS_EXPORT ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder,
ZydisDisassemblerMode disassemblerMode, ZydisCustomInput* input); ZydisDisassemblerMode disassemblerMode);
/**
* @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);
/** /**
* @brief Returns the current instruction-pointer of the given @c ZydisInstructionDecoder * @brief Returns the current instruction-pointer of the given @c ZydisInstructionDecoder
@ -199,16 +143,33 @@ ZYDIS_EXPORT ZydisStatus ZydisDecoderSetInstructionPointer(ZydisInstructionDecod
uint64_t instructionPointer); 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 decoder A pointer to the @c ZydisInstructionDecoder instance.
* @param info A pointer to the @c ZydisInstructionInfo struct, that receives the details * @param buffer A pointer to the input buffer.
* about the decoded instruction. * @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. * @return A zydis status code.
*/ */
ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder, ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeInstruction(ZydisInstructionDecoder* decoder,
ZydisInstructionInfo* info); 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);
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -451,8 +451,8 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* format
* *
* @param formatter A pointer to the @c ZydisInstructionFormatter instance. * @param formatter A pointer to the @c ZydisInstructionFormatter instance.
* @param info A pointer to the @c ZydisInstructionInfo struct. * @param info A pointer to the @c ZydisInstructionInfo struct.
* @param buffer A pointer to the string-buffer buffer. * @param buffer A pointer to the output buffer.
* @param bufferLen The length of the string-buffer. * @param bufferLen The length of the output buffer.
* *
* @return A zydis status code. * @return A zydis status code.
*/ */

View File

@ -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 <stdio.h>
#include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h>
#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 */

View File

@ -108,6 +108,7 @@ enum ZydisStatusCode
*/ */
ZYDIS_STATUS_MALFORMED_EVEX, ZYDIS_STATUS_MALFORMED_EVEX,
// TODO: // TODO:
ZYDIS_STATUS_INVALID_MASK,
ZYDIS_STATUS_INVALID_VSIB, ZYDIS_STATUS_INVALID_VSIB,
/* ------------------------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------------------------ */

View File

@ -33,7 +33,6 @@
#include <Zydis/Mnemonic.h> #include <Zydis/Mnemonic.h>
#include <Zydis/Register.h> #include <Zydis/Register.h>
#include <Zydis/InstructionInfo.h> #include <Zydis/InstructionInfo.h>
#include <Zydis/Input.h>
#include <Zydis/Decoder.h> #include <Zydis/Decoder.h>
#include <Zydis/Formatter.h> #include <Zydis/Formatter.h>

View File

@ -26,7 +26,6 @@
#include <string.h> #include <string.h>
#include <Zydis/Status.h> #include <Zydis/Status.h>
#include <Zydis/Input.h>
#include <Zydis/Decoder.h> #include <Zydis/Decoder.h>
#include <Zydis/Internal/InstructionTable.h> #include <Zydis/Internal/InstructionTable.h>
@ -85,27 +84,13 @@ static ZydisStatus ZydisInputPeek(ZydisInstructionDecoder* decoder, ZydisInstruc
return ZYDIS_STATUS_INSTRUCTION_TOO_LONG; 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->input.buffer[0];
*value = decoder->buffer.data[decoder->buffer.posRead];
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
} }
if (!decoder->input->inputNext((void*)decoder->input, value)) return ZYDIS_STATUS_NO_MORE_DATA;
{
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;
} }
/** /**
@ -128,12 +113,8 @@ static void ZydisInputSkip(ZydisInstructionDecoder* decoder, ZydisInstructionInf
ZYDIS_ASSERT(info); ZYDIS_ASSERT(info);
ZYDIS_ASSERT(info->length < ZYDIS_MAX_INSTRUCTION_LENGTH); ZYDIS_ASSERT(info->length < ZYDIS_MAX_INSTRUCTION_LENGTH);
info->data[info->length++] = decoder->buffer.data[decoder->buffer.posRead++]; info->data[info->length++] = decoder->input.buffer++[0];
if (decoder->buffer.posRead == sizeof(decoder->buffer.data)) --decoder->input.bufferLen;
{
decoder->buffer.posRead = 0;
}
--decoder->buffer.count;
} }
/** /**
@ -151,9 +132,24 @@ static void ZydisInputSkip(ZydisInstructionDecoder* decoder, ZydisInstructionInf
static ZydisStatus ZydisInputNext(ZydisInstructionDecoder* decoder, ZydisInstructionInfo* info, static ZydisStatus ZydisInputNext(ZydisInstructionDecoder* decoder, ZydisInstructionInfo* info,
uint8_t* value) uint8_t* value)
{ {
ZYDIS_CHECK(ZydisInputPeek(decoder, info, value)); ZYDIS_ASSERT(decoder);
ZydisInputSkip(decoder, info); ZYDIS_ASSERT(info);
return ZYDIS_STATUS_SUCCESS; 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; uint8_t nextInput;
ZYDIS_CHECK(ZydisInputPeek(decoder, info, &nextInput)); ZYDIS_CHECK(ZydisInputPeek(decoder, info, &nextInput));
if ((decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT) || if ((nextInput & 0xF0) >= 0xC0)
((nextInput & 0xF0) >= 0xC0))
{ {
if (info->attributes & ZYDIS_ATTRIB_HAS_REX) if (info->attributes & ZYDIS_ATTRIB_HAS_REX)
{ {
@ -2183,22 +2178,16 @@ static ZydisStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW) if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW)
{ {
// Save input-buffer state and decode dummy operands // 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; uint8_t length = info->length;
ZYDIS_ASSERT(operandCount == 2); ZYDIS_ASSERT(operandCount == 2);
ZYDIS_CHECK(ZydisDecodeOperands(decoder, info, operands, operandCount)); ZYDIS_CHECK(ZydisDecodeOperands(decoder, info, operands, operandCount));
// Read actual 3dnow opcode // Read actual 3dnow opcode
ZYDIS_CHECK(ZydisInputNext(decoder, info, &info->opcode)); ZYDIS_CHECK(ZydisInputNext(decoder, info, &info->opcode));
// Restore input-buffer state // Restore input-buffer state
if (decoder->buffer.posWrite >= bufferPosRead) decoder->input.buffer = buffer;
{ decoder->input.bufferLen = bufferLen;
decoder->buffer.count = decoder->buffer.posWrite - bufferPosRead;
} else
{
decoder->buffer.count =
decoder->buffer.posWrite + (sizeof(decoder->buffer.data) - bufferPosRead);
}
decoder->buffer.posRead = bufferPosRead;
info->length = length; info->length = length;
node = ZydisInstructionTableGetRootNode(); node = ZydisInstructionTableGetRootNode();
node = ZydisInstructionTableGetChildNode(node, 0x0F); node = ZydisInstructionTableGetChildNode(node, 0x0F);
@ -2296,13 +2285,7 @@ static ZydisStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
/* ============================================================================================== */ /* ============================================================================================== */
ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder, ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder,
ZydisDisassemblerMode disassemblerMode, ZydisCustomInput* input) ZydisDisassemblerMode disassemblerMode)
{
return ZydisDecoderInitInstructionDecoderEx(decoder, disassemblerMode, input, 0);
}
ZydisStatus ZydisDecoderInitInstructionDecoderEx(ZydisInstructionDecoder* decoder,
ZydisDisassemblerMode disassemblerMode, ZydisCustomInput* input, ZydisDecoderFlags flags)
{ {
if (!decoder || ( if (!decoder || (
(disassemblerMode != ZYDIS_DISASSEMBLER_MODE_16BIT) && (disassemblerMode != ZYDIS_DISASSEMBLER_MODE_16BIT) &&
@ -2312,39 +2295,11 @@ ZydisStatus ZydisDecoderInitInstructionDecoderEx(ZydisInstructionDecoder* decode
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
decoder->disassemblerMode = disassemblerMode; decoder->disassemblerMode = disassemblerMode;
decoder->input = input; decoder->input.buffer = NULL;
decoder->flags = flags; decoder->input.bufferLen = 0;
decoder->buffer.count = 0;
decoder->buffer.posRead = 0;
decoder->buffer.posWrite = 0;
return ZYDIS_STATUS_SUCCESS; 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, ZydisStatus ZydisDecoderGetInstructionPointer(const ZydisInstructionDecoder* decoder,
uint64_t* instructionPointer) uint64_t* instructionPointer)
{ {
@ -2367,18 +2322,28 @@ ZydisStatus ZydisDecoderSetInstructionPointer(ZydisInstructionDecoder* decoder,
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
} }
ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder, ZydisStatus ZydisDecoderDecodeInstruction(ZydisInstructionDecoder* decoder,
ZydisInstructionInfo* info) 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) if (!decoder)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
if (!decoder->input) if (!buffer || (bufferLen == 0))
{ {
return ZYDIS_STATUS_NO_MORE_DATA; return ZYDIS_STATUS_NO_MORE_DATA;
} }
decoder->input.buffer = (uint8_t*)buffer;
decoder->input.bufferLen = bufferLen;
decoder->hasUnusedPrefix66 = 0; decoder->hasUnusedPrefix66 = 0;
decoder->hasUnusedPrefixF2F3 = 0; decoder->hasUnusedPrefixF2F3 = 0;
decoder->lastSegmentPrefix = 0; decoder->lastSegmentPrefix = 0;
@ -2399,19 +2364,11 @@ ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder,
} }
info->userData = userData[5]; info->userData = userData[5];
uint8_t bufferPosRead = decoder->buffer.posRead; ZYDIS_CHECK(ZydisCollectOptionalPrefixes(decoder, info));
ZYDIS_CHECK(ZydisDecodeOpcode(decoder, info));
ZydisStatus status = ZydisCollectOptionalPrefixes(decoder, info);
if (status != ZYDIS_STATUS_SUCCESS)
{
goto DecodeError;
}
status = ZydisDecodeOpcode(decoder, info);
if (status != ZYDIS_STATUS_SUCCESS)
{
goto DecodeError;
}
// TODO: The index, dest and mask regs for AVX2 gathers must be different.
// TODO: More EVEX UD conditions (page 81)
// Set AVX-512 info // Set AVX-512 info
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX)
{ {
@ -2447,23 +2404,27 @@ ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder,
case ZYDIS_AVX512_MASKPOLICY_MASK_REQUIRED: case ZYDIS_AVX512_MASKPOLICY_MASK_REQUIRED:
if (info->details.evex.aaa == 0) 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; info->avx.maskRegister = ZYDIS_REGISTER_K0 + info->details.evex.aaa;
break; break;
case ZYDIS_AVX512_MASKPOLICY_MASK_FORBIDDEN: case ZYDIS_AVX512_MASKPOLICY_MASK_FORBIDDEN:
if (info->details.evex.aaa != 0) if (info->details.evex.aaa != 0)
{ {
return ZYDIS_STATUS_INVALID_REGISTER; return ZYDIS_STATUS_INVALID_MASK;
} }
info->avx.maskRegister = ZYDIS_REGISTER_K0; info->avx.maskRegister = ZYDIS_REGISTER_K0;
break; break;
default: default:
ZYDIS_UNREACHABLE; 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 } else
{ {
info->avx.maskMode = ZYDIS_AVX512_MASKMODE_MERGE; info->avx.maskMode = ZYDIS_AVX512_MASKMODE_MERGE;
@ -2490,46 +2451,6 @@ ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder,
info->instrPointer = decoder->instructionPointer; info->instrPointer = decoder->instructionPointer;
return ZYDIS_STATUS_SUCCESS; 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;
} }
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -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 <Zydis/Input.h>
/* ============================================================================================== */
/* 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;
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */

View File

@ -111,7 +111,7 @@ const char* registerStrings[] =
"dr12", "dr13", "dr14", "dr15", "dr12", "dr13", "dr14", "dr15",
// Mask registers // Mask registers
"k0", "k1", "k2", "k3", "k0", "k1", "k2", "k3",
"k4", "k5", "k6", "k7", "k4", "k5", "k6", "k7",
// Bounds registers // Bounds registers
"bnd0", "bnd1", "bnd2", "bnd3", "bnd0", "bnd1", "bnd2", "bnd3",
"bndcfg", "bndstatus" "bndcfg", "bndstatus"