mirror of https://github.com/x64dbg/zydis
Merge branch 'develop' of github.com:zyantific/zyan-disassembler-engine into develop
This commit is contained in:
commit
839729bfb2
|
@ -6,21 +6,21 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
|||
|
||||
option(ZYDIS_BUILD_SHARED_LIBS
|
||||
"Build shared libraries rather than static ones"
|
||||
FALSE)
|
||||
OFF)
|
||||
option(ZYDIS_FORCE_SHARED_CRT
|
||||
"Forces shared linkage against the CRT even when building a static library"
|
||||
FALSE)
|
||||
"Forces shared linkage against the CRT even when building a static library. MSVC only."
|
||||
OFF)
|
||||
option(ZYDIS_FEATURE_IMPLICITLY_USED_REGISTERS
|
||||
"Include information about implicitly used registers"
|
||||
TRUE)
|
||||
OFF)
|
||||
option(ZYDIS_FEATURE_AFFECTED_FLAGS
|
||||
"Include information about affected flags"
|
||||
TRUE)
|
||||
OFF)
|
||||
option(ZYDIS_FEATURE_CPUID
|
||||
"Include information about CPUID feature-flags"
|
||||
FALSE)
|
||||
option(ZYDIS_BUILD_EXAMPLES "Build examples" TRUE)
|
||||
option(ZYDIS_BUILD_TOOLS "Build tools" TRUE)
|
||||
OFF)
|
||||
option(ZYDIS_BUILD_EXAMPLES "Build examples" ON)
|
||||
option(ZYDIS_BUILD_TOOLS "Build tools" ON)
|
||||
|
||||
if (NOT CONFIGURED_ONCE)
|
||||
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
|
||||
|
@ -49,7 +49,7 @@ endif ()
|
|||
# Library
|
||||
set(headers
|
||||
"include/Zydis/Decoder.h"
|
||||
"include/Zydis/Encoder.h"
|
||||
#"include/Zydis/Encoder.h"
|
||||
"include/Zydis/Defines.h"
|
||||
"include/Zydis/Formatter.h"
|
||||
"include/Zydis/InstructionInfo.h"
|
||||
|
@ -62,7 +62,7 @@ set(headers
|
|||
"include/Zydis/Internal/InstructionTable.h")
|
||||
set(sources
|
||||
"src/Decoder.c"
|
||||
"src/Encoder.c"
|
||||
#"src/Encoder.c"
|
||||
"src/Formatter.c"
|
||||
"src/InstructionTable.c"
|
||||
"src/Mnemonic.c"
|
||||
|
|
|
@ -931,7 +931,7 @@ begin
|
|||
begin
|
||||
O := NodeData^.Definition.Operands.Operands[I];
|
||||
S := S + IntToStr(Integer(O.OperandType)) + ',' + IntToStr(Integer(O.Encoding)) + ',' +
|
||||
IntToStr(Integer(O.AccessMode)) + ',';
|
||||
IntToStr(Integer(O.Action)) + ',';
|
||||
end;
|
||||
Clipboard.AsText := S;
|
||||
end;
|
||||
|
@ -959,7 +959,7 @@ begin
|
|||
O := NodeData^.Definition.Operands.Operands[J];
|
||||
O.OperandType := TOperandType(StrToInt(A[I]));
|
||||
O.Encoding := TOperandEncoding(StrToInt(A[I + 1]));
|
||||
O.AccessMode := TOperandAccessMode(StrToInt(A[I + 2]));
|
||||
O.Action := TOperandAction(StrToInt(A[I + 2]));
|
||||
Inc(I, 3);
|
||||
Inc(J);
|
||||
end;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <Zydis/Decoder.h>
|
||||
#include <Zydis/Formatter.h>
|
||||
#include <Zydis/Encoder.h>
|
||||
#include <Zydis/Utils.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -524,7 +524,7 @@ static ZydisStatus ZydisDecodeOperandImmediate(ZydisInstructionDecoder* decoder,
|
|||
case 32:
|
||||
{
|
||||
uint32_t data[4] = { 0, 0, 0, 0 };
|
||||
for (int i = sizeof(data) / sizeof(data[0]); i > 0; --i)
|
||||
for (int i = ZYDIS_ARRAY_SIZE(data); i > 0; --i)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisInputNext(decoder, info, (uint8_t*)&data[i - 1]));
|
||||
}
|
||||
|
@ -1255,6 +1255,7 @@ static ZydisStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, ZydisIns
|
|||
case ZYDIS_SEM_OPERAND_TYPE_REL8:
|
||||
info->attributes |= ZYDIS_ATTRIB_IS_RELATIVE;
|
||||
operand->imm.isRelative = ZYDIS_TRUE;
|
||||
// Intentional fallthrough.
|
||||
case ZYDIS_SEM_OPERAND_TYPE_IMM8:
|
||||
operand->size = 8;
|
||||
operand->imm.isSigned = ZYDIS_TRUE;
|
||||
|
@ -1266,6 +1267,7 @@ static ZydisStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, ZydisIns
|
|||
case ZYDIS_SEM_OPERAND_TYPE_REL16:
|
||||
info->attributes |= ZYDIS_ATTRIB_IS_RELATIVE;
|
||||
operand->imm.isRelative = ZYDIS_TRUE;
|
||||
// Intentional fallthrough.
|
||||
case ZYDIS_SEM_OPERAND_TYPE_IMM16:
|
||||
operand->size = 16;
|
||||
operand->imm.isSigned = ZYDIS_TRUE;
|
||||
|
@ -1280,6 +1282,7 @@ static ZydisStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, ZydisIns
|
|||
case ZYDIS_SEM_OPERAND_TYPE_REL64:
|
||||
info->attributes |= ZYDIS_ATTRIB_IS_RELATIVE;
|
||||
operand->imm.isRelative = ZYDIS_TRUE;
|
||||
// Intentional fallthrough.
|
||||
case ZYDIS_SEM_OPERAND_TYPE_IMM64:
|
||||
operand->size = 64;
|
||||
operand->imm.isSigned = ZYDIS_TRUE;
|
||||
|
@ -2383,6 +2386,16 @@ ZydisStatus ZydisDecoderDecodeInstructionEx(ZydisInstructionDecoder* decoder,
|
|||
}
|
||||
}
|
||||
|
||||
// For relative operands, apply instruction length offset.
|
||||
for (size_t i = 0; i < info->operandCount; ++i)
|
||||
{
|
||||
if (info->operands[i].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||
info->operands[i].imm.isRelative)
|
||||
{
|
||||
info->operands[i].imm.value.sqword += info->length;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace XCHG rAX, rAX with NOP alias
|
||||
if (info->mnemonic == ZYDIS_MNEMONIC_XCHG)
|
||||
{
|
||||
|
|
223
src/Encoder.c
223
src/Encoder.c
|
@ -78,10 +78,11 @@ typedef struct ZydisEncoderTableEntry_
|
|||
ZydisEncoderTableOperand operands[5];
|
||||
ZydisOpcodeMap map;
|
||||
ZydisInstructionAttributes attribs;
|
||||
ZydisModRMMod modRmMod;
|
||||
ZydisModeConstraint modeConstraint;
|
||||
ZydisPrefixBit prefixBits;
|
||||
uint8_t mandatoryPrefix; // 0x00 = None
|
||||
uint8_t modrmReg; // 0xFF = None
|
||||
const char* cmt;
|
||||
} ZydisEncoderTableEntry;
|
||||
|
||||
struct ZydisPrefixAcceptMapping
|
||||
|
@ -250,8 +251,8 @@ static ZydisStatus ZydisEmitVEX(ZydisEncoderContext* ctx)
|
|||
ZYDIS_ASSERT(ctx);
|
||||
|
||||
// Can we use short 2-byte VEX encoding?
|
||||
if (ctx->info->details.vex.X == 1 &&
|
||||
ctx->info->details.vex.B == 1 &&
|
||||
if (ctx->info->details.vex.X == 0 &&
|
||||
ctx->info->details.vex.B == 0 &&
|
||||
ctx->info->details.vex.W == 0 &&
|
||||
ctx->info->details.vex.m_mmmm == 1)
|
||||
{
|
||||
|
@ -419,6 +420,8 @@ static ZydisStatus ZydisPrepareOpcode(ZydisEncoderContext* ctx)
|
|||
static ZydisStatus ZydisSimplifyOperandType(ZydisSemanticOperandType semType,
|
||||
ZydisOperandType* simpleType)
|
||||
{
|
||||
ZYDIS_ASSERT(simpleType);
|
||||
|
||||
// TODO: Better mapping, this is just for testing.
|
||||
switch (semType)
|
||||
{
|
||||
|
@ -454,6 +457,8 @@ static ZydisStatus ZydisSimplifyOperandType(ZydisSemanticOperandType semType,
|
|||
static ZydisStatus ZydisPrepareRegOperand(ZydisEncoderContext* ctx,
|
||||
ZydisRegister reg, char topBitLoc)
|
||||
{
|
||||
ZYDIS_ASSERT(ctx);
|
||||
|
||||
int16_t regID = ZydisRegisterGetId(reg);
|
||||
if (regID == -1) return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
|
||||
|
@ -467,9 +472,11 @@ static ZydisStatus ZydisPrepareRegOperand(ZydisEncoderContext* ctx,
|
|||
case 'X': ctx->info->details.sib.index = lowerBits; break;
|
||||
default: ZYDIS_UNREACHABLE;
|
||||
}
|
||||
|
||||
// No top bit? Quick exit.
|
||||
if (!topBit) return ZYDIS_STATUS_SUCCESS;
|
||||
|
||||
uint8_t* topBitDst = NULL;
|
||||
|
||||
switch (ctx->info->encoding)
|
||||
{
|
||||
case ZYDIS_INSTRUCTION_ENCODING_DEFAULT:
|
||||
|
@ -527,21 +534,73 @@ static ZydisBool ZydisIsBPReg(ZydisRegister reg)
|
|||
reg == ZYDIS_REGISTER_RBP;
|
||||
}
|
||||
|
||||
static ZydisBool ZydisIsStackReg(ZydisRegister reg)
|
||||
static ZydisBool ZydisIsSPReg(ZydisRegister reg)
|
||||
{
|
||||
return reg == ZYDIS_REGISTER_SPL ||
|
||||
reg == ZYDIS_REGISTER_SP ||
|
||||
reg == ZYDIS_REGISTER_ESP ||
|
||||
reg == ZYDIS_REGISTER_RSP ||
|
||||
ZydisIsBPReg(reg);
|
||||
reg == ZYDIS_REGISTER_RSP;
|
||||
}
|
||||
|
||||
static ZydisBool ZydisIsIPReg(ZydisRegister reg)
|
||||
{
|
||||
return reg == ZYDIS_REGISTER_IP ||
|
||||
reg == ZYDIS_REGISTER_EIP ||
|
||||
reg == ZYDIS_REGISTER_RIP;
|
||||
}
|
||||
|
||||
static ZydisBool ZydisIsStackReg(ZydisRegister reg)
|
||||
{
|
||||
return ZydisIsSPReg(reg) || ZydisIsBPReg(reg);
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisPrepareSegmentPrefix(ZydisEncoderContext* ctx,
|
||||
ZydisRegister segment, ZydisRegister base)
|
||||
{
|
||||
// Segment prefix required?
|
||||
switch (segment)
|
||||
{
|
||||
case ZYDIS_REGISTER_ES:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_ES;
|
||||
break;
|
||||
case ZYDIS_REGISTER_SS:
|
||||
if (!ZydisIsStackReg(base))
|
||||
{
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_SS;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_REGISTER_CS:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_CS;
|
||||
break;
|
||||
case ZYDIS_REGISTER_DS:
|
||||
if (ZydisIsStackReg(base))
|
||||
{
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_DS;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_REGISTER_FS:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_FS;
|
||||
break;
|
||||
case ZYDIS_REGISTER_GS:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_GS;
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO: Better status.
|
||||
}
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisPrepareMemoryOperand(ZydisEncoderContext* ctx,
|
||||
ZydisOperandInfo* operand, const ZydisEncoderTableOperand* tableEntry)
|
||||
{
|
||||
// TODO: RIP relative addressing
|
||||
ZYDIS_ASSERT(ctx);
|
||||
ZYDIS_ASSERT(operand);
|
||||
ZYDIS_ASSERT(tableEntry);
|
||||
|
||||
// Absolute memory access?
|
||||
ZYDIS_CHECK(ZydisPrepareSegmentPrefix(ctx, operand->mem.segment, operand->mem.base));
|
||||
|
||||
// Absolute memory access? Special case.
|
||||
if (operand->mem.base == ZYDIS_REGISTER_NONE)
|
||||
{
|
||||
ctx->disp = operand->mem.disp.value.sdword;
|
||||
|
@ -567,6 +626,34 @@ static ZydisStatus ZydisPrepareMemoryOperand(ZydisEncoderContext* ctx,
|
|||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// rIP relative addressing? Special case.
|
||||
if (ZydisIsIPReg(operand->mem.base))
|
||||
{
|
||||
// rIP addressing is only available since AMD64.
|
||||
if (ctx->info->mode != ZYDIS_DISASSEMBLER_MODE_64BIT)
|
||||
{
|
||||
return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO
|
||||
}
|
||||
|
||||
// Only available with either EIP or RIP, not with IP.
|
||||
if (operand->mem.base == ZYDIS_REGISTER_IP)
|
||||
{
|
||||
return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO
|
||||
}
|
||||
|
||||
ctx->disp = operand->mem.disp.value.sdword;
|
||||
ctx->dispBitSize = 32;
|
||||
ctx->info->details.modrm.mod = 0x00;
|
||||
ctx->info->details.modrm.rm = 0x05 /* RIP relative mem */;
|
||||
|
||||
if (operand->mem.base == ZYDIS_REGISTER_EIP)
|
||||
{
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_ADDRESSSIZE;
|
||||
}
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Process base register.
|
||||
ZYDIS_CHECK(ZydisPrepareRegOperand(ctx, operand->mem.base, 'B'));
|
||||
|
||||
|
@ -612,49 +699,13 @@ static ZydisStatus ZydisPrepareMemoryOperand(ZydisEncoderContext* ctx,
|
|||
return ZYDIS_STATUS_INVALID_PARAMETER; // TODO
|
||||
}
|
||||
|
||||
// Segment prefix required?
|
||||
switch (operand->mem.segment)
|
||||
// SIB byte required? rSP can only be encoded with SIB.
|
||||
if (operand->mem.index || operand->mem.scale || ZydisIsSPReg(operand->mem.base))
|
||||
{
|
||||
case ZYDIS_REGISTER_ES:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_ES;
|
||||
break;
|
||||
case ZYDIS_REGISTER_SS:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_SS;
|
||||
break;
|
||||
case ZYDIS_REGISTER_CS:
|
||||
if (!ZydisIsStackReg(operand->mem.base))
|
||||
{
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_CS;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_REGISTER_DS:
|
||||
if (ZydisIsStackReg(operand->mem.base))
|
||||
{
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_DS;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_REGISTER_FS:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_FS;
|
||||
break;
|
||||
case ZYDIS_REGISTER_GS:
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SEGMENT_GS;
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO: Better status.
|
||||
}
|
||||
|
||||
// SIB byte required?
|
||||
if (operand->mem.index || operand->mem.scale)
|
||||
{
|
||||
// Base and index register must be of same register class, verify.
|
||||
if (ZydisRegisterGetClass(operand->mem.index) != baseRegClass)
|
||||
{
|
||||
return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO
|
||||
}
|
||||
|
||||
// Translate scale to SIB format.
|
||||
switch (operand->mem.scale)
|
||||
{
|
||||
case 0: // We take 0 (uninitialized, 0 from memset) as * 1.
|
||||
case 1: ctx->info->details.sib.scale = 0x00; break;
|
||||
case 2: ctx->info->details.sib.scale = 0x01; break;
|
||||
case 4: ctx->info->details.sib.scale = 0x02; break;
|
||||
|
@ -662,11 +713,25 @@ static ZydisStatus ZydisPrepareMemoryOperand(ZydisEncoderContext* ctx,
|
|||
default: return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO
|
||||
}
|
||||
|
||||
// Base & index register.
|
||||
// Move base register info to SIB.
|
||||
ctx->info->details.sib.base = ctx->info->details.modrm.rm;
|
||||
ZYDIS_CHECK(ZydisPrepareRegOperand(ctx, operand->mem.index, 'X'));
|
||||
|
||||
ctx->info->details.modrm.rm = 0x04 /* SIB */;
|
||||
|
||||
// Process index register.
|
||||
if (operand->mem.index != ZYDIS_REGISTER_NONE)
|
||||
{
|
||||
// Base and index register must be of same register class, verify.
|
||||
if (ZydisRegisterGetClass(operand->mem.index) != baseRegClass)
|
||||
{
|
||||
return ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION; // TODO
|
||||
}
|
||||
ZYDIS_CHECK(ZydisPrepareRegOperand(ctx, operand->mem.index, 'X'));
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->info->details.sib.index = 0x04 /* no index */;
|
||||
}
|
||||
|
||||
ctx->info->attributes |= ZYDIS_ATTRIB_HAS_SIB;
|
||||
}
|
||||
|
||||
|
@ -727,12 +792,33 @@ static ZydisStatus ZydisPrepareMemoryOperand(ZydisEncoderContext* ctx,
|
|||
static ZydisStatus ZydisPrepareOperand(ZydisEncoderContext* ctx,
|
||||
ZydisOperandInfo* operand, const ZydisEncoderTableOperand* tableEntry)
|
||||
{
|
||||
ZYDIS_ASSERT(ctx);
|
||||
ZYDIS_ASSERT(operand);
|
||||
ZYDIS_ASSERT(tableEntry);
|
||||
|
||||
switch (tableEntry->encoding)
|
||||
{
|
||||
case ZYDIS_OPERAND_ENCODING_NONE:
|
||||
break; // Nothing to do.
|
||||
// For some encodings, we have to switch on the sem op type.
|
||||
switch (tableEntry->type)
|
||||
{
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MOFFS16:
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MOFFS32:
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MOFFS64:
|
||||
ZYDIS_CHECK(ZydisPrepareSegmentPrefix(
|
||||
ctx, operand->mem.segment, ZYDIS_REGISTER_NONE
|
||||
));
|
||||
ctx->imms[0] = operand->mem.disp.value.sqword;
|
||||
ctx->immBitSizes[0] = operand->mem.disp.dataSize;
|
||||
break;
|
||||
default:
|
||||
// Hidden operand, nothing to encode.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_OPERAND_ENCODING_REG:
|
||||
{
|
||||
ZYDIS_ASSERT(!ctx->info->details.modrm.reg);
|
||||
ZYDIS_CHECK(ZydisPrepareRegOperand(ctx, operand->reg, 'R'));
|
||||
} break;
|
||||
case ZYDIS_OPERAND_ENCODING_RM:
|
||||
|
@ -743,6 +829,12 @@ static ZydisStatus ZydisPrepareOperand(ZydisEncoderContext* ctx,
|
|||
case ZYDIS_OPERAND_ENCODING_RM_CD32:
|
||||
case ZYDIS_OPERAND_ENCODING_RM_CD64:
|
||||
{
|
||||
ZYDIS_ASSERT(!ctx->info->details.modrm.mod);
|
||||
ZYDIS_ASSERT(!ctx->info->details.modrm.rm);
|
||||
ZYDIS_ASSERT(!ctx->info->details.sib.base);
|
||||
ZYDIS_ASSERT(!ctx->info->details.sib.index);
|
||||
ZYDIS_ASSERT(!ctx->info->details.sib.scale);
|
||||
|
||||
// Memory operand?
|
||||
if (operand->type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
|
@ -762,8 +854,8 @@ static ZydisStatus ZydisPrepareOperand(ZydisEncoderContext* ctx,
|
|||
{
|
||||
int16_t reg = ZydisRegisterGetId(operand->reg);
|
||||
if (reg == -1) return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
ctx->info->opcode += reg & 0x0F;
|
||||
ctx->info->details.rex.R = (reg & 0x08) >> 3;
|
||||
ctx->info->opcode += reg & 0x07;
|
||||
ctx->info->details.rex.B = (reg & 0x08) >> 3;
|
||||
if (ctx->info->details.rex.B) ctx->info->attributes |= ZYDIS_ATTRIB_HAS_REX;
|
||||
break;
|
||||
}
|
||||
|
@ -811,6 +903,8 @@ static ZydisStatus ZydisPrepareOperand(ZydisEncoderContext* ctx,
|
|||
|
||||
static ZydisStatus ZydisPrepareMandatoryPrefixes(ZydisEncoderContext* ctx)
|
||||
{
|
||||
ZYDIS_ASSERT(ctx);
|
||||
|
||||
// Is a prefix mandatory? 0x00 is a sentinel value for `None` in the table.
|
||||
if (ctx->matchingEntry->mandatoryPrefix != 0x00)
|
||||
{
|
||||
|
@ -847,6 +941,8 @@ static ZydisStatus ZydisPrepareMandatoryPrefixes(ZydisEncoderContext* ctx)
|
|||
|
||||
static ZydisStatus ZydisDeriveEncodingForOp(ZydisOperandDefinition* operand)
|
||||
{
|
||||
ZYDIS_ASSERT(operand);
|
||||
|
||||
switch (operand->type)
|
||||
{
|
||||
default:
|
||||
|
@ -885,9 +981,10 @@ static ZydisStatus ZydisFindMatchingDef(const ZydisInstructionInfo* info,
|
|||
const ZydisEncoderTableOperand* curEncoderOp = &curEntry->operands[k];
|
||||
const ZydisOperandInfo* curReqOp = &info->operands[k];
|
||||
if (curReqOp->encoding != curEncoderOp->encoding) goto continueTopLevel;
|
||||
ZydisOperandType simpleType;
|
||||
ZYDIS_CHECK(ZydisSimplifyOperandType(curEncoderOp->type, &simpleType));
|
||||
if (curReqOp->type != simpleType) goto continueTopLevel;
|
||||
//ZydisOperandType simpleType;
|
||||
//ZYDIS_CHECK(ZydisSimplifyOperandType(curEncoderOp->type, &simpleType));
|
||||
//if (curReqOp->type != simpleType) goto continueTopLevel;
|
||||
if (curReqOp->temp != curEncoderOp->type) goto continueTopLevel;
|
||||
}
|
||||
|
||||
// Still here? We found our entry!
|
||||
|
@ -963,12 +1060,22 @@ ZydisStatus ZydisEncoderEncodeInstruction(void* buffer, size_t* bufferLen,
|
|||
info->details.evex.B = (pb & ZYDIS_PREFBIT_EVEX_B ) ? 1 : 0;
|
||||
info->details.evex.L2 = (pb & ZYDIS_PREFBIT_EVEX_L2) ? 1 : 0;
|
||||
info->details.vex.L = (pb & ZYDIS_PREFBIT_VEX_L ) ? 1 : 0;
|
||||
info->details.rex.W = (pb & ZYDIS_PREFBIT_REX_W ) ? 1 : 0;
|
||||
if (pb & ZYDIS_PREFBIT_REX_W)
|
||||
{
|
||||
info->details.rex.W = 1;
|
||||
info->attributes |= ZYDIS_ATTRIB_HAS_REX;
|
||||
}
|
||||
ZYDIS_CHECK(ZydisPrepareMandatoryPrefixes(&ctx));
|
||||
|
||||
// Prepare opcode.
|
||||
ZYDIS_CHECK(ZydisPrepareOpcode(&ctx));
|
||||
|
||||
// Some instructions have additional opcode bits encoded in ModRM.reg.
|
||||
if (ctx.matchingEntry->modrmReg != 0xFF)
|
||||
{
|
||||
ctx.info->details.modrm.reg = ctx.matchingEntry->modrmReg;
|
||||
}
|
||||
|
||||
// Analyze and prepare operands.
|
||||
if (info->operandCount > ZYDIS_ARRAY_SIZE(info->operands))
|
||||
{
|
||||
|
|
|
@ -95,6 +95,7 @@ int main(int argc, char** argv)
|
|||
|
||||
// TODO: Remove
|
||||
// DEBUG CODE START
|
||||
#if 0
|
||||
for (size_t i = 0; i < info.length; ++i)
|
||||
{
|
||||
printf("%02X ", *(readBuf + readOffs + i));
|
||||
|
@ -115,6 +116,7 @@ int main(int argc, char** argv)
|
|||
putchar('\n');
|
||||
ZYDIS_ASSERT(encBufferSize == info.length);
|
||||
ZYDIS_ASSERT(!memcmp(encBuffer, readBuf + readOffs, encBufferSize));
|
||||
#endif
|
||||
// DEBUG CODE END
|
||||
|
||||
readOffs += info.length;
|
||||
|
|
Loading…
Reference in New Issue