mirror of https://github.com/x64dbg/zydis
Removed Input-struct. The input buffer is now directly passed to the ZydisDecodeInstruction function.
This commit is contained in:
parent
b291c8a760
commit
4165c3b9b2
|
@ -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]);
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <Zydis/Defines.h>
|
||||
#include <Zydis/Types.h>
|
||||
#include <Zydis/Status.h>
|
||||
#include <Zydis/Input.h>
|
||||
#include <Zydis/InstructionInfo.h>
|
||||
|
||||
#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);
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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 */
|
|
@ -108,6 +108,7 @@ enum ZydisStatusCode
|
|||
*/
|
||||
ZYDIS_STATUS_MALFORMED_EVEX,
|
||||
// TODO:
|
||||
ZYDIS_STATUS_INVALID_MASK,
|
||||
ZYDIS_STATUS_INVALID_VSIB,
|
||||
|
||||
/* ------------------------------------------------------------------------------------------ */
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include <Zydis/Mnemonic.h>
|
||||
#include <Zydis/Register.h>
|
||||
#include <Zydis/InstructionInfo.h>
|
||||
#include <Zydis/Input.h>
|
||||
#include <Zydis/Decoder.h>
|
||||
#include <Zydis/Formatter.h>
|
||||
|
||||
|
|
191
src/Decoder.c
191
src/Decoder.c
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <Zydis/Status.h>
|
||||
#include <Zydis/Input.h>
|
||||
#include <Zydis/Decoder.h>
|
||||
#include <Zydis/Internal/InstructionTable.h>
|
||||
|
||||
|
@ -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,36 +2295,8 @@ 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;
|
||||
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;
|
||||
decoder->input.buffer = NULL;
|
||||
decoder->input.bufferLen = 0;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
|
98
src/Input.c
98
src/Input.c
|
@ -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;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue