Added more formatter-hooks

- ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT
- ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE
This commit is contained in:
flobernd 2016-11-28 11:14:47 +01:00
parent 805a407395
commit 477a908bb0
3 changed files with 122 additions and 74 deletions

View File

@ -1712,25 +1712,15 @@ end;
procedure TX86Flags.AssignTo(Dest: TPersistent);
var
D: TX86Flags;
I: Integer;
begin
if (Dest is TX86Flags) then
begin
D := Dest as TX86Flags;
D.FCF := FCF;
D.FPF := FPF;
D.FAF := FAF;
D.FZF := FZF;
D.FSF := FSF;
D.FTF := FTF;
D.FIF := FIF;
D.FDF := FDF;
D.FOF := FOF;
D.FRF := FRF;
D.FVM := FVM;
D.FAC := FAC;
D.FVIF := FVIF;
D.FVIP := FVIP;
D.FID := FID;
for I := 0 to GetFlagCount - 1 do
begin
D.SetFlagValue(I, GetFlagValue(I));
end;
D.Changed;
end else inherited;
end;
@ -1750,11 +1740,18 @@ begin
end;
function TX86Flags.Equals(const Value: TX86Flags): Boolean;
var
I: Integer;
begin
Result := (Value.FCF = FCF) and (Value.FPF = FPF) and (Value.FAF = FAF) and
(Value.FZF = FZF) and (Value.FSF = FSF) and (Value.FTF = FTF) and (Value.FIF = FIF) and
(Value.FDF = FDF) and (Value.FOF = FOF) and (Value.FRF = FRF) and (Value.FVM = FVM) and
(Value.FAC = FAC) and (Value.FVIF = FVIF) and (Value.FVIP = FVIP) and (Value.FID = FID);
Result := true;
for I := 0 to GetFlagCount - 1 do
begin
if (GetFlagValue(I) <> Value.GetFlagValue(I)) then
begin
Result := false;
Break;
end;
end;
end;
function TX86Flags.GetConflictState: Boolean;
@ -1765,6 +1762,8 @@ var
RegsWrite: TX86RegisterSet;
R: TX86Register;
begin
Exit(false);
Result := false;
RegsRead := [];
RegsWrite := [];
@ -2472,7 +2471,11 @@ begin
Result := true;
for I := Low(FOperands) to High(FOperands) do
begin
Result := Result and Value.FOperands[I].Equals(FOperands[I]);
if (not Value.FOperands[I].Equals(FOperands[I])) then
begin
Result := false;
Break;
end;
end;
end;

View File

