mirror of https://github.com/x64dbg/zydis
Fixed encoder IMM size derivation
This commit is contained in:
parent
4140db6c1f
commit
9152714865
100
src/Encoder.c
100
src/Encoder.c
|
@ -467,6 +467,7 @@ static ZydisStatus ZydisSemanticOperandTypeDeriveMask(
|
||||||
1 << ZYDIS_SEMANTIC_OPTYPE_MEM_VSIBX |
|
1 << ZYDIS_SEMANTIC_OPTYPE_MEM_VSIBX |
|
||||||
1 << ZYDIS_SEMANTIC_OPTYPE_MEM_VSIBY |
|
1 << ZYDIS_SEMANTIC_OPTYPE_MEM_VSIBY |
|
||||||
1 << ZYDIS_SEMANTIC_OPTYPE_MEM_VSIBZ |
|
1 << ZYDIS_SEMANTIC_OPTYPE_MEM_VSIBZ |
|
||||||
|
1 << ZYDIS_SEMANTIC_OPTYPE_AGEN |
|
||||||
1 << ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_MEM;
|
1 << ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_MEM;
|
||||||
break;
|
break;
|
||||||
case ZYDIS_OPERAND_TYPE_POINTER:
|
case ZYDIS_OPERAND_TYPE_POINTER:
|
||||||
|
@ -500,9 +501,9 @@ static uint8_t ZydisSImmGetMinSize(int64_t imm)
|
||||||
return 64;
|
return 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisBool ZydisSemanticOperandTypeImmIsSigned(ZydisSemanticOperandType type)
|
static ZydisBool ZydisOperandEncodingImmIsSigned(ZydisOperandEncoding enc)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (enc)
|
||||||
{
|
{
|
||||||
case ZYDIS_OPERAND_ENCODING_DISP8:
|
case ZYDIS_OPERAND_ENCODING_DISP8:
|
||||||
case ZYDIS_OPERAND_ENCODING_DISP16:
|
case ZYDIS_OPERAND_ENCODING_DISP16:
|
||||||
|
@ -539,10 +540,10 @@ static ZydisBool ZydisSemanticOperandTypeImmIsSigned(ZydisSemanticOperandType ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisStatus ZydisSemanticOperandTypeImmGetEffectiveSize(
|
static ZydisStatus ZydisOperandEncodingGetEffectiveImmSize(
|
||||||
ZydisSemanticOperandType type, ZydisMachineMode machineMode, uint8_t* esz)
|
ZydisOperandEncoding enc, ZydisMachineMode machineMode, uint8_t* esz)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (enc)
|
||||||
{
|
{
|
||||||
case ZYDIS_OPERAND_ENCODING_DISP8:
|
case ZYDIS_OPERAND_ENCODING_DISP8:
|
||||||
case ZYDIS_OPERAND_ENCODING_SIMM8:
|
case ZYDIS_OPERAND_ENCODING_SIMM8:
|
||||||
|
@ -606,6 +607,41 @@ static ZydisStatus ZydisSemanticOperandTypeImmGetEffectiveSize(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ZydisBool ZydisRegIsBP(ZydisRegister reg)
|
||||||
|
{
|
||||||
|
return reg == ZYDIS_REGISTER_BPL ||
|
||||||
|
reg == ZYDIS_REGISTER_BP ||
|
||||||
|
reg == ZYDIS_REGISTER_EBP ||
|
||||||
|
reg == ZYDIS_REGISTER_RBP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ZydisBool ZydisRegIsSP(ZydisRegister reg)
|
||||||
|
{
|
||||||
|
return reg == ZYDIS_REGISTER_SPL ||
|
||||||
|
reg == ZYDIS_REGISTER_SP ||
|
||||||
|
reg == ZYDIS_REGISTER_ESP ||
|
||||||
|
reg == ZYDIS_REGISTER_RSP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ZydisBool ZydisRegIsIP(ZydisRegister reg)
|
||||||
|
{
|
||||||
|
return reg == ZYDIS_REGISTER_IP ||
|
||||||
|
reg == ZYDIS_REGISTER_EIP ||
|
||||||
|
reg == ZYDIS_REGISTER_RIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ZydisBool ZydisRegIsStack(ZydisRegister reg)
|
||||||
|
{
|
||||||
|
return ZydisRegIsSP(reg) || ZydisRegIsBP(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ZydisBool ZydisSemanticTypeIsImplicit(ZydisSemanticOperandType type)
|
||||||
|
{
|
||||||
|
return type == ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_REG ||
|
||||||
|
type == ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_MEM ||
|
||||||
|
type == ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_IMM1;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
/* Preparation functions. Parse encoder request, determine required bytes and prefixes. */
|
/* Preparation functions. Parse encoder request, determine required bytes and prefixes. */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
@ -730,41 +766,6 @@ static ZydisStatus ZydisPrepareRegOperand(ZydisEncoderContext* ctx,
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisBool ZydisRegIsBP(ZydisRegister reg)
|
|
||||||
{
|
|
||||||
return reg == ZYDIS_REGISTER_BPL ||
|
|
||||||
reg == ZYDIS_REGISTER_BP ||
|
|
||||||
reg == ZYDIS_REGISTER_EBP ||
|
|
||||||
reg == ZYDIS_REGISTER_RBP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ZydisBool ZydisRegIsSP(ZydisRegister reg)
|
|
||||||
{
|
|
||||||
return reg == ZYDIS_REGISTER_SPL ||
|
|
||||||
reg == ZYDIS_REGISTER_SP ||
|
|
||||||
reg == ZYDIS_REGISTER_ESP ||
|
|
||||||
reg == ZYDIS_REGISTER_RSP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ZydisBool ZydisRegIsIP(ZydisRegister reg)
|
|
||||||
{
|
|
||||||
return reg == ZYDIS_REGISTER_IP ||
|
|
||||||
reg == ZYDIS_REGISTER_EIP ||
|
|
||||||
reg == ZYDIS_REGISTER_RIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ZydisBool ZydisRegIsStack(ZydisRegister reg)
|
|
||||||
{
|
|
||||||
return ZydisRegIsSP(reg) || ZydisRegIsBP(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ZydisBool ZydisSemanticTypeIsImplicit(ZydisSemanticOperandType type)
|
|
||||||
{
|
|
||||||
return type == ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_REG ||
|
|
||||||
type == ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_MEM ||
|
|
||||||
type == ZYDIS_SEMANTIC_OPTYPE_IMPLICIT_IMM1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ZydisStatus ZydisPrepareSegmentPrefix(ZydisEncoderContext* ctx,
|
static ZydisStatus ZydisPrepareSegmentPrefix(ZydisEncoderContext* ctx,
|
||||||
ZydisRegister segment, ZydisRegister base)
|
ZydisRegister segment, ZydisRegister base)
|
||||||
{
|
{
|
||||||
|
@ -1262,7 +1263,7 @@ static ZydisStatus ZydisFindMatchingDef(
|
||||||
const ZydisInstructionDefinition* candidateDef = NULL;
|
const ZydisInstructionDefinition* candidateDef = NULL;
|
||||||
ZydisGetInstructionDefinition(
|
ZydisGetInstructionDefinition(
|
||||||
candidateInsn->encoding, candidateInsn->definitionReference, &candidateDef);
|
candidateInsn->encoding, candidateInsn->definitionReference, &candidateDef);
|
||||||
ZydisOperandDefinition* candidateOperands = NULL;
|
const ZydisOperandDefinition* candidateOperands = NULL;
|
||||||
uint8_t defOperandCount = ZydisGetOperandDefinitions(candidateDef, &candidateOperands);
|
uint8_t defOperandCount = ZydisGetOperandDefinitions(candidateDef, &candidateOperands);
|
||||||
|
|
||||||
if (req->operandCount > defOperandCount) goto _nextInsn;
|
if (req->operandCount > defOperandCount) goto _nextInsn;
|
||||||
|
@ -1334,6 +1335,7 @@ static ZydisStatus ZydisFindMatchingDef(
|
||||||
if (curReqOperand->imm.u != 1) goto _nextInsn;
|
if (curReqOperand->imm.u != 1) goto _nextInsn;
|
||||||
} break;
|
} break;
|
||||||
case ZYDIS_SEMANTIC_OPTYPE_IMM:
|
case ZYDIS_SEMANTIC_OPTYPE_IMM:
|
||||||
|
case ZYDIS_SEMANTIC_OPTYPE_REL:
|
||||||
{
|
{
|
||||||
// Even though the user probably had an idea if their immediate was signed
|
// Even though the user probably had an idea if their immediate was signed
|
||||||
// or unsigned, we try to encode it with whatever the signedness of the
|
// or unsigned, we try to encode it with whatever the signedness of the
|
||||||
|
@ -1342,15 +1344,15 @@ static ZydisStatus ZydisFindMatchingDef(
|
||||||
// also encode it as an 8-bit signed -1 that is then expanded back to 0xFFFFFFFF
|
// also encode it as an 8-bit signed -1 that is then expanded back to 0xFFFFFFFF
|
||||||
// at runtime (assuming machineMode == 32), resulting in more compact and
|
// at runtime (assuming machineMode == 32), resulting in more compact and
|
||||||
// efficient encoding.
|
// efficient encoding.
|
||||||
uint8_t minSize = ZydisSemanticOperandTypeImmIsSigned(curDefOperand->type)
|
uint8_t minSize = ZydisOperandEncodingImmIsSigned(curDefOperand->op.encoding)
|
||||||
? ZydisSImmGetMinSize(curReqOperand->imm.s)
|
? ZydisSImmGetMinSize(curReqOperand->imm.s)
|
||||||
: ZydisUImmGetMinSize(curReqOperand->imm.u);
|
: ZydisUImmGetMinSize(curReqOperand->imm.u);
|
||||||
uint8_t eisz;
|
uint8_t eisz;
|
||||||
ZYDIS_CHECK(ZydisSemanticOperandTypeImmGetEffectiveSize(
|
ZYDIS_CHECK(ZydisOperandEncodingGetEffectiveImmSize(
|
||||||
curDefOperand->type, req->machineMode, &eisz
|
curDefOperand->op.encoding, req->machineMode, &eisz
|
||||||
));
|
));
|
||||||
if (eisz < minSize) goto _nextInsn;
|
if (eisz < minSize) goto _nextInsn;
|
||||||
ctx->derivedImmSize[k] = minSize;
|
ctx->derivedImmSize[k] = eisz;
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
; // No further checks required.
|
; // No further checks required.
|
||||||
|
@ -1400,11 +1402,11 @@ ZydisStatus ZydisEncoderDecodedInstructionToRequest(
|
||||||
out->encoding = in->encoding;
|
out->encoding = in->encoding;
|
||||||
out->operandCount = 0;
|
out->operandCount = 0;
|
||||||
|
|
||||||
for (uint8_t iIn = 0
|
for (uint8_t i = 0
|
||||||
; iIn < in->operandCount && out->operandCount < ZYDIS_ARRAY_SIZE(out->operands)
|
; i < in->operandCount && out->operandCount < ZYDIS_ARRAY_SIZE(out->operands)
|
||||||
; ++iIn)
|
; ++i)
|
||||||
{
|
{
|
||||||
const ZydisDecodedOperand* inOp = in->operands + iIn;
|
const ZydisDecodedOperand* inOp = in->operands + i;
|
||||||
ZydisEncoderOperand* outOp = out->operands + out->operandCount;
|
ZydisEncoderOperand* outOp = out->operands + out->operandCount;
|
||||||
if (inOp->visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN) continue;
|
if (inOp->visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN) continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue