Fixed encoder IMM size derivation

This commit is contained in:
Joel Höner 2017-07-28 02:26:52 +02:00
parent 4140db6c1f
commit 9152714865
1 changed files with 51 additions and 49 deletions

View File

@ -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;