This commit is contained in:
Joel Höner 2017-01-21 01:48:35 +01:00
commit 03e26408fe
7 changed files with 74 additions and 133 deletions

View File

@ -36,6 +36,8 @@
#include <inttypes.h> #include <inttypes.h>
#include <Zydis/Zydis.h> #include <Zydis/Zydis.h>
#include "FormatHelper.h" #include "FormatHelper.h"
#include <stdlib.h>
#include <time.h>
/* ============================================================================================== */ /* ============================================================================================== */
/* Static data */ /* Static data */
@ -46,38 +48,38 @@
*/ */
static const char* conditionCodeStrings[0x20] = static const char* conditionCodeStrings[0x20] =
{ {
"eq", /*00*/ "eq",
"lt", /*01*/ "lt",
"le", /*02*/ "le",
"unord", /*03*/ "unord",
"neq", /*04*/ "neq",
"nlt", /*05*/ "nlt",
"nle", /*06*/ "nle",
"ord", /*07*/ "ord",
"eq_uq", /*08*/ "eq_uq",
"nge", /*09*/ "nge",
"ngt", /*0A*/ "ngt",
"false", /*0B*/ "false",
"oq", /*0C*/ "oq",
"ge", /*0D*/ "ge",
"gt", /*0E*/ "gt",
"true", /*0F*/ "true",
"eq_os", /*10*/ "eq_os",
"lt_oq", /*11*/ "lt_oq",
"le_oq", /*12*/ "le_oq",
"unord_s", /*13*/ "unord_s",
"neq_us", /*14*/ "neq_us",
"nlt_uq", /*15*/ "nlt_uq",
"nle_uq", /*16*/ "nle_uq",
"ord_s", /*17*/ "ord_s",
"eq_us", /*18*/ "eq_us",
"nge_uq", /*19*/ "nge_uq",
"ngt_uq", /*1A*/ "ngt_uq",
"false_os", /*1B*/ "false_os",
"neq_os", /*1C*/ "neq_os",
"ge_oq", /*1D*/ "ge_oq",
"gt_oq", /*1E*/ "gt_oq",
"true_us" /*1F*/ "true_us"
}; };
/* ============================================================================================== */ /* ============================================================================================== */
@ -175,7 +177,6 @@ void disassembleBuffer(uint8_t* data, size_t length, ZydisBool installHooks)
{ {
ZydisInstructionDecoder decoder; ZydisInstructionDecoder decoder;
ZydisDecoderInitInstructionDecoder(&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT); ZydisDecoderInitInstructionDecoder(&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT);
ZydisDecoderSetInstructionPointer(&decoder, 0x007FFFFFFF400000);
ZydisInstructionFormatter formatter; ZydisInstructionFormatter formatter;
ZydisFormatterInitInstructionFormatterEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, ZydisFormatterInitInstructionFormatterEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL,
@ -191,13 +192,17 @@ void disassembleBuffer(uint8_t* data, size_t length, ZydisBool installHooks)
ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM,
(const void**)&defaultFormatOperandImm); (const void**)&defaultFormatOperandImm);
} }
uint64_t instructionPointer = 0x007FFFFFFF400000;
ZydisInstructionInfo info; ZydisInstructionInfo info;
char buffer[256]; char buffer[256];
while (ZYDIS_SUCCESS(ZydisDecoderDecodeInstruction(&decoder, data, length, &info))) while (ZYDIS_SUCCESS(
ZydisDecoderDecodeInstruction(&decoder, data, length, instructionPointer, &info)))
{ {
data += info.length; data += info.length;
length -= info.length; length -= info.length;
instructionPointer += 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

@ -67,11 +67,6 @@ typedef struct ZydisInstructionDecoder_
const uint8_t* buffer; const uint8_t* buffer;
size_t bufferLen; size_t bufferLen;
} input; } input;
// TODO: (Maybe) remove from this struct and pass as argument
/**
* @brief The current instruction-pointer value.
*/
uint64_t instructionPointer;
/** /**
* @brief Internal field. @c TRUE, if the @c imm8 value is already initialized. * @brief Internal field. @c TRUE, if the @c imm8 value is already initialized.
*/ */
@ -118,58 +113,37 @@ typedef struct ZydisInstructionDecoder_
ZYDIS_EXPORT ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder, ZYDIS_EXPORT ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder,
ZydisDisassemblerMode disassemblerMode); ZydisDisassemblerMode disassemblerMode);
/**
* @brief Returns the current instruction-pointer of the given @c ZydisInstructionDecoder
* instance.
*
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
* @param instructionPointer A pointer to the memory that receives the current
* instruction-pointer.
*
* @return A zydis status code.
*/
ZYDIS_EXPORT ZydisStatus ZydisDecoderGetInstructionPointer(
const ZydisInstructionDecoder* decoder, uint64_t* instructionPointer);
/**
* @brief Changes the instruction-pointer of the given @c ZydisInstructionDecoder instance.
*
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
* @param instructionPointer The new instruction-pointer value.
*
* @return A zydis status code.
*/
ZYDIS_EXPORT ZydisStatus ZydisDecoderSetInstructionPointer(ZydisInstructionDecoder* decoder,
uint64_t instructionPointer);
/** /**
* @brief Decodes the instruction in the given input @c buffer. * @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 buffer A pointer to the input buffer. * @param buffer A pointer to the input buffer.
* @param bufferLen The length of the input buffer. * @param bufferLen The length of the input buffer.
* @param info A pointer to the @c ZydisInstructionInfo struct, that receives the details * @param instructionPointer The instruction-pointer.
* about the decoded instruction. * @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 ZydisDecoderDecodeInstruction(ZydisInstructionDecoder* decoder, ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeInstruction(ZydisInstructionDecoder* decoder,
const void* buffer, size_t bufferLen, ZydisInstructionInfo* info); const void* buffer, size_t bufferLen, uint64_t instructionPointer, ZydisInstructionInfo* info);
/** /**
* @brief Decodes the instruction in the given input @c buffer. * @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 buffer A pointer to the input buffer. * @param buffer A pointer to the input buffer.
* @param bufferLen The length of the input buffer. * @param bufferLen The length of the input buffer.
* @param flags Additional decoding flags. * @param instructionPointer The instruction-pointer.
* @param info A pointer to the @c ZydisInstructionInfo struct, that receives the details * @param flags Additional decoding flags.
* about the decoded instruction. * @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 ZydisDecoderDecodeInstructionEx(ZydisInstructionDecoder* decoder, ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeInstructionEx(ZydisInstructionDecoder* decoder,
const void* buffer, size_t bufferLen, ZydisDecoderFlags flags, ZydisInstructionInfo* info); const void* buffer, size_t bufferLen, uint64_t instructionPointer, ZydisDecoderFlags flags,
ZydisInstructionInfo* info);
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -382,10 +382,6 @@ typedef struct ZydisOperandInfo_
*/ */
uint8_t dataOffset; uint8_t dataOffset;
} imm; } imm;
/**
* @brief This field is intended for custom data and may be freely set by the user.
*/
void* userData;
} ZydisOperandInfo; } ZydisOperandInfo;
/* ============================================================================================== */ /* ============================================================================================== */
@ -502,7 +498,7 @@ typedef uint64_t ZydisInstructionAttributes;
/** /**
* @brief The instruction has the EVEX prefix. * @brief The instruction has the EVEX prefix.
*/ */
#define ZYDIS_ATTRIB_HAS_EVEX 0x0000000000000020 #define ZYDIS_ATTRIB_HAS_EVEX 0x0000000000000020
/** /**
* @brief The instruction has one or more operands with position-relative offsets. * @brief The instruction has one or more operands with position-relative offsets.
*/ */
@ -547,7 +543,7 @@ typedef uint64_t ZydisInstructionAttributes;
*/ */
#define ZYDIS_ATTRIB_ACCEPTS_XACQUIRE 0x0000000000002000 #define ZYDIS_ATTRIB_ACCEPTS_XACQUIRE 0x0000000000002000
/** /**
* @brief The instruction accepts the xrelease prefix (0xF2). * @brief The instruction accepts the xrelease prefix (0xF3).
*/ */
#define ZYDIS_ATTRIB_ACCEPTS_XRELEASE 0x0000000000004000 #define ZYDIS_ATTRIB_ACCEPTS_XRELEASE 0x0000000000004000
/** /**

View File

@ -85,7 +85,7 @@ enum ZydisStatusCode
/** /**
* @brief The instruction encoded an invalid register. * @brief The instruction encoded an invalid register.
*/ */
ZYDIS_STATUS_INVALID_REGISTER, ZYDIS_STATUS_BAD_REGISTER,
/** /**
* @brief A lock-prefix (F0) was found while decoding an instruction that does not support * @brief A lock-prefix (F0) was found while decoding an instruction that does not support
* locking. * locking.
@ -154,13 +154,14 @@ enum ZydisStatusCode
* @param status The zydis status-code to check. * @param status The zydis status-code to check.
*/ */
#define ZYDIS_CHECK(status) \ #define ZYDIS_CHECK(status) \
do \
{ \ { \
ZydisStatus s = status; \ ZydisStatus s = status; \
if (!ZYDIS_SUCCESS(s)) \ if (!ZYDIS_SUCCESS(s)) \
{ \ { \
return s; \ return s; \
} \ } \
} } while(0)
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -600,7 +600,7 @@ static ZydisStatus ZydisDecodeOperandRegister(ZydisInstructionInfo* info,
operand->reg = ZydisRegisterEncode(registerClass, registerId); operand->reg = ZydisRegisterEncode(registerClass, registerId);
if (!operand->reg) if (!operand->reg)
{ {
return ZYDIS_STATUS_INVALID_REGISTER; return ZYDIS_STATUS_BAD_REGISTER;
} }
} }
@ -2275,40 +2275,18 @@ ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder,
decoder->disassemblerMode = disassemblerMode; decoder->disassemblerMode = disassemblerMode;
decoder->input.buffer = NULL; decoder->input.buffer = NULL;
decoder->input.bufferLen = 0; decoder->input.bufferLen = 0;
decoder->instructionPointer = 0;
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
} }
ZydisStatus ZydisDecoderGetInstructionPointer(const ZydisInstructionDecoder* decoder,
uint64_t* instructionPointer)
{
if (!decoder || !instructionPointer)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
*instructionPointer = decoder->instructionPointer;
return ZYDIS_STATUS_SUCCESS;
}
ZydisStatus ZydisDecoderSetInstructionPointer(ZydisInstructionDecoder* decoder,
uint64_t instructionPointer)
{
if (!decoder)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
decoder->instructionPointer = instructionPointer;
return ZYDIS_STATUS_SUCCESS;
}
ZydisStatus ZydisDecoderDecodeInstruction(ZydisInstructionDecoder* decoder, ZydisStatus ZydisDecoderDecodeInstruction(ZydisInstructionDecoder* decoder,
const void* buffer, size_t bufferLen, ZydisInstructionInfo* info) const void* buffer, size_t bufferLen, uint64_t instructionPointer, ZydisInstructionInfo* info)
{ {
return ZydisDecoderDecodeInstructionEx(decoder, buffer, bufferLen, 0, info); return ZydisDecoderDecodeInstructionEx(decoder, buffer, bufferLen, instructionPointer, 0, info);
} }
ZydisStatus ZydisDecoderDecodeInstructionEx(ZydisInstructionDecoder* decoder, ZydisStatus ZydisDecoderDecodeInstructionEx(ZydisInstructionDecoder* decoder,
const void* buffer, size_t bufferLen, ZydisDecoderFlags flags, ZydisInstructionInfo* info) const void* buffer, size_t bufferLen, uint64_t instructionPointer, ZydisDecoderFlags flags,
ZydisInstructionInfo* info)
{ {
(void)flags; (void)flags;
@ -2328,20 +2306,11 @@ ZydisStatus ZydisDecoderDecodeInstructionEx(ZydisInstructionDecoder* decoder,
decoder->lastSegmentPrefix = 0; decoder->lastSegmentPrefix = 0;
decoder->imm8initialized = ZYDIS_FALSE; decoder->imm8initialized = ZYDIS_FALSE;
void* userData[6]; void* userData = info->userData;
for (int i = 0; i < 5; ++i)
{
userData[i] = info->operands[i].userData;
}
userData[5] = info->userData;
memset(info, 0, sizeof(*info)); memset(info, 0, sizeof(*info));
info->mode = decoder->disassemblerMode; info->mode = decoder->disassemblerMode;
info->instrAddress = decoder->instructionPointer; info->instrAddress = instructionPointer;
for (int i = 0; i < 5; ++i) info->userData = userData;
{
info->operands[i].userData = userData[i];
}
info->userData = userData[5];
ZYDIS_CHECK(ZydisCollectOptionalPrefixes(decoder, info)); ZYDIS_CHECK(ZydisCollectOptionalPrefixes(decoder, info));
ZYDIS_CHECK(ZydisDecodeOpcode(decoder, info)); ZYDIS_CHECK(ZydisDecodeOpcode(decoder, info));
@ -2426,9 +2395,6 @@ ZydisStatus ZydisDecoderDecodeInstructionEx(ZydisInstructionDecoder* decoder,
} }
} }
decoder->instructionPointer += info->length;
info->instrPointer = decoder->instructionPointer;
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
} }

