Refactorings and bugfixes

- Added support for the BOUND prefix
- Added support for more detailed operand-actions (read, write, readwrite, cond. read, cond. write, read + cond. write, write + cond. read)
- Added operand-visibility info (explicit, implicit, hidden)
- Fixed some bugs in the prefix-decoding routines
- Removed stdbool.h dependency and introduced custom boolean-type for better portability
This commit is contained in:
flobernd 2016-12-05 02:24:01 +01:00
parent bb913f1272
commit d4dd176438
31 changed files with 17015 additions and 17079 deletions

View File

@ -51,11 +51,11 @@ set(headers
"include/Zydis/Defines.h" "include/Zydis/Defines.h"
"include/Zydis/Formatter.h" "include/Zydis/Formatter.h"
"include/Zydis/Input.h" "include/Zydis/Input.h"
"include/Zydis/InstructionDetails.h"
"include/Zydis/InstructionInfo.h" "include/Zydis/InstructionInfo.h"
"include/Zydis/Mnemonic.h" "include/Zydis/Mnemonic.h"
"include/Zydis/Register.h" "include/Zydis/Register.h"
"include/Zydis/Status.h" "include/Zydis/Status.h"
"include/Zydis/Types.h"
"include/Zydis/Utils.h" "include/Zydis/Utils.h"
"include/Zydis/Zydis.h" "include/Zydis/Zydis.h"
"include/Zydis/Internal/InstructionTable.h") "include/Zydis/Internal/InstructionTable.h")
@ -63,7 +63,6 @@ set(sources
"src/Decoder.c" "src/Decoder.c"
"src/Formatter.c" "src/Formatter.c"
"src/Input.c" "src/Input.c"
"src/InstructionDetails.c"
"src/InstructionTable.c" "src/InstructionTable.c"
"src/Mnemonic.c" "src/Mnemonic.c"
"src/Register.c" "src/Register.c"

View File

@ -699,9 +699,9 @@ begin
end; end;
end; end;
S := 'ZYDIS_EVEXB_FUNCTIONALITY_NONE'; T := 'false'; U := 'false'; S := 'ZYDIS_EVEXB_FUNCTIONALITY_NONE'; T := 'ZYDIS_FALSE'; U := 'ZYDIS_FALSE';
if (ifAcceptsEvexAAA in Definition.Flags) then S := 'true'; if (ifAcceptsEvexAAA in Definition.Flags) then S := 'ZYDIS_TRUE';
if (ifAcceptsEvexZ in Definition.Flags) then T := 'true'; if (ifAcceptsEvexZ in Definition.Flags) then T := 'ZYDIS_TRUE';
if (ifHasEvexBC in Definition.Flags) then U := 'ZYDIS_EVEXB_FUNCTIONALITY_BC' if (ifHasEvexBC in Definition.Flags) then U := 'ZYDIS_EVEXB_FUNCTIONALITY_BC'
else else
if (ifHasEvexRC in Definition.Flags) then U := 'ZYDIS_EVEXB_FUNCTIONALITY_RC' if (ifHasEvexRC in Definition.Flags) then U := 'ZYDIS_EVEXB_FUNCTIONALITY_RC'
@ -709,11 +709,12 @@ begin
if (ifHasEvexSAE in Definition.Flags) then U := 'ZYDIS_EVEXB_FUNCTIONALITY_SAE'; if (ifHasEvexSAE in Definition.Flags) then U := 'ZYDIS_EVEXB_FUNCTIONALITY_SAE';
Buffer.Append(Format(' /*%.4x*/ ', [Index])); Buffer.Append(Format(' /*%.4x*/ ', [Index]));
Buffer.Append(Format('{ ZYDIS_MNEMONIC_%s, 0x%.4x, %s, %s, %s, %d, %d, %d, %d, %d, %d, %d }', [ Buffer.Append(Format('{ ZYDIS_MNEMONIC_%s, 0x%.4x, %s, %s, %s, %d, %d, %d, %d, %d, %d, %d, %d }',
AnsiUpperCase(Definition.Mnemonic), O, U, S, T, [AnsiUpperCase(Definition.Mnemonic), O, U, S, T,
Byte(pfAcceptsLock in Definition.PrefixFlags), Byte(pfAcceptsLock in Definition.PrefixFlags),
Byte(pfAcceptsREP in Definition.PrefixFlags), Byte(pfAcceptsREP in Definition.PrefixFlags),
Byte(pfAcceptsREPEREPNE in Definition.PrefixFlags), Byte(pfAcceptsREPEREPNE in Definition.PrefixFlags),
Byte(pfAcceptsBOUND in Definition.PrefixFlags),
Byte(pfAcceptsXACQUIRE in Definition.PrefixFlags), Byte(pfAcceptsXACQUIRE in Definition.PrefixFlags),
Byte(pfAcceptsXRELEASE in Definition.PrefixFlags), Byte(pfAcceptsXRELEASE in Definition.PrefixFlags),
Byte(pfAcceptsHLEWithoutLock in Definition.PrefixFlags), Byte(pfAcceptsHLEWithoutLock in Definition.PrefixFlags),
@ -994,7 +995,7 @@ procedure AppendOperand(Buffer: TStringBuffer; Operand: TInstructionOperand);
var var
OperandType, OperandType,
OperandEncoding, OperandEncoding,
OperandAccessMode: String; OperandAction: String;
begin begin
OperandType := 'UNUSED'; OperandType := 'UNUSED';
case Operand.OperandType of case Operand.OperandType of
@ -1088,9 +1089,9 @@ begin
opeModrmRmCD2 : OperandEncoding := 'RM_CD2'; opeModrmRmCD2 : OperandEncoding := 'RM_CD2';
opeModrmRmCD4 : OperandEncoding := 'RM_CD4'; opeModrmRmCD4 : OperandEncoding := 'RM_CD4';
opeModrmRmCD8 : OperandEncoding := 'RM_CD8'; opeModrmRmCD8 : OperandEncoding := 'RM_CD8';
opeModrmRmCD16: OperandEncoding := 'RM_CD16'; opeModrmRmCD16 : OperandEncoding := 'RM_CD16';
opeModrmRmCD32: OperandEncoding := 'RM_CD32'; opeModrmRmCD32 : OperandEncoding := 'RM_CD32';
opeModrmRmCD64: OperandEncoding := 'RM_CD64'; opeModrmRmCD64 : OperandEncoding := 'RM_CD64';
opeOpcodeBits : OperandEncoding := 'OPCODE'; opeOpcodeBits : OperandEncoding := 'OPCODE';
opeVexVVVV : OperandEncoding := 'VVVV'; opeVexVVVV : OperandEncoding := 'VVVV';
opeEvexAAA : OperandEncoding := 'AAA'; opeEvexAAA : OperandEncoding := 'AAA';
@ -1101,14 +1102,18 @@ begin
opeImm32 : OperandEncoding := 'IMM32'; opeImm32 : OperandEncoding := 'IMM32';
opeImm64 : OperandEncoding := 'IMM64'; opeImm64 : OperandEncoding := 'IMM64';
end; end;
OperandAccessMode := 'READ'; OperandAction := 'READ';
case Operand.AccessMode of case Operand.Action of
opaWrite : OperandAccessMode := 'WRITE'; opaWrite : OperandAction := 'WRITE';
opaReadWrite : OperandAccessMode := 'READWRITE'; opaReadWrite : OperandAction := 'READWRITE';
opaCondRead : OperandAction := 'COND_READ';
opaCondWrite : OperandAction := 'COND_WRITE';
opaReadCondWrite: OperandAction := 'READ_COND_WRITE';
opaWriteCondRead: OperandAction := 'WRITE_COND_READ';
end; end;
Buffer.Append(Format('ZYDIS_OPERAND_DEFINITION(ZYDIS_SEM_OPERAND_TYPE_%s, ' + Buffer.Append(Format('ZYDIS_OPERAND_DEFINITION(ZYDIS_SEM_OPERAND_TYPE_%s, ' +
'ZYDIS_OPERAND_ENCODING_%s, ZYDIS_OPERAND_ACCESS_%s)', [ 'ZYDIS_OPERAND_ENCODING_%s, ZYDIS_OPERAND_ACTION_%s)', [
OperandType, OperandEncoding, OperandAccessMode])); OperandType, OperandEncoding, OperandAction]));
end; end;
var var

View File

@ -342,6 +342,29 @@ type
property FlagID : TX86FlagBehaviorSet index 16 read GetValue write SetValue default []; property FlagID : TX86FlagBehaviorSet index 16 read GetValue write SetValue default [];
end; end;
TEVEXEncodingContext = (
// EVEX.B = 1 is forbidden for this instruction and will cause UD
ecUD,
// EVEX.B = 1 broadcast
ecBC,
// EVEX.B = 1 rounding-control
ecRC,
// EVEX.B = 1 suppress all exceptions
ecSAE
);
TEVEXMaskPolicy = (
// The instruction can not encode a mask register
mpMaskInvalid,
// The instruction accepts mask registers other than the default-mask (K0), but does not
// require them
mpMaskAccepted,
// The instruction requires a mask register other than the default-mask (K0)
mpMaskRequired,
// The instruction does not allow mask registers other than the default-mask (K0)
mpMaskForbidden
);
{TEVEXEncodingContext = ( {TEVEXEncodingContext = (
ecNone, ecNone,
ecBroadcast, ecBroadcast,
@ -483,10 +506,14 @@ type
opeImm64 opeImm64
); );
TOperandAccessMode = ( TOperandAction = (
opaRead, opaRead,
opaWrite, opaWrite,
opaReadWrite opaReadWrite,
opaCondRead,
opaCondWrite,
opaReadCondWrite,
opaWriteCondRead
); );
TInstructionOperand = class(TPersistent) TInstructionOperand = class(TPersistent)
@ -494,12 +521,12 @@ type
FOperands: TInstructionOperands; FOperands: TInstructionOperands;
FType: TOperandType; FType: TOperandType;
FEncoding: TOperandEncoding; FEncoding: TOperandEncoding;
FAccessMode: TOperandAccessMode; FAction: TOperandAction;
strict private strict private
function GetConflictState: Boolean; function GetConflictState: Boolean;
procedure SetType(const Value: TOperandType); inline; procedure SetType(const Value: TOperandType); inline;
procedure SetEncoding(const Value: TOperandEncoding); inline; procedure SetEncoding(const Value: TOperandEncoding); inline;
procedure SetAccessMode(const Value: TOperandAccessMode); inline; procedure SetAction(const Value: TOperandAction); inline;
strict private strict private
procedure Changed; inline; procedure Changed; inline;
private private
@ -518,7 +545,7 @@ type
published published
property OperandType: TOperandType read FType write SetType default optUnused; property OperandType: TOperandType read FType write SetType default optUnused;
property Encoding: TOperandEncoding read FEncoding write SetEncoding default opeNone; property Encoding: TOperandEncoding read FEncoding write SetEncoding default opeNone;
property AccessMode: TOperandAccessMode read FAccessMode write SetAccessMode default opaRead; property Action: TOperandAction read FAction write SetAction default opaRead;
end; end;
TInstructionOperands = class(TPersistent) TInstructionOperands = class(TPersistent)
@ -594,6 +621,7 @@ type
pfAcceptsLock, pfAcceptsLock,
pfAcceptsREP, pfAcceptsREP,
pfAcceptsREPEREPNE, pfAcceptsREPEREPNE,
pfAcceptsBOUND,
pfAcceptsXACQUIRE, pfAcceptsXACQUIRE,
pfAcceptsXRELEASE, pfAcceptsXRELEASE,
pfAcceptsHLEWithoutLock, pfAcceptsHLEWithoutLock,
@ -1212,10 +1240,14 @@ const
'imm64' 'imm64'
); );
SOperandAccessMode: array[TOperandAccessMode] of String = ( SOperandAction: array[TOperandAction] of String = (
'read', 'read',
'write', 'write',
'readwrite' 'readwrite',
'cond_read',
'cond_write',
'read_cond_write',
'write_cond_read'
); );
{$ENDREGION} {$ENDREGION}
@ -1243,6 +1275,7 @@ const
'accepts_lock', 'accepts_lock',
'accepts_rep', 'accepts_rep',
'accepts_reperepne', 'accepts_reperepne',
'accepts_bound',
'accepts_xacquire', 'accepts_xacquire',
'accepts_xrelease', 'accepts_xrelease',
'accepts_hle_without_lock', 'accepts_hle_without_lock',
@ -1276,12 +1309,7 @@ class function TJSONEnumHelper<TEnum>.ReadValue(JSON: PJSONVariantData; const Na
var var
V: Integer; V: Integer;
begin begin
{$IFDEF DEBUG} Assert(PTypeInfo(TypeInfo(TEnum))^.Kind = tkEnumeration, 'Invalid generic type.');
if (PTypeInfo(TypeInfo(TEnum))^.Kind <> tkEnumeration) then
begin
raise Exception.Create('Invalid generic type.');
end;
{$ENDIF}
V := TStringHelper.IndexStr(ReadString(JSON, Name, ElementStrings[0]), ElementStrings); V := TStringHelper.IndexStr(ReadString(JSON, Name, ElementStrings[0]), ElementStrings);
if (V < 0) then if (V < 0) then
begin begin
@ -1327,23 +1355,10 @@ var
TypData: PTypeData; TypData: PTypeData;
begin begin
TypInfo := TypeInfo(TSet); TypInfo := TypeInfo(TSet);
{$IFDEF DEBUG} Assert(TypInfo^.Kind = tkSet, 'Invalid generic type.');
if (TypInfo^.Kind <> tkSet) then
begin
raise Exception.Create('Invalid generic type.');
end;
{$ENDIF}
TypData := GetTypeData(GetTypeData(TypInfo)^.CompType^); TypData := GetTypeData(GetTypeData(TypInfo)^.CompType^);
{$IFDEF DEBUG} Assert(TypData^.MinValue = 0, 'The enum-type needs to be zero-based.');
if (TypData^.MinValue <> 0) then Assert(TypData^.MaxValue <= 255, 'The enum-type''s maximum value needs the be lower than 256.');
begin
raise Exception.Create('The enum-type needs to be zero-based.');
end;
if (TypData^.MaxValue > 255) then
begin
raise Exception.Create('The enum-type''s maximum value needs the be lower than 256.');
end;
{$ENDIF}
MinValue := TypData^.MinValue; MinValue := TypData^.MinValue;
MaxValue := TypData^.MaxValue; MaxValue := TypData^.MaxValue;
end; end;
@ -1359,12 +1374,8 @@ var
I, J: Integer; I, J: Integer;
begin begin
GetEnumBounds(MinValue, MaxValue); GetEnumBounds(MinValue, MaxValue);
{$IFDEF DEBUG} Assert(MaxValue = High(ElementStrings),
if (MaxValue <> High(ElementStrings)) then 'The size of the string-array does not match the size of the enum-type');
begin
raise Exception.Create('The size of the string-array does not match the size of the enum-type');
end;
{$ENDIF}
FillChar(Pointer(@Result)^, SizeOf(TSet), #0); FillChar(Pointer(@Result)^, SizeOf(TSet), #0);
A := JSON^.Data(Name); A := JSON^.Data(Name);
if (Assigned(A)) then if (Assigned(A)) then
@ -1399,12 +1410,8 @@ var
I: Integer; I: Integer;
begin begin
GetEnumBounds(MinValue, MaxValue); GetEnumBounds(MinValue, MaxValue);
{$IFDEF DEBUG} Assert(MaxValue = High(ElementStrings),
if (MaxValue <> High(ElementStrings)) then 'The size of the string-array does not match the size of the enum-type');
begin
raise Exception.Create('The size of the string-array does not match the size of the enum-type');
end;
{$ENDIF}
A.Init; A.Init;
for I := MinValue to MaxValue do for I := MinValue to MaxValue do
begin begin
@ -1789,6 +1796,10 @@ begin
end; end;
end; end;
end; end;
if (regEFLAGS in RegsWrite) then Exclude(RegsWrite, regFLAGS);
if (regEFLAGS in RegsRead) then Exclude(RegsRead, regFLAGS);
for R := regRFLAGS to regFLAGS do for R := regRFLAGS to regFLAGS do
begin begin
if ((R in RegsRead) xor (R in FDefinition.ImplicitRead.Registers)) or if ((R in RegsRead) xor (R in FDefinition.ImplicitRead.Registers)) or
@ -1907,7 +1918,7 @@ begin
D := Dest as TInstructionOperand; D := Dest as TInstructionOperand;
D.FType := FType; D.FType := FType;
D.FEncoding := FEncoding; D.FEncoding := FEncoding;
D.FAccessMode := FAccessMode; D.FAction := FAction;
D.Changed; D.Changed;
end else inherited; end else inherited;
end; end;
@ -1926,7 +1937,7 @@ end;
function TInstructionOperand.Equals(const Value: TInstructionOperand): Boolean; function TInstructionOperand.Equals(const Value: TInstructionOperand): Boolean;
begin begin
Result := Result :=
(Value.FType = FType) and (Value.FEncoding = FEncoding) and (Value.FAccessMode = FAccessMode); (Value.FType = FType) and (Value.FEncoding = FEncoding) and (Value.FAction = FAction);
end; end;
function TInstructionOperand.GetConflictState: Boolean; function TInstructionOperand.GetConflictState: Boolean;
@ -2141,10 +2152,14 @@ begin
end; end;
if (IncludeAccessMode) then if (IncludeAccessMode) then
begin begin
case FAccessMode of case FAction of
opaRead : Result := Result + ' (r)'; opaRead : Result := Result + ' (r)';
opaWrite : Result := Result + ' (w)'; opaWrite : Result := Result + ' (w)';
opaReadWrite: Result := Result + ' (r, w)'; opaReadWrite : Result := Result + ' (r, w)';
opaCondRead : Result := Result + ' (r?)';
opaCondWrite : Result := Result + ' (w?)';
opaReadCondWrite: Result := Result + ' (r, w?)';
opaWriteCondRead: Result := Result + ' (r?, w)';
end; end;
end; end;
end; end;
@ -2165,8 +2180,8 @@ begin
V, 'type', SOperandType)); V, 'type', SOperandType));
SetEncoding(TJSONEnumHelper<TOperandEncoding>.ReadValue( SetEncoding(TJSONEnumHelper<TOperandEncoding>.ReadValue(
V, 'encoding', SOperandEncoding)); V, 'encoding', SOperandEncoding));
SetAccessMode(TJSONEnumHelper<TOperandAccessMode>.ReadValue( SetAction(TJSONEnumHelper<TOperandAction>.ReadValue(
V, 'accessmode', SOperandAccessMode)); V, 'action', SOperandAction));
end; end;
end; end;
@ -2178,17 +2193,19 @@ begin
begin begin
V.Init; V.Init;
V.AddNameValue('type', SOperandType[FType]); V.AddNameValue('type', SOperandType[FType]);
if (FEncoding <> opeNone) then V.AddNameValue('encoding', SOperandEncoding[FEncoding]); if (FEncoding <> opeNone) then
if (FAccessMode <> opaRead) then V.AddNameValue('accessmode', SOperandAccessMode[FAccessMode]); V.AddNameValue('encoding', SOperandEncoding[FEncoding]);
if (FAction <> opaRead) then
V.AddNameValue('action', SOperandAction[FAction]);
JSON^.AddNameValue(FieldName, Variant(V)); JSON^.AddNameValue(FieldName, Variant(V));
end; end;
end; end;
procedure TInstructionOperand.SetAccessMode(const Value: TOperandAccessMode); procedure TInstructionOperand.SetAction(const Value: TOperandAction);
begin begin
if (FAccessMode <> Value) then if (FAction <> Value) then
begin begin
FAccessMode := Value; FAction := Value;
Changed; Changed;
end; end;
end; end;
@ -2923,6 +2940,8 @@ begin
Include(Conflicts, idcOperands); Include(Conflicts, idcOperands);
end; end;
// TODO: FExtensions.ModrmReg and FExtensions.ModrmRm requires FExtensions.ModrmMod <> mdNeutral
if ((pfAcceptsXACQUIRE in FPrefixFlags) or (pfAcceptsXRELEASE in FPrefixFlags)) and if ((pfAcceptsXACQUIRE in FPrefixFlags) or (pfAcceptsXRELEASE in FPrefixFlags)) and
(not ((pfAcceptsLock in FPrefixFlags) or (pfAcceptsHLEWithoutLock in FPrefixFlags))) then (not ((pfAcceptsLock in FPrefixFlags) or (pfAcceptsHLEWithoutLock in FPrefixFlags))) then
begin begin
@ -2951,7 +2970,7 @@ begin
if (FX86Flags.HasConflicts) then if (FX86Flags.HasConflicts) then
begin begin
Include(Conflicts, idcX86Flags); //Include(Conflicts, idcX86Flags);
end; end;
// TODO: Check for more conflicts // TODO: Check for more conflicts
if (FConflicts <> Conflicts) then if (FConflicts <> Conflicts) then

View File

@ -326,9 +326,9 @@ begin
end; end;
if (Length(A) >= 1) then if (Length(A) >= 1) then
begin begin
if (A[1] = 'r') then TInstructionOperand(GetOrdValue).AccessMode := opaRead if (A[1] = 'r') then TInstructionOperand(GetOrdValue).Action := opaRead
else if (A[1] = 'w') then TInstructionOperand(GetOrdValue).AccessMode := opaWrite else if (A[1] = 'w') then TInstructionOperand(GetOrdValue).Action := opaWrite
else if (A[1] = 'rw') then TInstructionOperand(GetOrdValue).AccessMode := opaReadWrite; else if (A[1] = 'rw') then TInstructionOperand(GetOrdValue).Action := opaReadWrite;
end; end;
end; end;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -98,9 +98,9 @@ static ZydisStatus ZydisFormatterPrintMnemonic(ZydisInstructionFormatter* format
info->userData = (void*)1; info->userData = (void*)1;
// Rewrite the instruction-mnemonic for the given instructions // Rewrite the instruction-mnemonic for the given instructions
if ((info->operandCount == 3) && (info->operand[2].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)) if ((info->operandCount == 3) && (info->operands[2].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
{ {
uint8_t conditionCode = info->operand[2].imm.value.ubyte; uint8_t conditionCode = info->operands[2].imm.value.ubyte;
if (conditionCode < 0x08) if (conditionCode < 0x08)
{ {
switch (info->mnemonic) switch (info->mnemonic)
@ -118,9 +118,9 @@ static ZydisStatus ZydisFormatterPrintMnemonic(ZydisInstructionFormatter* format
} }
} }
} }
if ((info->operandCount == 4) && (info->operand[3].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)) if ((info->operandCount == 4) && (info->operands[3].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
{ {
uint8_t conditionCode = info->operand[3].imm.value.ubyte; uint8_t conditionCode = info->operands[3].imm.value.ubyte;
if (conditionCode < 0x20) if (conditionCode < 0x20)
{ {
switch (info->mnemonic) switch (info->mnemonic)
@ -203,11 +203,6 @@ void disassembleBuffer(uint8_t* data, size_t length, bool installHooks)
while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info))) while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info)))
{ {
printf("%016" PRIX64 " ", info.instrAddress); printf("%016" PRIX64 " ", info.instrAddress);
if (info.instrFlags & ZYDIS_INSTRFLAG_ERROR_MASK)
{
printf(" db %02x\n", info.data[0]);
continue;
}
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

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -27,8 +27,8 @@
#ifndef ZYDIS_DECODER_H #ifndef ZYDIS_DECODER_H
#define ZYDIS_DECODER_H #define ZYDIS_DECODER_H
#include <stdint.h>
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h> #include <Zydis/Status.h>
#include <Zydis/Input.h> #include <Zydis/Input.h>
#include <Zydis/InstructionInfo.h> #include <Zydis/InstructionInfo.h>
@ -55,40 +55,6 @@ typedef uint32_t ZydisDecoderFlags;
* have one of the @c ZYDIS_INSTRFLAG_ERROR_MASK flags set. * have one of the @c ZYDIS_INSTRFLAG_ERROR_MASK flags set.
*/ */
#define ZYDIS_DECODER_FLAG_SKIP_DATA 0x00000001 #define ZYDIS_DECODER_FLAG_SKIP_DATA 0x00000001
/**
* @brief Includes information about all registers implicitly used by the instruction.
*
* If the @c ZYDIS_FEATURE_IMPLICITLY_USED_REGISTERS feature is not available,
* @c ZydisDecoderDecodeNextInstruction will fail with
* @c ZYDIS_STATUS_INVALID_OPERATION.
*/
#define ZYDIS_DECODER_FLAG_REGISTER_USAGE_IMPLICIT 0x00000002
/**
* @brief Includes information about all registers explicitly used by the instruction.
*/
#define ZYDIS_DECODER_FLAG_REGISTER_USAGE_EXPLICIT 0x00000004
/**
* @brief Includes information about all registers indicrectly used by the instruction.
*
* For example:
* [1] If the instruction accesses the RAX register, it indirectly accesses the EAX/AX/AL/AH
* registers as well.
* [2] If the instruction accesses the AL register, it indirectly accesses the AX/EAX/RAX
* registers as well.
*
* This flag only works if either the @c ZYDIS_DECODER_FLAG_REGISTER_USAGE_IMPLICIT and/or the
* @c ZYDIS_DECODER_FLAG_REGISTER_USAGE_EXPLICIT flag is set.
*/
#define ZYDIS_DECODER_FLAG_REGISTER_USAGE_INDIRECT 0x00000008
/**
* @brief Includes information about bits of the FLAGS/EFLAGS/RFLAGS register that are
* affected by the instruction.
*/
#define ZYDIS_DECODER_FLAG_AFFECTED_FLAGS 0x00000010
/**
* @brief Includes information about the CPUID feature flags of the the instruction.
*/
#define ZYDIS_DECODER_FLAG_CPUID 0x00000020
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -116,12 +82,30 @@ typedef struct ZydisInstructionDecoder_
/** /**
* @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.
*/ */
bool imm8initialized; ZydisBool imm8initialized;
/** /**
* @brief Internal field. We have to store a copy of the imm8 value for instructions that * @brief Internal field. We have to store a copy of the imm8 value for instructions that
* encode different operands in the lo and hi part of the immediate. * encode different operands in the lo and hi part of the immediate.
*/ */
uint8_t imm8; uint8_t imm8;
/**
* @brief Internal field. The 0x66 prefix can be consumed, if it is used as mandatory-prefix.
* This field contains the prefix-byte, if the prefix is present and not already
* consumed.
*/
uint8_t hasUnusedPrefix66;
/**
* @brief Internal field. The mutally exclusive 0xF2 and 0xF3 prefixs can be consumed, if
* they are used as mandatory-prefix. This field contains the prefix-byte of the
* latest 0xF2 or 0xF3 prefix, if one of the prefixes is present and not already
* consumed.
*/
uint8_t hasUnusedPrefixF2F3;
/**
* @brief Internal field. Contains the latest (significant) segment prefix.
*/
uint8_t lastSegmentPrefix;
/** /**
* @brief Internal buffer. * @brief Internal buffer.
*/ */

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -27,7 +27,6 @@
#ifndef ZYDIS_FORMATTER_H #ifndef ZYDIS_FORMATTER_H
#define ZYDIS_FORMATTER_H #define ZYDIS_FORMATTER_H
#include <stdint.h>
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Status.h> #include <Zydis/Status.h>
#include <Zydis/InstructionInfo.h> #include <Zydis/InstructionInfo.h>

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -27,10 +27,9 @@
#ifndef ZYDIS_INPUT_H #ifndef ZYDIS_INPUT_H
#define ZYDIS_INPUT_H #define ZYDIS_INPUT_H
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h> #include <Zydis/Status.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -60,7 +59,7 @@ typedef struct ZydisCustomInput_ ZydisCustomInput;
* This function should return the byte at the current input-position and increase the position * This function should return the byte at the current input-position and increase the position
* by one. * by one.
*/ */
typedef bool (*ZydisInputNextFunc)(ZydisCustomInput* input, uint8_t* data); typedef ZydisBool (*ZydisInputNextFunc)(ZydisCustomInput* input, uint8_t* data);
/** /**
* @brief Defines the zydis custom input struct. * @brief Defines the zydis custom input struct.

View File

@ -1,187 +0,0 @@
/***************************************************************************************************
Zyan Disassembler Engine (Zydis)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
#ifndef ZYDIS_INSTRUCTIONDETAILS_H
#define ZYDIS_INSTRUCTIONDETAILS_H
#include <stdint.h>
#include <stdbool.h>
#include <Zydis/Defines.h>
#include <Zydis/InstructionInfo.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ============================================================================================== */
/* CPUID */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Enums and types */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisRegisterAccessFlags datatype.
*/
typedef uint8_t ZydisRegisterAccessFlags;
/**
* @brief The instruction reads from this register.
*/
#define ZYDIS_REGISTER_ACCESS_READ 0x01
/**
* @brief The instruction writes to this register.
*/
#define ZYDIS_REGISTER_ACCESS_WRITE 0x02
/**
* @brief The instruction implicitly reads from this register.
*/
#define ZYDIS_REGISTER_ACCESS_IMPLICIT_READ 0x04
/**
* @brief The instruction implicitly writes to this register.
*/
#define ZYDIS_REGISTER_ACCESS_IMPLICIT_WRITE 0x08
/**
* @brief The instruction indirectly reads from this register.
*
* For example:
* [1] If the instruction accesses the RAX register, it indirectly accesses the
* EAX/AX/AL/AH registers as well.
* [2] If the instruction accesses the AL register, it indirectly accesses the
* AX/EAX/RAX registers as well.
*/
#define ZYDIS_REGISTER_ACCESS_INDIRECT_READ 0x10
/**
* @brief The instruction indirectly writes to this register.
*
* For example:
* [1] If the instruction accesses the RAX register, it indirectly accesses the
* EAX/AX/AL/AH registers as well.
* [2] If the instruction accesses the AL register, it indirectly accesses the
* AX/EAX/RAX registers as well.
*/
#define ZYDIS_REGISTER_ACCESS_INDIRECT_WRITE 0x20
/**
* @brief The instruction indirectly and implicitly reads from this register.
*
* For example:
* [1] If the instruction accesses the RAX register, it indirectly accesses the
* EAX/AX/AL/AH registers as well.
* [2] If the instruction accesses the AL register, it indirectly accesses the
* AX/EAX/RAX registers as well.
*/
#define ZYDIS_REGISTER_ACCESS_INDIRECT_IMPLICIT_READ 0x40
/**
* @brief The instruction indirectly and implicitly writes to this register.
*
* For example:
* [1] If the instruction accesses the RAX register, it indirectly accesses the
* EAX/AX/AL/AH registers as well.
* [2] If the instruction accesses the AL register, it indirectly accesses the
* AX/EAX/RAX registers as well.
*/
#define ZYDIS_REGISTER_ACCESS_INDIRECT_IMPLICIT_WRITE 0x80
/**
* @brief Defines the @c ZydisRegisterInfo struct.
*/
typedef struct ZydisRegisterInfo_
{
/**
* @brief The number of items in the @c reg array.
*/
uint8_t count;
/**
* @brief Array with advanced information about every register used by the current
* instruction.
*/
struct
{
/**
* @brief The register id.
*/
ZydisRegister id;
/**
* @brief The register access-flags.
*/
ZydisRegisterAccessFlags access;
} reg[255];
} ZydisRegisterInfo;
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the zydis cpuid-feature-flag datatype.
*/
typedef uint8_t ZydisCPUIDFeatureFlag;
/**
* @brief Values that represent zydis cpuid feature flags.
*/
enum ZydisCPUIDFeatureFlags
{
ZYDIS_CPUID_FEATURE_NONE
};
/* ---------------------------------------------------------------------------------------------- */
/* Exported functions */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Retrieves the first CPUID feature-flag of the given instruction.
*
* @param info A pointer to the instruction-info struct.
* @param featureFlag A pointer to the memory that receives the first CPUID feature-flag.
*
* @return @c True if the function succeeds, @c false if the instruction does not have any CPUID
* feature-flags assigned.
*/
ZYDIS_EXPORT bool ZydisGetFirstCPUIDFeatureFlag(const ZydisInstructionInfo* info,
ZydisCPUIDFeatureFlag* featureFlag);
/**
* @brief Retrieves the next CPUID feature-flag of the given instruction.
*
* @param info A pointer to the instruction-info struct.
* @param featureFlag A pointer to the memory that contains the last CPUID feature-flag and
* receives the next one.
*
* @return @c True if the function succeeds, @c false if the instruction does not have another
* CPUID feature-flag assigned.
*/
ZYDIS_EXPORT bool ZydisGetNextCPUIDFeatureFlag(const ZydisInstructionInfo* info,
ZydisCPUIDFeatureFlag* featureFlag);
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
#ifdef __cplusplus
}
#endif
#endif /* ZYDIS_INSTRUCTIONDETAILS_H */

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@ typedef struct ZydisInstructionDefinition_
uint32_t acceptsLock : 1; uint32_t acceptsLock : 1;
uint32_t acceptsREP : 1; uint32_t acceptsREP : 1;
uint32_t acceptsREPEREPNE : 1; uint32_t acceptsREPEREPNE : 1;
uint32_t acceptsBOUND : 1;
uint32_t acceptsXACQUIRE : 1; uint32_t acceptsXACQUIRE : 1;
uint32_t acceptsXRELEASE : 1; uint32_t acceptsXRELEASE : 1;
uint32_t acceptsHLEWithoutLock : 1; uint32_t acceptsHLEWithoutLock : 1;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -27,7 +27,6 @@
#ifndef ZYDIS_INSTRUCTIONTABLE_H #ifndef ZYDIS_INSTRUCTIONTABLE_H
#define ZYDIS_INSTRUCTIONTABLE_H #define ZYDIS_INSTRUCTIONTABLE_H
#include <stdint.h>
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Mnemonic.h> #include <Zydis/Mnemonic.h>
#include <Zydis/InstructionInfo.h> #include <Zydis/InstructionInfo.h>
@ -89,7 +88,7 @@ typedef struct ZydisOperandDefinition_
{ {
ZydisSemanticOperandType type : 7; ZydisSemanticOperandType type : 7;
ZydisOperandEncoding encoding : 5; ZydisOperandEncoding encoding : 5;
ZydisOperandAccess access : 2; ZydisOperandAction action : 3;
} ZydisOperandDefinition; } ZydisOperandDefinition;
#include <Zydis/Internal/GeneratedTypes.inc> #include <Zydis/Internal/GeneratedTypes.inc>
@ -139,7 +138,7 @@ enum ZydisInstructionTableNodeTypes
*/ */
ZYDIS_NODETYPE_FILTER_OPCODE = 0x07, ZYDIS_NODETYPE_FILTER_OPCODE = 0x07,
/** /**
* @brief Reference to an vex-map filter. * @brief Reference to an vex/evex-map filter.
*/ */
ZYDIS_NODETYPE_FILTER_VEX = 0x08, ZYDIS_NODETYPE_FILTER_VEX = 0x08,
/** /**
@ -337,7 +336,7 @@ ZYDIS_NO_EXPORT const ZydisInstructionTableNode* ZydisInstructionTableGetChildNo
* *
* @return @c TRUE, if @c node contained a valid instruction-definition, @c FALSE if not. * @return @c TRUE, if @c node contained a valid instruction-definition, @c FALSE if not.
*/ */
ZYDIS_NO_EXPORT bool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node, ZYDIS_NO_EXPORT ZydisBool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
const ZydisInstructionDefinition** definition, const ZydisOperandDefinition** operands, const ZydisInstructionDefinition** definition, const ZydisOperandDefinition** operands,
uint8_t* operandCount); uint8_t* operandCount);

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -27,8 +27,8 @@
#ifndef ZYDIS_MNEMONIC_H #ifndef ZYDIS_MNEMONIC_H
#define ZYDIS_MNEMONIC_H #define ZYDIS_MNEMONIC_H
#include <stdint.h>
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h> #include <Zydis/Status.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -59,17 +59,6 @@ typedef uint16_t ZydisInstructionMnemonic;
*/ */
ZYDIS_EXPORT const char* ZydisMnemonicGetString(ZydisInstructionMnemonic mnemonic); ZYDIS_EXPORT const char* ZydisMnemonicGetString(ZydisInstructionMnemonic mnemonic);
/**
* @brief Replaces the string representation of the given mnemonic with a new value.
*
* @param mnemonic The mnemonic.
* @param mnemonicString The new mnemonic string. Use @c NULL to restore default value.
*
* @return A zydis status code.
*/
ZYDIS_EXPORT ZydisStatus ZydisMnemonicReplaceString(ZydisInstructionMnemonic mnemonic,
const char* mnemonicString);
/* ============================================================================================== */ /* ============================================================================================== */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -27,9 +27,9 @@
#ifndef ZYDIS_REGISTER_H #ifndef ZYDIS_REGISTER_H
#define ZYDIS_REGISTER_H #define ZYDIS_REGISTER_H
#include <stdint.h>
#include <stdbool.h>
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -39,6 +39,10 @@ extern "C" {
/* Enums and types */ /* Enums and types */
/* ============================================================================================== */ /* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Registers */
/* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Defines the @c ZydisRegister datatype. * @brief Defines the @c ZydisRegister datatype.
*/ */
@ -58,7 +62,7 @@ enum ZydisRegisters
// General purpose registers 32-bit // General purpose registers 32-bit
ZYDIS_REGISTER_EAX, ZYDIS_REGISTER_ECX, ZYDIS_REGISTER_EDX, ZYDIS_REGISTER_EBX, ZYDIS_REGISTER_EAX, ZYDIS_REGISTER_ECX, ZYDIS_REGISTER_EDX, ZYDIS_REGISTER_EBX,
ZYDIS_REGISTER_ESP, ZYDIS_REGISTER_EBP, ZYDIS_REGISTER_ESI, ZYDIS_REGISTER_EDI, ZYDIS_REGISTER_ESP, ZYDIS_REGISTER_EBP, ZYDIS_REGISTER_ESI, ZYDIS_REGISTER_EDI,
ZYDIS_REGISTER_R8D, ZYDIS_REGISTER_r9D, ZYDIS_REGISTER_R10D, ZYDIS_REGISTER_R11D, ZYDIS_REGISTER_R8D, ZYDIS_REGISTER_R9D, ZYDIS_REGISTER_R10D, ZYDIS_REGISTER_R11D,
ZYDIS_REGISTER_R12D, ZYDIS_REGISTER_R13D, ZYDIS_REGISTER_R14D, ZYDIS_REGISTER_R15D, ZYDIS_REGISTER_R12D, ZYDIS_REGISTER_R13D, ZYDIS_REGISTER_R14D, ZYDIS_REGISTER_R15D,
// General purpose registers 16-bit // General purpose registers 16-bit
ZYDIS_REGISTER_AX, ZYDIS_REGISTER_CX, ZYDIS_REGISTER_DX, ZYDIS_REGISTER_BX, ZYDIS_REGISTER_AX, ZYDIS_REGISTER_CX, ZYDIS_REGISTER_DX, ZYDIS_REGISTER_BX,
@ -104,10 +108,12 @@ enum ZydisRegisters
ZYDIS_REGISTER_XMM20, ZYDIS_REGISTER_XMM21, ZYDIS_REGISTER_XMM22, ZYDIS_REGISTER_XMM23, ZYDIS_REGISTER_XMM20, ZYDIS_REGISTER_XMM21, ZYDIS_REGISTER_XMM22, ZYDIS_REGISTER_XMM23,
ZYDIS_REGISTER_XMM24, ZYDIS_REGISTER_XMM25, ZYDIS_REGISTER_XMM26, ZYDIS_REGISTER_XMM27, ZYDIS_REGISTER_XMM24, ZYDIS_REGISTER_XMM25, ZYDIS_REGISTER_XMM26, ZYDIS_REGISTER_XMM27,
ZYDIS_REGISTER_XMM28, ZYDIS_REGISTER_XMM29, ZYDIS_REGISTER_XMM30, ZYDIS_REGISTER_XMM31, ZYDIS_REGISTER_XMM28, ZYDIS_REGISTER_XMM29, ZYDIS_REGISTER_XMM30, ZYDIS_REGISTER_XMM31,
// Flags registers
ZYDIS_REGISTER_RFLAGS, ZYDIS_REGISTER_EFLAGS, ZYDIS_REGISTER_FLAGS,
// Instruction-pointer registers
ZYDIS_REGISTER_RIP, ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_IP,
// Special registers // Special registers
ZYDIS_REGISTER_RFLAGS, ZYDIS_REGISTER_EFLAGS, ZYDIS_REGISTER_FLAGS, ZYDIS_REGISTER_RIP, ZYDIS_REGISTER_MXCSR, ZYDIS_REGISTER_PKRU, ZYDIS_REGISTER_XCR0,
ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_IP, ZYDIS_REGISTER_MXCSR, ZYDIS_REGISTER_PKRU,
ZYDIS_REGISTER_XCR0,
// Segment registers // Segment registers
ZYDIS_REGISTER_ES, ZYDIS_REGISTER_SS, ZYDIS_REGISTER_CS, ZYDIS_REGISTER_DS, ZYDIS_REGISTER_ES, ZYDIS_REGISTER_SS, ZYDIS_REGISTER_CS, ZYDIS_REGISTER_DS,
ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS, ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS,
@ -129,11 +135,13 @@ enum ZydisRegisters
// Mask registers // Mask registers
ZYDIS_REGISTER_K0, ZYDIS_REGISTER_K1, ZYDIS_REGISTER_K2, ZYDIS_REGISTER_K3, ZYDIS_REGISTER_K0, ZYDIS_REGISTER_K1, ZYDIS_REGISTER_K2, ZYDIS_REGISTER_K3,
ZYDIS_REGISTER_K4, ZYDIS_REGISTER_K5, ZYDIS_REGISTER_K6, ZYDIS_REGISTER_K7, ZYDIS_REGISTER_K4, ZYDIS_REGISTER_K5, ZYDIS_REGISTER_K6, ZYDIS_REGISTER_K7,
// Bounds registers // Bound registers
ZYDIS_REGISTER_BND0, ZYDIS_REGISTER_BND1, ZYDIS_REGISTER_BND2, ZYDIS_REGISTER_BND3, ZYDIS_REGISTER_BND0, ZYDIS_REGISTER_BND1, ZYDIS_REGISTER_BND2, ZYDIS_REGISTER_BND3,
ZYDIS_REGISTER_BNDCFG, ZYDIS_REGISTER_BNDSTATUS ZYDIS_REGISTER_BNDCFG, ZYDIS_REGISTER_BNDSTATUS
}; };
/* ---------------------------------------------------------------------------------------------- */
/* Register classes */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
@ -146,210 +154,87 @@ typedef uint8_t ZydisRegisterClass;
*/ */
enum ZydisRegisterClasses enum ZydisRegisterClasses
{ {
ZYDIS_REGISTERCLASS_NONE, ZYDIS_REGCLASS_INVALID,
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8, /**
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16, * @brief 8-bit general-purpose registers.
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32, */
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64, ZYDIS_REGCLASS_GPR8,
ZYDIS_REGISTERCLASS_FLOATING_POINT, /**
ZYDIS_REGISTERCLASS_MULTIMEDIA, * @brief 16-bit general-purpose registers.
ZYDIS_REGISTERCLASS_VECTOR128, */
ZYDIS_REGISTERCLASS_VECTOR256, ZYDIS_REGCLASS_GPR16,
ZYDIS_REGISTERCLASS_VECTOR512, /**
ZYDIS_REGISTERCLASS_FLAGS, * @brief 32-bit general-purpose registers.
ZYDIS_REGISTERCLASS_IP, */
ZYDIS_REGISTERCLASS_SEGMENT, ZYDIS_REGCLASS_GPR32,
ZYDIS_REGISTERCLASS_TABLE, /**
ZYDIS_REGISTERCLASS_TEST, * @brief 64-bit general-purpose registers.
ZYDIS_REGISTERCLASS_CONTROL, */
ZYDIS_REGISTERCLASS_DEBUG, ZYDIS_REGCLASS_GPR64,
ZYDIS_REGISTERCLASS_MASK, /**
ZYDIS_REGISTERCLASS_BOUNDS * @brief Floating point legacy registers.
*/
ZYDIS_REGCLASS_X87,
/**
* @brief Floating point multimedia registers.
*/
ZYDIS_REGCLASS_MMX,
/**
* @brief 128-bit vector registers.
*/
ZYDIS_REGCLASS_XMM,
/**
* @brief 256-bit vector registers.
*/
ZYDIS_REGCLASS_YMM,
/**
* @brief 512-bit vector registers.
*/
ZYDIS_REGCLASS_ZMM,
/**
* @brief Flags registers.
*/
ZYDIS_REGCLASS_FLAGS,
/**
* @brief Instruction-pointer registers.
*/
ZYDIS_REGCLASS_IP,
/**
* @brief Segment registers.
*/
ZYDIS_REGCLASS_SEGMENT,
/**
* @brief Test registers.
*/
ZYDIS_REGCLASS_TEST,
/**
* @brief Control registers.
*/
ZYDIS_REGCLASS_CONTROL,
/**
* @brief Debug registers.
*/
ZYDIS_REGCLASS_DEBUG,
/**
* @brief Mask registers.
*/
ZYDIS_REGCLASS_MASK,
/**
* @brief Bound registers.
*/
ZYDIS_REGCLASS_BOUND
}; };
/* ---------------------------------------------------------------------------------------------- */
/* Register width */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Defines the @c ZydisRegisterSize datatype. * @brief Defines the @c ZydisRegisterWidth datatype.
*/ */
typedef uint32_t ZydisRegisterSize; typedef uint16_t ZydisRegisterWidth;
/** /* ---------------------------------------------------------------------------------------------- */
* @brief Values that represent zydis register-sizes.
*/
enum ZydisRegisterSizes
{
ZYDIS_REGISTERSIZE_INVALID = 0,
ZYDIS_REGISTERSIZE_DYNAMIC = 1,
ZYDIS_REGISTERSIZE_8 = 8,
ZYDIS_REGISTERSIZE_16 = 16,
ZYDIS_REGISTERSIZE_32 = 32,
ZYDIS_REGISTERSIZE_64 = 64,
ZYDIS_REGISTERSIZE_80 = 80,
ZYDIS_REGISTERSIZE_128 = 128,
ZYDIS_REGISTERSIZE_256 = 256,
ZYDIS_REGISTERSIZE_512 = 512
};
/* ============================================================================================== */
/* Macros */
/* ============================================================================================== */
/**
* @brief Checks, if the given register is a general-purpose register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_GPR(reg) \
((ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8) ||) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16) || \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32))
/**
* @brief Checks, if the given register is a 8-bit general-purpose register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_GPR8(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8)
/**
* @brief Checks, if the given register is a 16-bit general-purpose register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_GPR16(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16)
/**
* @brief Checks, if the given register is a 32-bit general-purpose register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_GPR32(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32)
/**
* @brief Checks, if the given register is a legacy floating-point register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_FLOATING_POINT(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_FLOATING_POINT)
/**
* @brief Checks, if the given register is a multimedia floating-point register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_MLUTIMEDIA(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_MULTIMEDIA)
/**
* @brief Checks, if the given register is a vector register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_VECTOR(reg) \
((ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR128) ||) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR256) || \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR512))
/**
* @brief Checks, if the given register is a 128-bit vector register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_VECTOR128(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR128)
/**
* @brief Checks, if the given register is a 256-bit vector register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_VECTOR256(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR256)
/**
* @brief Checks, if the given register is a 512-bit vector register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_VECTOR512(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR512)
/**
* @brief Checks, if the given register is a flags register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_FLAGS(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_FLAGS)
/**
* @brief Checks, if the given register is an instruction-pointer register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_IP(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_IP)
/**
* @brief Checks, if the given register is a segment register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_SEGMENT(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_SEGMENT)
/**
* @brief Checks, if the given register is a table register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_TABLE(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_TABLE)
/**
* @brief Checks, if the given register is a test register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_TEST(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_TEST)
/**
* @brief Checks, if the given register is a control register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_CONTROL(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_CONTROL)
/**
* @brief Checks, if the given register is a debug register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_DEBUG(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_DEBUG)
/**
* @brief Checks, if the given register is a mask register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_MASK(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_MASK)
/**
* @brief Checks, if the given register is a bounds register.
*
* @param reg The register.
*/
#define ZYDIS_REGISTER_IS_BOUNDS(reg) \
(ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_BOUNDS)
/* ============================================================================================== */ /* ============================================================================================== */
/* Exported functions */ /* Exported functions */
@ -361,9 +246,19 @@ enum ZydisRegisterSizes
* @param registerClass The register class. * @param registerClass The register class.
* @param id The register id. * @param id The register id.
* *
* @return The register specified by the @c registerClass and the @c id. * @return The register specified by the @c registerClass and the @c id or @c ZYDIS_REGISTER_NONE,
* if an invalid parameter was passed.
*/ */
ZYDIS_EXPORT ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass, uint8_t id); ZYDIS_EXPORT ZydisRegister ZydisRegisterEncode(ZydisRegisterClass registerClass, uint8_t id);
/**
* @brief Returns the id of the specified register.
*
* @param reg The register.
*
* @return The id of the specified register, or -1 if an invalid parameter was passed.
*/
ZYDIS_EXPORT int16_t ZydisRegisterGetId(ZydisRegister reg);
/** /**
* @brief Returns the register-class of the specified register. * @brief Returns the register-class of the specified register.
@ -375,13 +270,22 @@ ZYDIS_EXPORT ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass
ZYDIS_EXPORT ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg); ZYDIS_EXPORT ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg);
/** /**
* @brief Returns the size of the specified register. * @brief Returns the width of the specified register mode.
* *
* @param reg The register. * @param reg The register.
* *
* @return The size of the specified register. * @return The width of the specified register.
*/ */
ZYDIS_EXPORT ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg); ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterGetWidth(ZydisRegister reg);
/**
* @brief Returns the width of the specified register in 64-bit mode.
*
* @param reg The register.
*
* @return The width of the specified register.
*/
ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterGetWidth64(ZydisRegister reg);
/** /**
* @brief Returns the specified register string. * @brief Returns the specified register string.

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -27,7 +27,7 @@
#ifndef ZYDIS_STATUS_H #ifndef ZYDIS_STATUS_H
#define ZYDIS_STATUS_H #define ZYDIS_STATUS_H
#include <stdint.h> #include <Zydis/Types.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -47,6 +47,10 @@ typedef uint32_t ZydisStatus;
*/ */
enum ZydisStatusCode enum ZydisStatusCode
{ {
/* ------------------------------------------------------------------------------------------ */
/* General */
/* ------------------------------------------------------------------------------------------ */
/** /**
* @brief The operation completed successfully. * @brief The operation completed successfully.
*/ */
@ -54,25 +58,71 @@ enum ZydisStatusCode
/** /**
* @brief An invalid parameter was passed to a function. * @brief An invalid parameter was passed to a function.
*/ */
ZYDIS_STATUS_INVALID_PARAMETER = 0x00000001, ZYDIS_STATUS_INVALID_PARAMETER,
/** /**
* @brief An attempt was made to perform an invalid operation. * @brief An attempt was made to perform an invalid operation.
*/ */
ZYDIS_STATUS_INVALID_OPERATION = 0x00000002, ZYDIS_STATUS_INVALID_OPERATION,
/* ------------------------------------------------------------------------------------------ */
/* Decoder */
/* ------------------------------------------------------------------------------------------ */
/** /**
* @brief An attempt was made to read data from an input data-source that has no more data * @brief An attempt was made to read data from an input data-source that has no more data
* available. * available.
*/ */
ZYDIS_STATUS_NO_MORE_DATA = 0x00000003, ZYDIS_STATUS_NO_MORE_DATA,
/** /**
* @brief An error occured while decoding the current instruction. Check the @c instrFlags * @brief An general error occured while decoding the current instruction. The instruction
* field of the @c ZydisInstructionInfo struct for further details. * might be undefined.
*/ */
ZYDIS_STATUS_DECODING_ERROR = 0x00000004, ZYDIS_STATUS_DECODING_ERROR,
/**
* @brief The instruction exceeded the maximum length of 15 bytes.
*/
ZYDIS_STATUS_INSTRUCTION_TOO_LONG,
/**
* @brief The instruction encoded an invalid register.
*/
ZYDIS_STATUS_INVALID_REGISTER,
/**
* @brief A lock-prefix (F0) was found while decoding an instruction that does not support
* locking.
*/
ZYDIS_STATUS_ILLEGAL_LOCK,
/**
* @brief A legacy-prefix (F2, F3, 66) was found while decoding a xop/vex/evex instruction.
*/
ZYDIS_STATUS_ILLEGAL_LEGACY_PFX,
/**
* @brief A rex-prefix was found while decoding a xop/vex/evex instruction.
*/
ZYDIS_STATUS_ILLEGAL_REX,
/**
* @brief An invalid opcode-map value was found while decoding a xop/vex/evex-prefix.
*/
ZYDIS_STATUS_INVALID_MAP,
/**
* @brief An error occured while decoding the evex-prefix.
*/
ZYDIS_STATUS_MALFORMED_EVEX,
// TODO:
ZYDIS_STATUS_INVALID_VSIB,
/* ------------------------------------------------------------------------------------------ */
/* Formatter */
/* ------------------------------------------------------------------------------------------ */
/** /**
* @brief A buffer passed to a function was too small to complete the requested operation. * @brief A buffer passed to a function was too small to complete the requested operation.
*/ */
ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE = 0x00000005, ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE,
/* ------------------------------------------------------------------------------------------ */
/* Misc */
/* ------------------------------------------------------------------------------------------ */
/** /**
* @brief The base value for user-defined status codes. * @brief The base value for user-defined status codes.
*/ */
@ -84,9 +134,9 @@ enum ZydisStatusCode
/* ============================================================================================== */ /* ============================================================================================== */
/** /**
* @brief Checks a zydis status code for success. * @brief Checks if a zydis operation was successfull.
* *
* @param status The status code. * @param status The zydis status-code to check.
*/ */
#define ZYDIS_SUCCESS(status) (status == ZYDIS_STATUS_SUCCESS) #define ZYDIS_SUCCESS(status) (status == ZYDIS_STATUS_SUCCESS)

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -24,32 +24,44 @@
***************************************************************************************************/ ***************************************************************************************************/
#include <Zydis/InstructionDetails.h> /**
* @file
* @brief Includes and defines some default datatypes.
*/
#ifndef ZYDIS_TYPES_H
#define ZYDIS_TYPES_H
/* ============================================================================================== */ /* ============================================================================================== */
/* CPUID */ /* Integral types */
/* ============================================================================================== */ /* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */ /**
/* Exported functions */ * uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t
/* ---------------------------------------------------------------------------------------------- */ */
#include <stdint.h>
bool ZydisGetFirstCPUIDFeatureFlag(const ZydisInstructionInfo* info, /**
ZydisCPUIDFeatureFlag* featureFlag) * size_t, ptrdiff_t
{ */
(void)info; #include <stddef.h>
(void)featureFlag;
return false; /* ============================================================================================== */
/* Boolean */
/* ============================================================================================== */
#define ZYDIS_FALSE 0
#define ZYDIS_TRUE 1
/**
* @briefs Defines the @c ZydisBool datatype.
*/
typedef uint8_t ZydisBool;
/* ============================================================================================== */
#ifdef __cplusplus
} }
#endif
bool ZydisGetNextCPUIDFeatureFlag(const ZydisInstructionInfo* info, #endif /* ZYDIS_TYPES_H */
ZydisCPUIDFeatureFlag* featureFlag)
{
(void)info;
(void)featureFlag;
return false;
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -27,17 +27,16 @@
#ifndef ZYDIS_H #ifndef ZYDIS_H
#define ZYDIS_H #define ZYDIS_H
#include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h> #include <Zydis/Status.h>
#include <Zydis/Mnemonic.h> #include <Zydis/Mnemonic.h>
#include <Zydis/Register.h> #include <Zydis/Register.h>
#include <Zydis/InstructionDetails.h>
#include <Zydis/InstructionInfo.h> #include <Zydis/InstructionInfo.h>
#include <Zydis/Input.h> #include <Zydis/Input.h>
#include <Zydis/Decoder.h> #include <Zydis/Decoder.h>
#include <Zydis/Formatter.h> #include <Zydis/Formatter.h>
// TODO: Replace "bool" with a custom - compiler-unspecific sized - zype
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -94,7 +93,7 @@ extern "C" {
/* ============================================================================================== */ /* ============================================================================================== */
/** /**
* @brief Defines the zydis feature datatype. * @brief Defines the @c ZydisFeature datatype.
*/ */
typedef uint8_t ZydisFeature; typedef uint8_t ZydisFeature;
@ -129,7 +128,7 @@ ZYDIS_EXPORT uint64_t ZydisGetVersion();
* *
* @return @c True if the feature is enabled, @c false if not. * @return @c True if the feature is enabled, @c false if not.
*/ */
ZYDIS_EXPORT bool ZydisIsFeatureEnabled(ZydisFeature feature); ZYDIS_EXPORT ZydisBool ZydisIsFeatureEnabled(ZydisFeature feature);
/* ============================================================================================== */ /* ============================================================================================== */

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -26,12 +26,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <inttypes.h> #include <inttypes.h>
#include <assert.h>
#include <Zydis/Status.h>
#include <Zydis/Formatter.h> #include <Zydis/Formatter.h>
#include <Zydis/Utils.h> #include <Zydis/Utils.h>
@ -206,33 +203,34 @@ static ZydisStatus ZydisFormatterPrintPrefixesIntel(ZydisInstructionFormatter* f
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_LOCK) && if (info->attributes & ZYDIS_ATTRIB_HAS_LOCK)
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_LOCK))
{ {
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "lock "); return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "lock ");
} }
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REP) && if (info->attributes & ZYDIS_ATTRIB_HAS_REP)
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP))
{ {
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "rep "); return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "rep ");
} }
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REPE) && if (info->attributes & ZYDIS_ATTRIB_HAS_REPE)
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPE))
{ {
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "repe "); return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "repe ");
} }
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REPNE) && if (info->attributes & ZYDIS_ATTRIB_HAS_REPNE)
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE))
{ {
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "repne "); return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "repne ");
} }
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_XACQUIRE) if (info->attributes & ZYDIS_ATTRIB_HAS_BOUND)
{
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "bnd ");
}
if (info->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE)
{ {
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "xacquire "); return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "xacquire ");
} }
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_XRELEASE) if (info->attributes & ZYDIS_ATTRIB_HAS_XRELEASE)
{ {
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "xrelease "); return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "xrelease ");
} }
@ -287,8 +285,10 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(ZydisInstructionFormatter
ZYDIS_CHECK( ZYDIS_CHECK(
ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "[")); ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "["));
if ((operand->mem.disp.dataSize != 0) && ((operand->mem.base == ZYDIS_REGISTER_NONE) || if ((operand->mem.disp.dataSize != 0) && (
(operand->mem.base == ZYDIS_REGISTER_EIP) || (operand->mem.base == ZYDIS_REGISTER_RIP)) && (operand->mem.base == ZYDIS_REGISTER_NONE) ||
(operand->mem.base == ZYDIS_REGISTER_EIP) ||
(operand->mem.base == ZYDIS_REGISTER_RIP)) &&
(operand->mem.index == ZYDIS_REGISTER_NONE) && (operand->mem.scale == 0)) (operand->mem.index == ZYDIS_REGISTER_NONE) && (operand->mem.scale == 0))
{ {
// Address operand // Address operand
@ -362,7 +362,7 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(ZydisInstructionFormatter
// The immediate operand contains an address // The immediate operand contains an address
if (operand->imm.isRelative) if (operand->imm.isRelative)
{ {
bool printSignedHEX = false; ZydisBool printSignedHEX = ZYDIS_FALSE;
switch (formatter->addressFormat) switch (formatter->addressFormat)
{ {
case ZYDIS_FORMATTER_ADDR_DEFAULT: case ZYDIS_FORMATTER_ADDR_DEFAULT:
@ -374,7 +374,7 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(ZydisInstructionFormatter
address); address);
} }
case ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED: case ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED:
printSignedHEX = true; printSignedHEX = ZYDIS_TRUE;
break; break;
case ZYDIS_FORMATTER_ADDR_RELATIVE_UNSIGNED: case ZYDIS_FORMATTER_ADDR_RELATIVE_UNSIGNED:
break; break;
@ -426,11 +426,13 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(ZydisInstructionFormatte
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
if ((operand->mem.disp.dataSize) && ((operand->mem.disp.value.sqword) || if ((operand->mem.disp.dataSize) && ((operand->mem.disp.value.sqword) ||
((operand->mem.base == ZYDIS_REGISTER_NONE) && ((operand->mem.base == ZYDIS_REGISTER_NONE) &&
(operand->mem.index == ZYDIS_REGISTER_NONE)))) (operand->mem.index == ZYDIS_REGISTER_NONE))))
{ {
bool printSignedHEX = (formatter->displacementFormat != ZYDIS_FORMATTER_DISP_HEX_UNSIGNED); ZydisBool printSignedHEX =
(formatter->displacementFormat != ZYDIS_FORMATTER_DISP_HEX_UNSIGNED);
if (printSignedHEX && (operand->mem.disp.value.sqword < 0) && ( if (printSignedHEX && (operand->mem.disp.value.sqword < 0) && (
(operand->mem.base != ZYDIS_REGISTER_NONE) || (operand->mem.base != ZYDIS_REGISTER_NONE) ||
(operand->mem.index != ZYDIS_REGISTER_NONE))) (operand->mem.index != ZYDIS_REGISTER_NONE)))
@ -438,12 +440,13 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(ZydisInstructionFormatte
return ZydisStringBufferAppendFormat(buffer, bufferLen, return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "-0x%02"PRIX32, -operand->mem.disp.value.sdword); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "-0x%02"PRIX32, -operand->mem.disp.value.sdword);
} }
}
const char* sign = const char* sign =
((operand->mem.base == ZYDIS_REGISTER_NONE) && ((operand->mem.base == ZYDIS_REGISTER_NONE) &&
(operand->mem.index == ZYDIS_REGISTER_NONE)) ? "" : "+"; (operand->mem.index == ZYDIS_REGISTER_NONE)) ? "" : "+";
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT, return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"%s0x%02"PRIX32, sign, operand->mem.disp.value.sdword); "%s0x%02"PRIX32, sign, operand->mem.disp.value.sdword);
}
return ZYDIS_STATUS_SUCCESS;
} }
static ZydisStatus ZydisFormatterPrintImmediateIntel(ZydisInstructionFormatter* formatter, static ZydisStatus ZydisFormatterPrintImmediateIntel(ZydisInstructionFormatter* formatter,
@ -454,7 +457,7 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(ZydisInstructionFormatter*
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
bool printSignedHEX = (formatter->immediateFormat == ZYDIS_FORMATTER_IMM_HEX_SIGNED); ZydisBool printSignedHEX = (formatter->immediateFormat == ZYDIS_FORMATTER_IMM_HEX_SIGNED);
if (formatter->immediateFormat == ZYDIS_FORMATTER_IMM_HEX_AUTO) if (formatter->immediateFormat == ZYDIS_FORMATTER_IMM_HEX_AUTO)
{ {
printSignedHEX = operand->imm.isSigned; printSignedHEX = operand->imm.isSigned;
@ -511,21 +514,21 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(ZydisInstructionFormatter
uint32_t typecast = 0; uint32_t typecast = 0;
if (formatter->flags & ZYDIS_FMTFLAG_FORCE_OPERANDSIZE) if (formatter->flags & ZYDIS_FMTFLAG_FORCE_OPERANDSIZE)
{ {
if (info->operand[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY) if (info->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY)
{ {
typecast = info->operand[operand->id].size; typecast = info->operands[operand->id].size;
} }
} else if (info->operand[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY) } else if (info->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY)
{ {
switch (operand->id) switch (operand->id)
{ {
case 0: case 0:
typecast = ((info->operand[1].type == ZYDIS_OPERAND_TYPE_UNUSED) || typecast = ((info->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
(info->operand[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) || (info->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
(info->operand[0].size != info->operand[1].size)) ? info->operand[0].size : 0; (info->operands[0].size != info->operands[1].size)) ? info->operands[0].size : 0;
if (!typecast && if (!typecast &&
(info->operand[1].type == ZYDIS_OPERAND_TYPE_REGISTER) && (info->operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER) &&
(info->operand[1].reg == ZYDIS_REGISTER_CL)) (info->operands[1].reg == ZYDIS_REGISTER_CL))
{ {
switch (info->mnemonic) switch (info->mnemonic)
{ {
@ -536,7 +539,7 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(ZydisInstructionFormatter
case ZYDIS_MNEMONIC_SHL: case ZYDIS_MNEMONIC_SHL:
case ZYDIS_MNEMONIC_SHR: case ZYDIS_MNEMONIC_SHR:
case ZYDIS_MNEMONIC_SAR: case ZYDIS_MNEMONIC_SAR:
typecast = info->operand[0].size; typecast = info->operands[0].size;
default: default:
break; break;
} }
@ -545,8 +548,8 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(ZydisInstructionFormatter
case 1: case 1:
case 2: case 2:
typecast = typecast =
(info->operand[operand->id - 1].size != info->operand[operand->id].size) ? (info->operands[operand->id - 1].size != info->operands[operand->id].size) ?
info->operand[operand->id].size : 0; info->operands[operand->id].size : 0;
break; break;
default: default:
break; break;
@ -610,7 +613,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(ZydisInstructionFormatter* fo
ZydisRegisterGetString(operand->mem.segment)); ZydisRegisterGetString(operand->mem.segment));
case ZYDIS_REGISTER_CS: case ZYDIS_REGISTER_CS:
if ((formatter->flags & ZYDIS_FMTFLAG_FORCE_SEGMENTS) || if ((formatter->flags & ZYDIS_FMTFLAG_FORCE_SEGMENTS) ||
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS)) (info->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_CS))
{ {
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:", return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:",
ZydisRegisterGetString(operand->mem.segment)); ZydisRegisterGetString(operand->mem.segment));
@ -618,7 +621,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(ZydisInstructionFormatter* fo
break; break;
case ZYDIS_REGISTER_DS: case ZYDIS_REGISTER_DS:
if ((formatter->flags & ZYDIS_FMTFLAG_FORCE_SEGMENTS) || if ((formatter->flags & ZYDIS_FMTFLAG_FORCE_SEGMENTS) ||
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS)) (info->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS))
{ {
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:", return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:",
ZydisRegisterGetString(operand->mem.segment)); ZydisRegisterGetString(operand->mem.segment));
@ -627,7 +630,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(ZydisInstructionFormatter* fo
default: default:
break; break;
} }
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_SUCCESS;
} }
static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter* formatter, static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter* formatter,
@ -652,32 +655,32 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter*
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE, ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE,
" {%s}", reg)); " {%s}", reg));
} }
if (info->avx.maskMode == ZYDIS_AVX_MASKMODE_ZERO) if (info->avx.maskMode == ZYDIS_AVX512_MASKMODE_ZERO)
{ {
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
} }
} else } else
{ {
if (info->operand[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY) if (info->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY)
{ {
switch (info->avx.broadcast) switch (info->avx.broadcast)
{ {
case ZYDIS_AVX_BCSTMODE_INVALID: case ZYDIS_AVX512_BCSTMODE_INVALID:
break; break;
case ZYDIS_AVX_BCSTMODE_2: case ZYDIS_AVX512_BCSTMODE_2:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
break; break;
case ZYDIS_AVX_BCSTMODE_4: case ZYDIS_AVX512_BCSTMODE_4:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
break; break;
case ZYDIS_AVX_BCSTMODE_8: case ZYDIS_AVX512_BCSTMODE_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
break; break;
case ZYDIS_AVX_BCSTMODE_16: case ZYDIS_AVX512_BCSTMODE_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
break; break;
@ -688,12 +691,12 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter*
if ((operand->id == (info->operandCount - 1)) || if ((operand->id == (info->operandCount - 1)) ||
((operand->id != (info->operandCount - 1)) && ((operand->id != (info->operandCount - 1)) &&
(info->operand[operand->id + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))) (info->operands[operand->id + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)))
{ {
switch (info->avx.roundingMode) switch (info->avx.roundingMode)
{ {
case ZYDIS_AVX_RNDMODE_INVALID: case ZYDIS_AVX_RNDMODE_INVALID:
if (info->avx.sae) if (info->avx.hasSAE)
{ {
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sae}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sae}"));
@ -751,23 +754,23 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
} }
const char* bufPreOperand = *buffer; const char* bufPreOperand = *buffer;
switch (info->operand[i].type) switch (info->operands[i].type)
{ {
case ZYDIS_OPERAND_TYPE_UNUSED: case ZYDIS_OPERAND_TYPE_UNUSED:
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
case ZYDIS_OPERAND_TYPE_REGISTER: case ZYDIS_OPERAND_TYPE_REGISTER:
ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i])); info, &info->operands[i]));
break; break;
case ZYDIS_OPERAND_TYPE_MEMORY: case ZYDIS_OPERAND_TYPE_MEMORY:
{ {
ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i])); info, &info->operands[i]));
ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i])); info, &info->operands[i]));
const char* bufTemp = *buffer; const char* bufTemp = *buffer;
ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i])); info, &info->operands[i]));
if (bufTemp == *buffer) if (bufTemp == *buffer)
{ {
*buffer = (char*)bufPreOperand; *buffer = (char*)bufPreOperand;
@ -776,11 +779,11 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
} }
case ZYDIS_OPERAND_TYPE_POINTER: case ZYDIS_OPERAND_TYPE_POINTER:
ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i])); info, &info->operands[i]));
break; break;
case ZYDIS_OPERAND_TYPE_IMMEDIATE: case ZYDIS_OPERAND_TYPE_IMMEDIATE:
ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i])); info, &info->operands[i]));
break; break;
default: default:
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -788,7 +791,7 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
if (bufPreOperand == *buffer) if (bufPreOperand == *buffer)
{ {
// Omit whole operand, if the buffer did not change during the formatting-callback // Omit whole operands, if the buffer did not change during the formatting-callback
*buffer = bufRestore; *buffer = bufRestore;
*buffer[0] = 0; *buffer[0] = 0;
} else } else
@ -796,7 +799,7 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX)
{ {
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i])); info, &info->operands[i]));
} }
} }
} }

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -24,8 +24,6 @@
***************************************************************************************************/ ***************************************************************************************************/
#include <assert.h>
#include <Zydis/Status.h>
#include <Zydis/Input.h> #include <Zydis/Input.h>
/* ============================================================================================== */ /* ============================================================================================== */
@ -36,14 +34,14 @@
/* Internal functions */ /* Internal functions */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
static bool ZydisMemoryInputNext(ZydisMemoryInput* input, uint8_t* data) static ZydisBool ZydisMemoryInputNext(ZydisMemoryInput* input, uint8_t* data)
{ {
if (input->inputBufferPos >= input->inputBufferLen) if (input->inputBufferPos >= input->inputBufferLen)
{ {
return false; return ZYDIS_FALSE;
} }
*data = input->inputBuffer[input->inputBufferPos++]; *data = input->inputBuffer[input->inputBufferPos++];
return true; return ZYDIS_TRUE;
} }
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -73,7 +71,7 @@ ZydisStatus ZydisInputInitMemoryInput(ZydisMemoryInput* input, const void* buffe
/* Internal functions */ /* Internal functions */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
static bool ZydisFileInputNext(ZydisFileInput* input, uint8_t* data) static ZydisBool ZydisFileInputNext(ZydisFileInput* input, uint8_t* data)
{ {
int c = fgetc(input->file); int c = fgetc(input->file);
*data = (uint8_t)c; *data = (uint8_t)c;

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -169,7 +169,7 @@ extern const ZydisInstructionTableNode filterEVEXB[][2];
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Contains all operand-definitions with 1 operand. * @brief Contains all operand-definitions with 1 operands.
*/ */
extern const ZydisOperandDefinition operandDefinitions1[][1]; extern const ZydisOperandDefinition operandDefinitions1[][1];
@ -264,7 +264,7 @@ const ZydisInstructionTableNode* ZydisInstructionTableGetChildNode(
return &invalid; return &invalid;
} }
bool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node, ZydisBool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
const ZydisInstructionDefinition** definition, const ZydisOperandDefinition** operands, const ZydisInstructionDefinition** definition, const ZydisOperandDefinition** operands,
uint8_t* operandCount) uint8_t* operandCount)
{ {
@ -296,9 +296,9 @@ bool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
break; break;
default: default:
ZYDIS_UNREACHABLE; ZYDIS_UNREACHABLE;
return false; return ZYDIS_FALSE;
} }
return true; return ZYDIS_TRUE;
} }
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -24,8 +24,6 @@
***************************************************************************************************/ ***************************************************************************************************/
#include <stddef.h>
#include <Zydis/Defines.h>
#include <Zydis/Mnemonic.h> #include <Zydis/Mnemonic.h>
/* ============================================================================================== */ /* ============================================================================================== */
@ -50,12 +48,4 @@ const char* ZydisMnemonicGetString(ZydisInstructionMnemonic mnemonic)
return mnemonicStrings[mnemonic]; return mnemonicStrings[mnemonic];
} }
ZydisStatus ZydisMnemonicReplaceString(ZydisInstructionMnemonic mnemonic,
const char* mnemonicString)
{
(void)mnemonic;
(void)mnemonicString;
return ZYDIS_STATUS_INVALID_OPERATION;
}
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -24,8 +24,6 @@
***************************************************************************************************/ ***************************************************************************************************/
#include <stddef.h>
#include <stdbool.h>
#include <Zydis/Register.h> #include <Zydis/Register.h>
/* ============================================================================================== */ /* ============================================================================================== */
@ -119,96 +117,121 @@ const char* registerStrings[] =
"bndcfg", "bndstatus" "bndcfg", "bndstatus"
}; };
/* ============================================================================================== */
/* Register-class mapping */
/* ============================================================================================== */
struct ZydisRegisterMapItem
{
ZydisRegisterClass class;
ZydisRegister lo;
ZydisRegister hi;
ZydisRegisterWidth width;
ZydisRegisterWidth width64;
};
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_GPR16 , ZYDIS_REGISTER_AX , ZYDIS_REGISTER_R15W , 16 , 16 },
{ ZYDIS_REGCLASS_GPR32 , ZYDIS_REGISTER_EAX , ZYDIS_REGISTER_R15D , 32 , 32 },
{ ZYDIS_REGCLASS_GPR64 , ZYDIS_REGISTER_RAX , ZYDIS_REGISTER_R15 , 0 , 64 },
{ ZYDIS_REGCLASS_X87 , ZYDIS_REGISTER_ST0 , ZYDIS_REGISTER_ST7 , 80 , 80 },
{ ZYDIS_REGCLASS_MMX , ZYDIS_REGISTER_MM0 , ZYDIS_REGISTER_MM7 , 64 , 64 },
{ ZYDIS_REGCLASS_XMM , ZYDIS_REGISTER_XMM0 , ZYDIS_REGISTER_XMM31 , 128 , 128 },
{ ZYDIS_REGCLASS_YMM , ZYDIS_REGISTER_YMM0 , ZYDIS_REGISTER_YMM31 , 256 , 256 },
{ ZYDIS_REGCLASS_ZMM , ZYDIS_REGISTER_ZMM0 , ZYDIS_REGISTER_ZMM31 , 512 , 512 },
{ ZYDIS_REGCLASS_FLAGS , ZYDIS_REGISTER_RFLAGS , ZYDIS_REGISTER_FLAGS , 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_TEST , ZYDIS_REGISTER_TR0 , ZYDIS_REGISTER_TR7 , 32 , 32 },
{ ZYDIS_REGCLASS_CONTROL , ZYDIS_REGISTER_CR0 , ZYDIS_REGISTER_CR7 , 32 , 64 },
{ ZYDIS_REGCLASS_DEBUG , ZYDIS_REGISTER_DR0 , ZYDIS_REGISTER_DR7 , 32 , 64 },
{ ZYDIS_REGCLASS_MASK , ZYDIS_REGISTER_K0 , ZYDIS_REGISTER_K7 , 64 , 64 },
{ ZYDIS_REGCLASS_BOUND , ZYDIS_REGISTER_BND0 , ZYDIS_REGISTER_BND3 , 128 , 128 }
};
static const uint8_t registerMapCount = sizeof(registerMap) / sizeof(struct ZydisRegisterMapItem);
/* ============================================================================================== */ /* ============================================================================================== */
/* Exported functions */ /* Exported functions */
/* ============================================================================================== */ /* ============================================================================================== */
ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass, uint8_t id) ZydisRegister ZydisRegisterEncode(ZydisRegisterClass registerClass, uint8_t id)
{ {
switch (registerClass) switch (registerClass)
{ {
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8: case ZYDIS_REGCLASS_INVALID:
if (id <= 19) case ZYDIS_REGCLASS_FLAGS:
{ case ZYDIS_REGCLASS_IP:
return ZYDIS_REGISTER_AL + id;
}
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16:
if (id <= 15)
{
return ZYDIS_REGISTER_AX + id;
}
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32:
if (id <= 15)
{
return ZYDIS_REGISTER_EAX + id;
}
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64:
if (id <= 15)
{
return ZYDIS_REGISTER_RAX + id;
}
case ZYDIS_REGISTERCLASS_FLOATING_POINT:
if (id <= 7)
{
return ZYDIS_REGISTER_ST0 + id;
}
case ZYDIS_REGISTERCLASS_MULTIMEDIA:
if (id <= 7)
{
return ZYDIS_REGISTER_MM0 + id;
}
case ZYDIS_REGISTERCLASS_VECTOR128:
if (id <= 31)
{
return ZYDIS_REGISTER_XMM0 + id;
}
case ZYDIS_REGISTERCLASS_VECTOR256:
if (id <= 31)
{
return ZYDIS_REGISTER_YMM0 + id;
}
case ZYDIS_REGISTERCLASS_VECTOR512:
if (id <= 31)
{
return ZYDIS_REGISTER_ZMM0 + id;
}
case ZYDIS_REGISTERCLASS_SEGMENT:
if (id <= 5)
{
return ZYDIS_REGISTER_ES + id;
}
case ZYDIS_REGISTERCLASS_TEST:
if (id <= 7)
{
return ZYDIS_REGISTER_TR0 + id;
}
case ZYDIS_REGISTERCLASS_CONTROL:
if (id <= 15)
{
return ZYDIS_REGISTER_CR0 + id;
}
case ZYDIS_REGISTERCLASS_DEBUG:
if (id <= 15)
{
return ZYDIS_REGISTER_DR0 + id;
}
case ZYDIS_REGISTERCLASS_MASK:
if (id <= 7)
{
return ZYDIS_REGISTER_K0 + id;
}
case ZYDIS_REGISTERCLASS_BOUNDS:
if (id <= 3)
{
return ZYDIS_REGISTER_BND0 + id;
}
default:
// The registers of the missing register-classes can not be encoded by the register-id.
break; break;
default:
if ((registerClass < registerMapCount) &&
(id < (registerMap[registerClass].hi - registerMap[registerClass].lo)))
{
return registerMap[registerClass].lo + id;
}
} }
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_NONE;
} }
int16_t ZydisRegisterGetId(ZydisRegister reg)
{
for (unsigned i = 0; i < registerMapCount; ++i)
{
switch (registerMap[i].class)
{
case ZYDIS_REGCLASS_INVALID:
case ZYDIS_REGCLASS_FLAGS:
case ZYDIS_REGCLASS_IP:
break;
default:
if ((reg >= registerMap[i].lo) && (reg <= registerMap[i].hi))
{
return reg - registerMap[i].lo;
}
}
}
return -1;
}
ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg)
{
for (unsigned i = 0; i < registerMapCount; ++i)
{
if ((reg >= registerMap[i].lo) && (reg <= registerMap[i].hi))
{
return registerMap[i].class;
}
}
return ZYDIS_REGCLASS_INVALID;
}
ZydisRegisterWidth ZydisRegisterGetWidth(ZydisRegister reg)
{
for (unsigned i = 0; i < registerMapCount; ++i)
{
if ((reg >= registerMap[i].lo) && (reg <= registerMap[i].hi))
{
return registerMap[i].width;
}
}
return 0;
}
ZydisRegisterWidth ZydisRegisterGetWidth64(ZydisRegister reg)
{
for (unsigned i = 0; i < registerMapCount; ++i)
{
if ((reg >= registerMap[i].lo) && (reg <= registerMap[i].hi))
{
return registerMap[i].width64;
}
}
return 0;
}
const char* ZydisRegisterGetString(ZydisRegister reg) const char* ZydisRegisterGetString(ZydisRegister reg)
{ {
if ((reg == 0) || (reg > (sizeof(registerStrings) / sizeof(registerStrings[0])) - 1)) if ((reg == 0) || (reg > (sizeof(registerStrings) / sizeof(registerStrings[0])) - 1))
@ -218,124 +241,4 @@ const char* ZydisRegisterGetString(ZydisRegister reg)
return registerStrings[reg]; return registerStrings[reg];
} }
ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg)
{
if ((reg >= ZYDIS_REGISTER_RAX) && (reg <= ZYDIS_REGISTER_R15))
{
return ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64;
}
if ((reg >= ZYDIS_REGISTER_EAX) && (reg <= ZYDIS_REGISTER_R15D))
{
return ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32;
}
if ((reg >= ZYDIS_REGISTER_AX) && (reg <= ZYDIS_REGISTER_R15W))
{
return ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16;
}
if ((reg >= ZYDIS_REGISTER_AL) && (reg <= ZYDIS_REGISTER_R15B))
{
return ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8;
}
if ((reg >= ZYDIS_REGISTER_ST0) && (reg <= ZYDIS_REGISTER_ST7))
{
return ZYDIS_REGISTERCLASS_FLOATING_POINT;
}
if ((reg >= ZYDIS_REGISTER_ZMM0) && (reg <= ZYDIS_REGISTER_ZMM31))
{
return ZYDIS_REGISTERCLASS_VECTOR512;
}
if ((reg >= ZYDIS_REGISTER_YMM0) && (reg <= ZYDIS_REGISTER_YMM31))
{
return ZYDIS_REGISTERCLASS_VECTOR256;
}
if ((reg >= ZYDIS_REGISTER_XMM0) && (reg <= ZYDIS_REGISTER_XMM31))
{
return ZYDIS_REGISTERCLASS_VECTOR128;
}
if ((reg >= ZYDIS_REGISTER_RFLAGS) && (reg <= ZYDIS_REGISTER_FLAGS))
{
return ZYDIS_REGISTERCLASS_FLAGS;
}
if ((reg >= ZYDIS_REGISTER_RIP) && (reg <= ZYDIS_REGISTER_IP))
{
return ZYDIS_REGISTERCLASS_IP;
}
if ((reg >= ZYDIS_REGISTER_ES) && (reg <= ZYDIS_REGISTER_GS))
{
return ZYDIS_REGISTERCLASS_SEGMENT;
}
if ((reg >= ZYDIS_REGISTER_GDTR) && (reg <= ZYDIS_REGISTER_TR))
{
return ZYDIS_REGISTERCLASS_TABLE;
}
if ((reg >= ZYDIS_REGISTER_TR0) && (reg <= ZYDIS_REGISTER_TR7))
{
return ZYDIS_REGISTERCLASS_TEST;
}
if ((reg >= ZYDIS_REGISTER_CR0) && (reg <= ZYDIS_REGISTER_CR15))
{
return ZYDIS_REGISTERCLASS_CONTROL;
}
if ((reg >= ZYDIS_REGISTER_DR0) && (reg <= ZYDIS_REGISTER_DR15))
{
return ZYDIS_REGISTERCLASS_DEBUG;
}
if ((reg >= ZYDIS_REGISTER_K0) && (reg <= ZYDIS_REGISTER_K7))
{
return ZYDIS_REGISTERCLASS_MASK;
}
if ((reg >= ZYDIS_REGISTER_BND0) && (reg <= ZYDIS_REGISTER_BNDSTATUS))
{
return ZYDIS_REGISTERCLASS_BOUNDS;
}
return ZYDIS_REGISTERCLASS_NONE;
}
ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg)
{
ZydisRegisterClass registerClass = ZydisRegisterGetClass(reg);
switch (registerClass)
{
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8:
return ZYDIS_REGISTERSIZE_8;
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16:
return ZYDIS_REGISTERSIZE_16;
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32:
return ZYDIS_REGISTERSIZE_32;
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64:
return ZYDIS_REGISTERSIZE_64;
case ZYDIS_REGISTERCLASS_FLOATING_POINT:
return ZYDIS_REGISTERSIZE_80;
case ZYDIS_REGISTERCLASS_MULTIMEDIA:
return ZYDIS_REGISTERSIZE_64;
case ZYDIS_REGISTERCLASS_VECTOR128:
return ZYDIS_REGISTERSIZE_128;
case ZYDIS_REGISTERCLASS_VECTOR256:
return ZYDIS_REGISTERSIZE_256;
case ZYDIS_REGISTERCLASS_VECTOR512:
return ZYDIS_REGISTERSIZE_512;
case ZYDIS_REGISTERCLASS_FLAGS:
return ZYDIS_REGISTERSIZE_DYNAMIC;
case ZYDIS_REGISTERCLASS_IP:
return ZYDIS_REGISTERSIZE_DYNAMIC;
case ZYDIS_REGISTERCLASS_SEGMENT:
return ZYDIS_REGISTERSIZE_16;
case ZYDIS_REGISTERCLASS_TABLE:
return ZYDIS_REGISTERSIZE_DYNAMIC;
case ZYDIS_REGISTERCLASS_TEST:
return ZYDIS_REGISTERSIZE_32;
case ZYDIS_REGISTERCLASS_CONTROL:
return ZYDIS_REGISTERSIZE_DYNAMIC;
case ZYDIS_REGISTERCLASS_DEBUG:
return ZYDIS_REGISTERSIZE_DYNAMIC;
case ZYDIS_REGISTERCLASS_MASK:
return ZYDIS_REGISTERSIZE_64;
case ZYDIS_REGISTERCLASS_BOUNDS:
return ZYDIS_REGISTERSIZE_128;
default:
break;
}
return ZYDIS_REGISTERSIZE_INVALID;
}
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -74,7 +74,6 @@ ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info
} }
break; break;
case ZYDIS_DISASSEMBLER_MODE_64BIT: case ZYDIS_DISASSEMBLER_MODE_64BIT:
assert((operand->size == 64)); // TODO: Remove after fuzzing
break; break;
default: default:
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;

Binary file not shown.

View File

@ -1,6 +1,6 @@
/*************************************************************************************************** /***************************************************************************************************
Zyan Disassembler Engine (Zydis) Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd Original Author : Florian Bernd
@ -35,32 +35,32 @@ uint64_t ZydisGetVersion()
return ZYDIS_VERSION; return ZYDIS_VERSION;
} }
bool ZydisIsFeatureEnabled(ZydisFeature feature) ZydisBool ZydisIsFeatureEnabled(ZydisFeature feature)
{ {
switch (feature) switch (feature)
{ {
case ZYDIS_FEATURE_IMPLICITLY_USED_REGISTERS: case ZYDIS_FEATURE_IMPLICITLY_USED_REGISTERS:
#ifdef ZYDIS_ENABLE_FEATURE_IMPLICITLY_USED_REGISTERS #ifdef ZYDIS_ENABLE_FEATURE_IMPLICITLY_USED_REGISTERS
return true; return ZYDIS_TRUE;
#else #else
return false; return ZYDIS_FALSE;
#endif #endif
case ZYDIS_FEATURE_AFFECTED_FLAGS: case ZYDIS_FEATURE_AFFECTED_FLAGS:
#ifdef ZYDIS_ENABLE_FEATURE_AFFECTED_FLAGS #ifdef ZYDIS_ENABLE_FEATURE_AFFECTED_FLAGS
return true; return ZYDIS_TRUE;
#else #else
return false; return ZYDIS_FALSE;
#endif #endif
case ZYDIS_FEATURE_CPUID: case ZYDIS_FEATURE_CPUID:
#ifdef ZYDIS_ENABLE_FEATURE_CPUID #ifdef ZYDIS_ENABLE_FEATURE_CPUID
return true; return ZYDIS_TRUE;
#else #else
return false; return ZYDIS_FALSE;
#endif #endif
default: default:
break; break;
} }
return false; return ZYDIS_FALSE;
} }
/* ============================================================================================== */ /* ============================================================================================== */