@ -233,7 +233,7 @@ enum ZydisFormatterHookTypes
* @brief This function is called to format an memory operand.
*
* Replacing this function might indirectly disable some specific calls to the
* @c ZYDIS_FORMATTER_PRINT_ADDRESS function.
* @c ZYDIS_FORMATTER_PRINT_ADDRESS and @c ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT functions.
*/
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM,
/**
@ -244,7 +244,7 @@ enum ZydisFormatterHookTypes
* @brief This function is called to format an immediate operand.
*
* Replacing this function might indirectly disable some specific calls to the
* @c ZYDIS_FORMATTER_PRINT_ADDRESS function.
* @c ZYDIS_FORMATTER_PRINT_ADDRESS and @c ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE functions.
*/
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM,
/**
@ -265,7 +265,15 @@ enum ZydisFormatterHookTypes
/**
* @brief This function is called to print an absolute address.
*/
ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS
ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS,
/**
* @brief This function is called to print a memory displacement value.
*/
ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT,
/**
* @brief This function is called to print an immediate value.
*/
ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE
};
/* ---------------------------------------------------------------------------------------------- */
@ -336,7 +344,9 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(ZydisInstructionFormatter* forma
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG,
* @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM, @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR,
* @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE,
* @c ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT and @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-types.
* @c ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT, @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR,
* @c ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT and @c ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE
* hook-types.
*/
typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(ZydisInstructionFormatter* formatter,
char** buffer, size_t bufferLen, ZydisInstructionInfo* info, ZydisOperandInfo* operand);
@ -385,6 +395,8 @@ typedef struct ZydisInstructionFormatter_
ZydisFormatterFormatOperandFunc funcPrintSegment;
ZydisFormatterFormatOperandFunc funcPrintDecorator;
ZydisFormatterFormatAddressFunc funcPrintAddress;
ZydisFormatterFormatOperandFunc funcPrintDisplacement;
ZydisFormatterFormatOperandFunc funcPrintImmediate;
const char* prefixHEX;
const char* prefixOCT;
const char* delimMnemonic;

View File

@ -332,29 +332,8 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(ZydisInstructionFormatter
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "*%d", operand->mem.scale));
}
}
if ((operand->mem.disp.dataSize) && ((operand->mem.disp.value.sqword) ||
((operand->mem.base == ZYDIS_REGISTER_NONE) &&
(operand->mem.index == ZYDIS_REGISTER_NONE))))
{
bool printSignedHEX =
(formatter->displacementFormat != ZYDIS_FORMATTER_DISP_HEX_UNSIGNED);
if (printSignedHEX && (operand->mem.disp.value.sqword < 0) && (
(operand->mem.base != ZYDIS_REGISTER_NONE) ||
(operand->mem.index != ZYDIS_REGISTER_NONE)))
{
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"-0x%02"PRIX32, -operand->mem.disp.value.sdword));
} else
{
const char* sign =
((operand->mem.base == ZYDIS_REGISTER_NONE) &&
(operand->mem.index == ZYDIS_REGISTER_NONE)) ? "" : "+";
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"%s0x%02"PRIX32, sign, operand->mem.disp.value.sdword));
}
}
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer,
info, operand));
}
return ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "]");
@ -380,10 +359,10 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(ZydisInstructionFormatter
return ZYDIS_STATUS_INVALID_PARAMETER;
}
bool printSignedHEX = false;
// The immediate operand contains an address
if (operand->imm.isRelative)
{
bool printSignedHEX = false;
switch (formatter->addressFormat)
{
case ZYDIS_FORMATTER_ADDR_DEFAULT:
@ -412,7 +391,70 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(ZydisInstructionFormatter
}
// The immediate operand contains an actual ordinal value
printSignedHEX = (formatter->immediateFormat == ZYDIS_FORMATTER_IMM_HEX_SIGNED);
return formatter->funcPrintImmediate(formatter, buffer, bufferLen, info, operand);
}
/* ---------------------------------------------------------------------------------------------- */
static ZydisStatus ZydisFormatterPrintAddressIntel(ZydisInstructionFormatter* formatter,
char** buffer, size_t bufferLen, ZydisInstructionInfo* info, ZydisOperandInfo* operand,
uint64_t address)
{
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !info || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
switch (info->mode)
{
case ZYDIS_DISASSEMBLER_MODE_16BIT:
case ZYDIS_DISASSEMBLER_MODE_32BIT:
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"0x%08"PRIX64, address);
case ZYDIS_DISASSEMBLER_MODE_64BIT:
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"0x%016"PRIX64, address);
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
}
static ZydisStatus ZydisFormatterPrintDisplacementIntel(ZydisInstructionFormatter* formatter,
char** buffer, size_t bufferLen, ZydisInstructionInfo* info, ZydisOperandInfo* operand)
{
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !info || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
if ((operand->mem.disp.dataSize) && ((operand->mem.disp.value.sqword) ||
((operand->mem.base == ZYDIS_REGISTER_NONE) &&
(operand->mem.index == ZYDIS_REGISTER_NONE))))
{
bool printSignedHEX = (formatter->displacementFormat != ZYDIS_FORMATTER_DISP_HEX_UNSIGNED);
if (printSignedHEX && (operand->mem.disp.value.sqword < 0) && (
(operand->mem.base != ZYDIS_REGISTER_NONE) ||
(operand->mem.index != ZYDIS_REGISTER_NONE)))
{
return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "-0x%02"PRIX32, -operand->mem.disp.value.sdword);
}
}
const char* sign =
((operand->mem.base == ZYDIS_REGISTER_NONE) &&
(operand->mem.index == ZYDIS_REGISTER_NONE)) ? "" : "+";
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"%s0x%02"PRIX32, sign, operand->mem.disp.value.sdword);
}
static ZydisStatus ZydisFormatterPrintImmediateIntel(ZydisInstructionFormatter* formatter,
char** buffer, size_t bufferLen, ZydisInstructionInfo* info, ZydisOperandInfo* operand)
{
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !info || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
bool printSignedHEX = (formatter->immediateFormat == ZYDIS_FORMATTER_IMM_HEX_SIGNED);
if (formatter->immediateFormat == ZYDIS_FORMATTER_IMM_HEX_AUTO)
{
printSignedHEX = operand->imm.isSigned;
@ -458,29 +500,6 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(ZydisInstructionFormatter
/* ---------------------------------------------------------------------------------------------- */
static ZydisStatus ZydisFormatterPrintAddressIntel(ZydisInstructionFormatter* formatter,
char** buffer, size_t bufferLen, ZydisInstructionInfo* info, ZydisOperandInfo* operand,
uint64_t address)
{
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !info || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
switch (info->mode)
{
case ZYDIS_DISASSEMBLER_MODE_16BIT:
case ZYDIS_DISASSEMBLER_MODE_32BIT:
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"0x%08"PRIX64, address);
case ZYDIS_DISASSEMBLER_MODE_64BIT:
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"0x%016"PRIX64, address);
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
}
static ZydisStatus ZydisFormatterPrintOperandSizeIntel(ZydisInstructionFormatter* formatter,
char** buffer, size_t bufferLen, ZydisInstructionInfo* info, ZydisOperandInfo* operand)
{
@ -836,6 +855,8 @@ ZydisStatus ZydisFormatterInitInstructionFormatterEx(
formatter->funcPrintSegment = &ZydisFormatterPrintSegmentIntel;
formatter->funcPrintDecorator = &ZydisFormatterPrintDecoratorIntel;
formatter->funcPrintAddress = &ZydisFormatterPrintAddressIntel;
formatter->funcPrintDisplacement = &ZydisFormatterPrintDisplacementIntel;
formatter->funcPrintImmediate = &ZydisFormatterPrintImmediateIntel;
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
@ -896,6 +917,12 @@ ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* formatter,
case ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS:
*callback = *(const void**)&formatter->funcPrintAddress;
break;
case ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT:
*callback = *(const void**)&formatter->funcPrintDisplacement;
break;
case ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE:
*callback = *(const void**)&formatter->funcPrintImmediate;
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
@ -948,6 +975,12 @@ ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* formatter,
case ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS:
formatter->funcPrintAddress = *(ZydisFormatterFormatAddressFunc*)&temp;
break;
case ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT:
formatter->funcPrintDisplacement = *(ZydisFormatterFormatOperandFunc*)&temp;
break;
case ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE:
formatter->funcPrintImmediate = *(ZydisFormatterFormatOperandFunc*)&temp;
break;
default:
break;
}