View File

@ -592,14 +592,14 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(ZydisInstructionFormatter* fo
switch (operand->mem.segment) switch (operand->mem.segment)
{ {
case ZYDIS_REGISTER_ES: case ZYDIS_REGISTER_ES:
case ZYDIS_REGISTER_SS: case ZYDIS_REGISTER_CS:
case ZYDIS_REGISTER_FS: case ZYDIS_REGISTER_FS:
case ZYDIS_REGISTER_GS: case ZYDIS_REGISTER_GS:
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:", return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:",
ZydisRegisterGetString(operand->mem.segment)); ZydisRegisterGetString(operand->mem.segment));
case ZYDIS_REGISTER_CS: case ZYDIS_REGISTER_SS:
if ((formatter->flags & ZYDIS_FMTFLAG_FORCE_SEGMENTS) || if ((formatter->flags & ZYDIS_FMTFLAG_FORCE_SEGMENTS) ||
(info->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_CS)) (info->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS))
{ {
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:", return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:",
ZydisRegisterGetString(operand->mem.segment)); ZydisRegisterGetString(operand->mem.segment));

View File

@ -132,7 +132,6 @@ struct ZydisRegisterMapItem
static const struct ZydisRegisterMapItem registerMap[] = static const struct ZydisRegisterMapItem registerMap[] =
{ {
{ ZYDIS_REGCLASS_INVALID , ZYDIS_REGISTER_NONE , ZYDIS_REGISTER_NONE , 0 , 0 },
{ ZYDIS_REGCLASS_GPR8 , ZYDIS_REGISTER_AL , ZYDIS_REGISTER_R15B , 8 , 8 }, { ZYDIS_REGCLASS_GPR8 , ZYDIS_REGISTER_AL , ZYDIS_REGISTER_R15B , 8 , 8 },
{ ZYDIS_REGCLASS_GPR16 , ZYDIS_REGISTER_AX , ZYDIS_REGISTER_R15W , 16 , 16 }, { ZYDIS_REGCLASS_GPR16 , ZYDIS_REGISTER_AX , ZYDIS_REGISTER_R15W , 16 , 16 },
{ ZYDIS_REGCLASS_GPR32 , ZYDIS_REGISTER_EAX , ZYDIS_REGISTER_R15D , 32 , 32 }, { ZYDIS_REGCLASS_GPR32 , ZYDIS_REGISTER_EAX , ZYDIS_REGISTER_R15D , 32 , 32 },
@ -146,8 +145,8 @@ static const struct ZydisRegisterMapItem registerMap[] =
{ ZYDIS_REGCLASS_IP , ZYDIS_REGISTER_RIP , ZYDIS_REGISTER_IP , 0 , 0 }, { ZYDIS_REGCLASS_IP , ZYDIS_REGISTER_RIP , ZYDIS_REGISTER_IP , 0 , 0 },
{ ZYDIS_REGCLASS_SEGMENT , ZYDIS_REGISTER_ES , ZYDIS_REGISTER_GS , 16 , 16 }, { ZYDIS_REGCLASS_SEGMENT , ZYDIS_REGISTER_ES , ZYDIS_REGISTER_GS , 16 , 16 },
{ ZYDIS_REGCLASS_TEST , ZYDIS_REGISTER_TR0 , ZYDIS_REGISTER_TR7 , 32 , 32 }, { ZYDIS_REGCLASS_TEST , ZYDIS_REGISTER_TR0 , ZYDIS_REGISTER_TR7 , 32 , 32 },
{ ZYDIS_REGCLASS_CONTROL , ZYDIS_REGISTER_CR0 , ZYDIS_REGISTER_CR7 , 32 , 64 }, { ZYDIS_REGCLASS_CONTROL , ZYDIS_REGISTER_CR0 , ZYDIS_REGISTER_CR15 , 32 , 64 },
{ ZYDIS_REGCLASS_DEBUG , ZYDIS_REGISTER_DR0 , ZYDIS_REGISTER_DR7 , 32 , 64 }, { ZYDIS_REGCLASS_DEBUG , ZYDIS_REGISTER_DR0 , ZYDIS_REGISTER_DR15 , 32 , 64 },
{ ZYDIS_REGCLASS_MASK , ZYDIS_REGISTER_K0 , ZYDIS_REGISTER_K7 , 64 , 64 }, { ZYDIS_REGCLASS_MASK , ZYDIS_REGISTER_K0 , ZYDIS_REGISTER_K7 , 64 , 64 },
{ ZYDIS_REGCLASS_BOUND , ZYDIS_REGISTER_BND0 , ZYDIS_REGISTER_BND3 , 128 , 128 } { ZYDIS_REGCLASS_BOUND , ZYDIS_REGISTER_BND0 , ZYDIS_REGISTER_BND3 , 128 , 128 }
}; };