mirror of https://github.com/x64dbg/zydis
Bugfixes and Support for some more registers
Zydis: - Fixed operand-size of some instructions in 64-bit mode - Fixed operand decoding of the "movq MM, GPR" instruction - Added table-registers (GDRT, LDTR, IDTR, TR) - Added test-registers (TR0..TR7) - Added BNDCFG and BNDSTATUS registers - Added MXCR register InstructionEditor: - The code-generator now eliminates duplicate instruction-definitions to optimize the size of the generated tables - Fixed conflict indication for some operand type/encoding combinations - Added conflict indication for X86Flags
This commit is contained in:
parent
3f09ffca69
commit
58c73b2885
|
@ -142,11 +142,17 @@ begin
|
|||
VirtualTreeView.Expanded[N1] := true;
|
||||
|
||||
N1 := AddCategory(Root, 'Special Registers');
|
||||
AddRegisterRange(N1, regRFLAGS, regIP);
|
||||
AddRegisterRange(N1, regRFLAGS, regMXCSR);
|
||||
|
||||
N1 := AddCategory(Root, 'Segment Registers');
|
||||
AddRegisterRange(N1, regES, regFS);
|
||||
|
||||
N1 := AddCategory(Root, 'Table Registers');
|
||||
AddRegisterRange(N1, regGDTR, regTR);
|
||||
|
||||
N1 := AddCategory(Root, 'Test Registers');
|
||||
AddRegisterRange(N1, regTR0, regTR7);
|
||||
|
||||
N1 := AddCategory(Root, 'Control Registers');
|
||||
AddRegisterRange(N1, regCR0, regCR15);
|
||||
|
||||
|
@ -157,7 +163,7 @@ begin
|
|||
AddRegisterRange(N1, regK0, regK7);
|
||||
|
||||
N1 := AddCategory(Root, 'Bound Registers');
|
||||
AddRegisterRange(N1, regBND0, regBND3);
|
||||
AddRegisterRange(N1, regBND0, regBNDSTATUS);
|
||||
|
||||
VirtualTreeView.Expanded[Root] := true;
|
||||
finally
|
||||
|
|
|
@ -188,27 +188,12 @@
|
|||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
|
@ -560,12 +545,27 @@
|
|||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
|
||||
|
|
Binary file not shown.
|
@ -33,7 +33,7 @@ dxSkinOffice2013DarkGray=0
|
|||
dxSkinOffice2013LightGray=0
|
||||
dxSkinOffice2013White=0
|
||||
dxSkinPumpkin=0
|
||||
dxSkinSeven=1
|
||||
dxSkinSeven=0
|
||||
dxSkinSevenClassic=0
|
||||
dxSkinSharp=0
|
||||
dxSkinSharpPlus=0
|
||||
|
|
|
@ -172,8 +172,9 @@ procedure TCodeGenerator.CreateInstructionDefinitionList(Editor: TInstructionEdi
|
|||
var DefinitionList: TIndexedInstructionDefinitionList; var InstructionDefinitionCount: Integer;
|
||||
var InstructionDefinitionSize: Cardinal);
|
||||
var
|
||||
I: Integer;
|
||||
List: TList<TInstructionDefinition>;
|
||||
I, J: Integer;
|
||||
B: Boolean;
|
||||
Comparison: TComparison<TInstructionDefinition>;
|
||||
begin
|
||||
List := TList<TInstructionDefinition>.Create;
|
||||
|
@ -181,7 +182,19 @@ begin
|
|||
WorkStart('Indexing instruction definitions', 0, Editor.DefinitionCount * 2);
|
||||
for I := 0 to Editor.DefinitionCount - 1 do
|
||||
begin
|
||||
List.Add(Editor.Definitions[I]);
|
||||
B := false;
|
||||
for J := 0 to List.Count - 1 do
|
||||
begin
|
||||
if (Editor.Definitions[I].Equals(List[J], false, false)) then
|
||||
begin
|
||||
B := true;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
if (not B) then
|
||||
begin
|
||||
List.Add(Editor.Definitions[I]);
|
||||
end;
|
||||
Work(I + 1);
|
||||
end;
|
||||
Comparison :=
|
||||
|
|
|
@ -201,51 +201,55 @@ type
|
|||
TX86Register = (
|
||||
regNone,
|
||||
// General purpose registers 64-bit
|
||||
regRAX, regRCX, regRDX, regRBX, regRSP, regRBP, regRSI, regRDI,
|
||||
regR8, regR9, regR10, regR11, regR12, regR13, regR14, regR15,
|
||||
regRAX, regRCX, regRDX, regRBX, regRSP, regRBP, regRSI, regRDI,
|
||||
regR8, regR9, regR10, regR11, regR12, regR13, regR14, regR15,
|
||||
// General purpose registers 32-bit
|
||||
regEAX, regECX, regEDX, regEBX, regESP, regEBP, regESI, regEDI,
|
||||
regR8D, regr9D, regR10D, regR11D, regR12D, regR13D, regR14D, regR15D,
|
||||
regEAX, regECX, regEDX, regEBX, regESP, regEBP, regESI, regEDI,
|
||||
regR8D, regr9D, regR10D, regR11D, regR12D, regR13D, regR14D, regR15D,
|
||||
// General purpose registers 16-bit
|
||||
regAX, regCX, regDX, regBX, regSP, regBP, regSI, regDI,
|
||||
regR8W, regR9W, regR10W, regR11W, regR12W, regR13W, regR14W, regR15W,
|
||||
regAX, regCX, regDX, regBX, regSP, regBP, regSI, regDI,
|
||||
regR8W, regR9W, regR10W, regR11W, regR12W, regR13W, regR14W, regR15W,
|
||||
// General purpose registers 8-bit
|
||||
regAL, regCL, regDL, regBL, regAH, regCH, regDH, regBH,
|
||||
regAL, regCL, regDL, regBL, regAH, regCH, regDH, regBH,
|
||||
regSPL, regBPL, regSIL, regDIL,
|
||||
regR8B, regR9B, regR10B, regR11B, regR12B, regR13B, regR14B, regR15B,
|
||||
regR8B, regR9B, regR10B, regR11B, regR12B, regR13B, regR14B, regR15B,
|
||||
// Floating point legacy registers
|
||||
regST0, regST1, regST2, regST3, regST4, regST5, regST6, regST7,
|
||||
regST0, regST1, regST2, regST3, regST4, regST5, regST6, regST7,
|
||||
// Floating point multimedia registers
|
||||
regMM0, regMM1, regMM2, regMM3, regMM4, regMM5, regMM6, regMM7,
|
||||
regMM0, regMM1, regMM2, regMM3, regMM4, regMM5, regMM6, regMM7,
|
||||
// Floating point vector registers 512-bit
|
||||
regZMM0, regZMM1, regZMM2, regZMM3, regZMM4, regZMM5, regZMM6, regZMM7,
|
||||
regZMM8, regZMM9, regZMM10, regZMM11, regZMM12, regZMM13, regZMM14, regZMM15,
|
||||
regZMM16, regZMM17, regZMM18, regZMM19, regZMM20, regZMM21, regZMM22, regZMM23,
|
||||
regZMM24, regZMM25, regZMM26, regZMM27, regZMM28, regZMM29, regZMM30, regZMM31,
|
||||
regZMM0, regZMM1, regZMM2, regZMM3, regZMM4, regZMM5, regZMM6, regZMM7,
|
||||
regZMM8, regZMM9, regZMM10, regZMM11, regZMM12, regZMM13, regZMM14, regZMM15,
|
||||
regZMM16, regZMM17, regZMM18, regZMM19, regZMM20, regZMM21, regZMM22, regZMM23,
|
||||
regZMM24, regZMM25, regZMM26, regZMM27, regZMM28, regZMM29, regZMM30, regZMM31,
|
||||
// Floating point vector registers 256-bit
|
||||
regYMM0, regYMM1, regYMM2, regYMM3, regYMM4, regYMM5, regYMM6, regYMM7,
|
||||
regYMM8, regYMM9, regYMM10, regYMM11, regYMM12, regYMM13, regYMM14, regYMM15,
|
||||
regYMM16, regYMM17, regYMM18, regYMM19, regYMM20, regYMM21, regYMM22, regYMM23,
|
||||
regYMM24, regYMM25, regYMM26, regYMM27, regYMM28, regYMM29, regYMM30, regYMM31,
|
||||
regYMM0, regYMM1, regYMM2, regYMM3, regYMM4, regYMM5, regYMM6, regYMM7,
|
||||
regYMM8, regYMM9, regYMM10, regYMM11, regYMM12, regYMM13, regYMM14, regYMM15,
|
||||
regYMM16, regYMM17, regYMM18, regYMM19, regYMM20, regYMM21, regYMM22, regYMM23,
|
||||
regYMM24, regYMM25, regYMM26, regYMM27, regYMM28, regYMM29, regYMM30, regYMM31,
|
||||
// Floating point vector registers 128-bit
|
||||
regXMM0, regXMM1, regXMM2, regXMM3, regXMM4, regXMM5, regXMM6, regXMM7,
|
||||
regXMM8, regXMM9, regXMM10, regXMM11, regXMM12, regXMM13, regXMM14, regXMM15,
|
||||
regXMM16, regXMM17, regXMM18, regXMM19, regXMM20, regXMM21, regXMM22, regXMM23,
|
||||
regXMM24, regXMM25, regXMM26, regXMM27, regXMM28, regXMM29, regXMM30, regXMM31,
|
||||
regXMM0, regXMM1, regXMM2, regXMM3, regXMM4, regXMM5, regXMM6, regXMM7,
|
||||
regXMM8, regXMM9, regXMM10, regXMM11, regXMM12, regXMM13, regXMM14, regXMM15,
|
||||
regXMM16, regXMM17, regXMM18, regXMM19, regXMM20, regXMM21, regXMM22, regXMM23,
|
||||
regXMM24, regXMM25, regXMM26, regXMM27, regXMM28, regXMM29, regXMM30, regXMM31,
|
||||
// Special registers
|
||||
regRFLAGS, regEFLAGS, regFLAGS, regRIP, regEIP, regIP,
|
||||
regRFLAGS, regEFLAGS, regFLAGS, regRIP, regEIP, regIP, regMXCSR,
|
||||
// Segment registers
|
||||
regES, regCS, regSS, regDS, regGS, regFS,
|
||||
regES, regCS, regSS, regDS, regGS, regFS,
|
||||
// Table registers
|
||||
regGDTR, regLDTR, regIDTR, regTR,
|
||||
// Test registers
|
||||
regTR0, regTR1, regTR2, regTR3, regTR4, regTR5, regTR6, regTR7,
|
||||
// Control registers
|
||||
regCR0, regCR1, regCR2, regCR3, regCR4, regCR5, regCR6, regCR7,
|
||||
regCR8, regCR9, regCR10, regCR11, regCR12, regCR13, regCR14, regCR15,
|
||||
regCR0, regCR1, regCR2, regCR3, regCR4, regCR5, regCR6, regCR7,
|
||||
regCR8, regCR9, regCR10, regCR11, regCR12, regCR13, regCR14, regCR15,
|
||||
// Debug registers
|
||||
regDR0, regDR1, regDR2, regDR3, regDR4, regDR5, regDR6, regDR7,
|
||||
regDR8, regDR9, regDR10, regDR11, regDR12, regDR13, regDR14, regDR15,
|
||||
regDR0, regDR1, regDR2, regDR3, regDR4, regDR5, regDR6, regDR7,
|
||||
regDR8, regDR9, regDR10, regDR11, regDR12, regDR13, regDR14, regDR15,
|
||||
// Mask registers
|
||||
regK0, regK1, regK2, regK3, regK4, regK5, regK6, regK7,
|
||||
regK0, regK1, regK2, regK3, regK4, regK5, regK6, regK7,
|
||||
// Bounds registers
|
||||
regBND0, regBND1, regBND2, regBND3
|
||||
regBND0, regBND1, regBND2, regBND3, regBNDCFG, regBNDSTATUS
|
||||
);
|
||||
|
||||
TX86RegisterSet = set of TX86Register;
|
||||
|
@ -318,7 +322,9 @@ type
|
|||
procedure SetID(const Value: TX86FlagValue); inline;
|
||||
strict private
|
||||
procedure Changed; inline;
|
||||
private
|
||||
strict private
|
||||
function GetConflictState: Boolean;
|
||||
public // TODO: Make private again
|
||||
procedure LoadFromJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||
procedure SaveToJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||
protected
|
||||
|
@ -327,6 +333,8 @@ type
|
|||
constructor Create(Definition: TInstructionDefinition);
|
||||
public
|
||||
function Equals(const Value: TX86Flags): Boolean; reintroduce;
|
||||
public
|
||||
property HasConflicts: Boolean read GetConflictState;
|
||||
published
|
||||
{ FLAGS }
|
||||
property FlagCF: TX86FlagValue read FCF write SetCF default fvUnused;
|
||||
|
@ -532,7 +540,10 @@ type
|
|||
// This conflict is enforced by the user
|
||||
idcForcedConflict,
|
||||
// The instruction-operands configuration is invalid
|
||||
idcOperands
|
||||
idcOperands,
|
||||
// The FLAGS/EFLAGS/RFLAGS registers in the ImplicitRead or ImplicitWrite property do not
|
||||
// match the given X86Flags configuration
|
||||
idcX86Flags
|
||||
);
|
||||
TInstructionDefinitionConflicts = set of TInstructionDefinitionConflict;
|
||||
|
||||
|
@ -562,6 +573,7 @@ type
|
|||
ifAcceptsREP,
|
||||
ifAcceptsXACQUIRE,
|
||||
ifAcceptsXRELEASE,
|
||||
ifAcceptsBranchHints,
|
||||
ifAcceptsEVEXAAA,
|
||||
ifAcceptsEVEXZ,
|
||||
ifIsPrivileged,
|
||||
|
@ -616,7 +628,8 @@ type
|
|||
procedure EndUpdate; inline;
|
||||
public
|
||||
function Equals(const Value: TInstructionDefinition;
|
||||
const CheckComment: Boolean = false): Boolean; reintroduce;
|
||||
CheckComment: Boolean = false;
|
||||
CheckFilterRelatedAttributes: Boolean = true): Boolean; reintroduce;
|
||||
public
|
||||
procedure LoadFromJSON(JSON: PJSONVariantData);
|
||||
procedure SaveToJSON(JSON: PJSONVariantData);
|
||||
|
@ -1022,9 +1035,13 @@ const
|
|||
'xmm16', 'xmm17', 'xmm18', 'xmm19', 'xmm20', 'xmm21', 'xmm22', 'xmm23',
|
||||
'xmm24', 'xmm25', 'xmm26', 'xmm27', 'xmm28', 'xmm29', 'xmm30', 'xmm31',
|
||||
// Special registers
|
||||
'rflags', 'eflags', 'flags', 'rip', 'eip', 'ip',
|
||||
'rflags', 'eflags', 'flags', 'rip', 'eip', 'ip', 'mxcsr',
|
||||
// Segment registers
|
||||
'es', 'cs', 'ss', 'ds', 'gs', 'fs',
|
||||
// Table registers
|
||||
'gdtr', 'ldtr', 'idtr', 'tr',
|
||||
// Test registers
|
||||
'tr0', 'tr1', 'tr2', 'tr3', 'tr4', 'tr5', 'tr6', 'tr7',
|
||||
// Control registers
|
||||
'cr0', 'cr1', 'cr2', 'cr3', 'cr4', 'cr5', 'cr6', 'cr7',
|
||||
'cr8', 'cr9', 'cr10', 'cr11', 'cr12', 'cr13', 'cr14', 'cr15',
|
||||
|
@ -1034,7 +1051,7 @@ const
|
|||
// Mask registers
|
||||
'k0', 'k1', 'k2', 'k3', 'k4', 'k5', 'k6', 'k7',
|
||||
// Bounds registers
|
||||
'bnd0', 'bnd1', 'bnd2', 'bnd3'
|
||||
'bnd0', 'bnd1', 'bnd2', 'bnd3', 'bndcfg', 'bndstatus'
|
||||
);
|
||||
{$ENDREGION}
|
||||
|
||||
|
@ -1191,6 +1208,7 @@ const
|
|||
'accepts_rep',
|
||||
'accepts_xacquire',
|
||||
'accepts_xrelease',
|
||||
'accepts_branch_hints',
|
||||
'accepts_evex_aaa',
|
||||
'accepts_evex_z',
|
||||
'privileged',
|
||||
|
@ -1648,6 +1666,9 @@ constructor TX86Flags.Create(Definition: TInstructionDefinition);
|
|||
begin
|
||||
inherited Create;
|
||||
FDefinition := Definition;
|
||||
// NOTE: Some instructions clear all flags in the FLAGS/EFLAGS/RFLAGS register except some.
|
||||
// If you add a new flag field to this struct, you have to set it to fvReset for all these
|
||||
// instructions
|
||||
end;
|
||||
|
||||
function TX86Flags.Equals(const Value: TX86Flags): Boolean;
|
||||
|
@ -1658,6 +1679,58 @@ begin
|
|||
(Value.FAC = FAC) and (Value.FVIF = FVIF) and (Value.FVIP = FVIP) and (Value.FID = FID);
|
||||
end;
|
||||
|
||||
function TX86Flags.GetConflictState: Boolean;
|
||||
var
|
||||
F: array[0..14] of ^TX86FlagValue;
|
||||
I: Integer;
|
||||
RegsRead,
|
||||
RegsWrite: TX86RegisterSet;
|
||||
R: TX86Register;
|
||||
begin
|
||||
Exit(false); // TODO: Remove
|
||||
Result := false;
|
||||
F[ 0] := @FCF; F[ 1] := @FPF; F[ 2] := @FAF; F[ 3] := @FZF; F[ 4] := @FSF;
|
||||
F[ 5] := @FTF; F[ 6] := @FIF; F[ 7] := @FDF; F[ 8] := @FOF; F[ 9] := @FRF;
|
||||
F[10] := @FVM; F[11] := @FAC; F[12] := @FVIF; F[13] := @FVIP; F[14] := @FID;
|
||||
RegsRead := [];
|
||||
RegsWrite := [];
|
||||
for I := Low(F) to High(F) do
|
||||
begin
|
||||
if (F[I]^ in [fvTested]) then
|
||||
begin
|
||||
if (I < 9) then
|
||||
begin
|
||||
// These flags are in the FLAGS register
|
||||
Include(RegsRead, regFLAGS);
|
||||
end else
|
||||
begin
|
||||
// These flags are in the EFLAGS register
|
||||
Include(RegsRead, regEFLAGS);
|
||||
end;
|
||||
end;
|
||||
if (F[I]^ in [fvModified, fvReset, fvSet, fvUndefined, fvPriorValue]) then
|
||||
begin
|
||||
if (I < 9) then
|
||||
begin
|
||||
// These flags are in the FLAGS register
|
||||
Include(RegsWrite, regFLAGS);
|
||||
end else
|
||||
begin
|
||||
// These flags are in the EFLAGS register
|
||||
Include(RegsWrite, regEFLAGS);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
for R := regRFLAGS to regFLAGS do
|
||||
begin
|
||||
if ((R in RegsRead) xor (R in FDefinition.ImplicitRead.Registers)) or
|
||||
((R in RegsWrite) xor (R in FDefinition.ImplicitWrite.Registers)) then
|
||||
begin
|
||||
Exit(true);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TX86Flags.LoadFromJSON(JSON: PJSONVariantData; const FieldName: String);
|
||||
var
|
||||
C: PJSONVariantData;
|
||||
|
@ -1961,11 +2034,11 @@ begin
|
|||
optRel8:
|
||||
Result := not (FEncoding in [opeImm8]);
|
||||
optRel16:
|
||||
Result := not (FEncoding in [opeImm16]);
|
||||
Result := not (FEncoding in [opeImm8, opeImm16]);
|
||||
optRel32:
|
||||
Result := not (FEncoding in [opeImm32]);
|
||||
Result := not (FEncoding in [opeImm8, opeImm32]);
|
||||
optRel64:
|
||||
Result := not (FEncoding in [opeImm64]);
|
||||
Result := not (FEncoding in [opeImm8, opeImm32, opeImm64]);
|
||||
optPtr1616,
|
||||
optPtr1632,
|
||||
optPtr1664,
|
||||
|
@ -2379,36 +2452,7 @@ begin
|
|||
end;
|
||||
|
||||
procedure TInstructionOperands.Changed;
|
||||
{var
|
||||
A: array[0..3] of TInstructionOperand;
|
||||
I, J: Integer;
|
||||
begin
|
||||
FHasConflicts := false;
|
||||
|
||||
// Check for invalid operand order
|
||||
A[0] := FOperandA; A[1] := FOperandB; A[2] := FOperandC; A[3] := FOperandD;
|
||||
for I := High(A) downto Low(A) do
|
||||
begin
|
||||
if (A[I].OperandType <> otUnused) then
|
||||
begin
|
||||
for J := I downto Low(A) do
|
||||
begin
|
||||
if (A[J].OperandType = otUnused) then
|
||||
begin
|
||||
FHasConflicts := true;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if (FHasConflicts) then
|
||||
begin
|
||||
Break;
|
||||
end;
|
||||
end; }
|
||||
begin
|
||||
|
||||
// TODO: Determine Encoding
|
||||
|
||||
FDefinition.UpdateValues;
|
||||
end;
|
||||
|
||||
|
@ -2451,6 +2495,32 @@ var
|
|||
I: Integer;
|
||||
EncReg, EncRm, EncVVVV, EncAAA: Integer;
|
||||
begin
|
||||
{var
|
||||
A: array[0..3] of TInstructionOperand;
|
||||
I, J: Integer;
|
||||
begin
|
||||
FHasConflicts := false;
|
||||
|
||||
// Check for invalid operand order
|
||||
A[0] := FOperandA; A[1] := FOperandB; A[2] := FOperandC; A[3] := FOperandD;
|
||||
for I := High(A) downto Low(A) do
|
||||
begin
|
||||
if (A[I].OperandType <> otUnused) then
|
||||
begin
|
||||
for J := I downto Low(A) do
|
||||
begin
|
||||
if (A[J].OperandType = otUnused) then
|
||||
begin
|
||||
FHasConflicts := true;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if (FHasConflicts) then
|
||||
begin
|
||||
Break;
|
||||
end;
|
||||
end; }
|
||||
Result := false;
|
||||
for I := Low(FOperands) to High(FOperands) do
|
||||
begin
|
||||
|
@ -2638,14 +2708,14 @@ begin
|
|||
end;
|
||||
|
||||
function TInstructionDefinition.Equals(const Value: TInstructionDefinition;
|
||||
const CheckComment: Boolean): Boolean;
|
||||
CheckComment: Boolean; CheckFilterRelatedAttributes: Boolean): Boolean;
|
||||
begin
|
||||
Result :=
|
||||
(Value.FMnemonic = FMnemonic) and (Value.FEncoding = FEncoding) and
|
||||
(Value.FOpcodeMap = FOpcodeMap) and (Value.FOpcode = FOpcode) and
|
||||
(Value.FExtensions.Equals(FExtensions)) and (Value.FCPUID.Equals(FCPUID)) and
|
||||
(Value.FOperands.Equals(FOperands)) and (Value.FFlags = FFlags) and
|
||||
(Value.FEVEXCD8Scale = FEVEXCD8Scale) and
|
||||
(Value.FMnemonic = FMnemonic) and ((not CheckFilterRelatedAttributes) or
|
||||
((Value.FEncoding = FEncoding) and (Value.FOpcodeMap = FOpcodeMap) and
|
||||
(Value.FOpcode = FOpcode) and (Value.FExtensions.Equals(FExtensions)))) and
|
||||
(Value.FCPUID.Equals(FCPUID)) and (Value.FOperands.Equals(FOperands)) and
|
||||
(Value.FFlags = FFlags) and (Value.FEVEXCD8Scale = FEVEXCD8Scale) and
|
||||
(Value.FImplicitRead.Equals(FImplicitRead)) and
|
||||
(Value.FImplicitWrite.Equals(FImplicitWrite)) and (Value.FX86Flags.Equals(FX86Flags)) and
|
||||
((not CheckComment) or (Value.FComment = FComment));
|
||||
|
@ -2889,8 +2959,10 @@ begin
|
|||
begin
|
||||
Include(Conflicts, idcOperands);
|
||||
end;
|
||||
// TODO: Check for X86Flag conflicts
|
||||
// [ ] EFLAGS in ImplicitRead / ImplicitWrite required or forbidden
|
||||
if (FX86Flags.HasConflicts) then
|
||||
begin
|
||||
Include(Conflicts, idcX86Flags);
|
||||
end;
|
||||
// TODO: Check for more conflicts
|
||||
if (FConflicts <> Conflicts) then
|
||||
begin
|
||||
|
@ -3239,20 +3311,20 @@ begin
|
|||
FilterOrderDef[ 0] := TModrmModFilter;
|
||||
FilterOrderDef[ 1] := TModrmRegFilter;
|
||||
FilterOrderDef[ 2] := TModrmRmFilter;
|
||||
FilterOrderDef[ 3] := TRexWFilter;
|
||||
FilterOrderDef[ 4] := TOperandSizeFilter;
|
||||
FilterOrderDef[ 5] := TAddressSizeFilter;
|
||||
FilterOrderDef[ 6] := TMandatoryPrefixFilter;
|
||||
FilterOrderDef[ 7] := TModeFilter;
|
||||
FilterOrderDef[ 3] := TModeFilter;
|
||||
FilterOrderDef[ 4] := TRexWFilter;
|
||||
FilterOrderDef[ 5] := TOperandSizeFilter;
|
||||
FilterOrderDef[ 6] := TAddressSizeFilter;
|
||||
FilterOrderDef[ 7] := TMandatoryPrefixFilter;
|
||||
// Specialized filter order for XOP instruction encoding
|
||||
SetLength(FilterOrderXOP, 8);
|
||||
FilterOrderXOP[ 0] := TModrmModFilter;
|
||||
FilterOrderXOP[ 1] := TModrmRegFilter;
|
||||
FilterOrderXOP[ 2] := TModrmRmFilter;
|
||||
FilterOrderXOP[ 3] := TRexWFilter;
|
||||
FilterOrderXOP[ 4] := TOperandSizeFilter;
|
||||
FilterOrderXOP[ 5] := TAddressSizeFilter;
|
||||
FilterOrderXOP[ 6] := TModeFilter;
|
||||
FilterOrderXOP[ 3] := TModeFilter;
|
||||
FilterOrderXOP[ 4] := TRexWFilter;
|
||||
FilterOrderXOP[ 5] := TOperandSizeFilter;
|
||||
FilterOrderXOP[ 6] := TAddressSizeFilter;
|
||||
FilterOrderXOP[ 7] := TVexLFilter;
|
||||
// Specialized filter order for VEX instruction encoding
|
||||
SetLength(FilterOrderVEX, 9);
|
||||
|
@ -3260,10 +3332,10 @@ begin
|
|||
FilterOrderVEX[ 1] := TModrmModFilter;
|
||||
FilterOrderVEX[ 2] := TModrmRegFilter;
|
||||
FilterOrderVEX[ 3] := TModrmRmFilter;
|
||||
FilterOrderVEX[ 4] := TRexWFilter;
|
||||
FilterOrderVEX[ 5] := TOperandSizeFilter;
|
||||
FilterOrderVEX[ 6] := TAddressSizeFilter;
|
||||
FilterOrderVEX[ 7] := TModeFilter;
|
||||
FilterOrderVEX[ 4] := TModeFilter;
|
||||
FilterOrderVEX[ 5] := TRexWFilter;
|
||||
FilterOrderVEX[ 6] := TOperandSizeFilter;
|
||||
FilterOrderVEX[ 7] := TAddressSizeFilter;
|
||||
FilterOrderVEX[ 8] := TVexLFilter;
|
||||
// Specialized filter order for EVEX instruction encoding
|
||||
SetLength(FilterOrderEVEX, 11);
|
||||
|
@ -3271,10 +3343,10 @@ begin
|
|||
FilterOrderEVEX[ 1] := TModrmModFilter;
|
||||
FilterOrderEVEX[ 2] := TModrmRegFilter;
|
||||
FilterOrderEVEX[ 3] := TModrmRmFilter;
|
||||
FilterOrderEVEX[ 4] := TRexWFilter;
|
||||
FilterOrderEVEX[ 5] := TOperandSizeFilter;
|
||||
FilterOrderEVEX[ 6] := TAddressSizeFilter;
|
||||
FilterOrderEVEX[ 7] := TModeFilter;
|
||||
FilterOrderEVEX[ 4] := TModeFilter;
|
||||
FilterOrderEVEX[ 5] := TRexWFilter;
|
||||
FilterOrderEVEX[ 6] := TOperandSizeFilter;
|
||||
FilterOrderEVEX[ 7] := TAddressSizeFilter;
|
||||
FilterOrderEVEX[ 8] := TEvexBFilter;
|
||||
FilterOrderEVEX[ 9] := TVexLFilter;
|
||||
FilterOrderEVEX[10] := TEvexL2Filter;
|
||||
|
|
168970
assets/instructions.json
168970
assets/instructions.json
File diff suppressed because it is too large
Load Diff
|
@ -139,136 +139,144 @@ typedef uint32_t ZydisPrefixFlags;
|
|||
/**
|
||||
* @brief The instruction has the rex-prefix (0x40 - 0x4F).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REX 0x00000001
|
||||
#define ZYDIS_PREFIX_REX 0x00000001
|
||||
/**
|
||||
* @brief The instruction has the xop-prefix (0x8F).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_XOP 0x00000002
|
||||
#define ZYDIS_PREFIX_XOP 0x00000002
|
||||
/**
|
||||
* @brief The instruction has the vex-prefix (0xC4 or 0xC5).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_VEX 0x00000004
|
||||
#define ZYDIS_PREFIX_VEX 0x00000004
|
||||
/**
|
||||
* @brief The instruction has the evex-prefix (0x62).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_EVEX 0x00000008
|
||||
#define ZYDIS_PREFIX_EVEX 0x00000008
|
||||
/**
|
||||
* @brief The instruction has the lock-prefix (0x0F)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_LOCK 0x00000010
|
||||
#define ZYDIS_PREFIX_LOCK 0x00000010
|
||||
/**
|
||||
* @brief The instruction has the rep/repe/repz-prefix (0xF3)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REP 0x00000020
|
||||
#define ZYDIS_PREFIX_REP 0x00000020
|
||||
/**
|
||||
* @brief The instruction has the rep/repe/repz-prefix (0xF3)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REPE 0x00000020
|
||||
#define ZYDIS_PREFIX_REPE 0x00000020
|
||||
/**
|
||||
* @brief The instruction has the rep/repe/repz-prefix (0xF3)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REPZ 0x00000020
|
||||
#define ZYDIS_PREFIX_REPZ 0x00000020
|
||||
/**
|
||||
* @brief The instruction has the repne/repnz-prefix (0xF2)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REPNE 0x00000040
|
||||
#define ZYDIS_PREFIX_REPNE 0x00000040
|
||||
/**
|
||||
* @brief The instruction has the repne/repnz-prefix (0xF2)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_REPNZ 0x00000040
|
||||
#define ZYDIS_PREFIX_REPNZ 0x00000040
|
||||
/**
|
||||
* @brief The instruction has a segment-override prefix.
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_MASK 0x00001F80
|
||||
#define ZYDIS_PREFIX_SEGMENT_MASK 0x00001F80
|
||||
/**
|
||||
* @brief The instruction has the cs segment-override prefix (0x2E).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_CS 0x00000080
|
||||
#define ZYDIS_PREFIX_SEGMENT_CS 0x00000080
|
||||
/**
|
||||
* @brief The instruction has the ss segment-override prefix (0x36).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_SS 0x00000100
|
||||
#define ZYDIS_PREFIX_SEGMENT_SS 0x00000100
|
||||
/**
|
||||
* @brief The instruction has the ds segment-override prefix (0x3E).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_DS 0x00000200
|
||||
#define ZYDIS_PREFIX_SEGMENT_DS 0x00000200
|
||||
/**
|
||||
* @brief The instruction has the es segment-override prefix (0x26).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_ES 0x00000400
|
||||
#define ZYDIS_PREFIX_SEGMENT_ES 0x00000400
|
||||
/**
|
||||
* @brief The instruction has the fs segment-override prefix (0x64).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_FS 0x00000800
|
||||
#define ZYDIS_PREFIX_SEGMENT_FS 0x00000800
|
||||
/**
|
||||
* @brief The instruction has the gs segment-override prefix (0x65).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_SEGMENT_GS 0x00001000
|
||||
#define ZYDIS_PREFIX_SEGMENT_GS 0x00001000
|
||||
/**
|
||||
* @brief The instruction has the operand-size-override prefix (0x66).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_OPERANDSIZE 0x00002000
|
||||
#define ZYDIS_PREFIX_OPERANDSIZE 0x00002000
|
||||
/**
|
||||
* @brief The instruction has the address-size-override prefix (0x67).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ADDRESSSIZE 0x00004000
|
||||
#define ZYDIS_PREFIX_ADDRESSSIZE 0x00004000
|
||||
/**
|
||||
* @brief The instruction has the xacquire prefix (0xF2).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_XACQUIRE 0x00008000
|
||||
#define ZYDIS_PREFIX_XACQUIRE 0x00008000
|
||||
/**
|
||||
* @brief The instruction has the xrelease prefix (0xF3).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_XRELEASE 0x00010000
|
||||
#define ZYDIS_PREFIX_XRELEASE 0x00010000
|
||||
/**
|
||||
* @brief The instruction has the branch-not-taken hint (0x2E).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_BRANCH_NOT_TAKEN 0x00020000
|
||||
#define ZYDIS_PREFIX_BRANCH_NOT_TAKEN 0x00020000
|
||||
/**
|
||||
* @brief The instruction has the branch-taken hint (0x3E).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_BRANCH_TAKEN 0x00040000
|
||||
#define ZYDIS_PREFIX_BRANCH_TAKEN 0x00040000
|
||||
/**
|
||||
* @brief The instruction accepts the operand-size override prefix (0x66)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_OPERANDSIZE 0x00080000
|
||||
/**
|
||||
* @brief The instruction accepts the adress-size override prefix (0x67)
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE 0x00100000
|
||||
/**
|
||||
* @brief The instruction accepts the lock-prefix.
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_LOCK 0x00080000
|
||||
#define ZYDIS_PREFIX_ACCEPTS_LOCK 0x00200000
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REP 0x00100000
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REP 0x00400000
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPE 0x00100000
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPE 0x00400000
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPZ 0x00100000
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPZ 0x00400000
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPNE 0x00100000
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPNE 0x00400000
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPNZ 0x00100000
|
||||
#define ZYDIS_PREFIX_ACCEPTS_REPNZ 0x00400000
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the first prefix-group (0x0F, 0xF3, 0xF2).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP1 0x01000000
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP1 0x00800000
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the second prefix-group (0x2E, 0x36,
|
||||
* 0x3E, 0x26, 0x64, 0x65).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP2 0x02000000
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP2 0x01000000
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the third prefix-group (0x66).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP3 0x04000000
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP3 0x02000000
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the fourth prefix-group (0x67).
|
||||
*/
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP4 0x08000000
|
||||
#define ZYDIS_PREFIX_MULTIPLE_GRP4 0x04000000
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Instruction encoding */
|
||||
|
@ -537,6 +545,10 @@ typedef struct ZydisOperandInfo_
|
|||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief The adress size (16, 32 or 64 bit).
|
||||
*/
|
||||
uint8_t addressSize;
|
||||
/**
|
||||
* @brief The segment register.
|
||||
*/
|
||||
|
@ -649,7 +661,7 @@ typedef struct ZydisInstructionInfo_
|
|||
/**
|
||||
* @brief Prefix flags.
|
||||
*/
|
||||
ZydisPrefixFlags prefixFlags;
|
||||
ZydisPrefixFlags prefixes;
|
||||
/**
|
||||
* @brief The instruction-mnemonic.
|
||||
*/
|
||||
|
@ -682,14 +694,6 @@ typedef struct ZydisInstructionInfo_
|
|||
* @brief Detailed info for all instruction operands.
|
||||
*/
|
||||
ZydisOperandInfo operand[5];
|
||||
/**
|
||||
* @brief The operand mode (16, 32, 64).
|
||||
*/
|
||||
uint8_t operandMode;
|
||||
/**
|
||||
* @brief The address mode (16, 32, 64).
|
||||
*/
|
||||
uint8_t addressMode;
|
||||
/**
|
||||
* @brief Extended info for avx-related instructions.
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -106,10 +106,15 @@ enum ZydisRegisters
|
|||
ZYDIS_REGISTER_XMM28, ZYDIS_REGISTER_XMM29, ZYDIS_REGISTER_XMM30, ZYDIS_REGISTER_XMM31,
|
||||
// Special registers
|
||||
ZYDIS_REGISTER_RFLAGS, ZYDIS_REGISTER_EFLAGS, ZYDIS_REGISTER_FLAGS, ZYDIS_REGISTER_RIP,
|
||||
ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_IP,
|
||||
ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_IP, ZYDIS_REGISTER_MXCSR,
|
||||
// Segment registers
|
||||
ZYDIS_REGISTER_ES, ZYDIS_REGISTER_SS, ZYDIS_REGISTER_CS, ZYDIS_REGISTER_DS,
|
||||
ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS,
|
||||
// Table registers
|
||||
ZYDIS_REGISTER_GDTR, ZYDIS_REGISTER_LDTR, ZYDIS_REGISTER_IDTR, ZYDIS_REGISTER_TR,
|
||||
// Test registers
|
||||
ZYDIS_REGISTER_TR0, ZYDIS_REGISTER_TR1, ZYDIS_REGISTER_TR2, ZYDIS_REGISTER_TR3,
|
||||
ZYDIS_REGISTER_TR4, ZYDIS_REGISTER_TR5, ZYDIS_REGISTER_TR6, ZYDIS_REGISTER_TR7,
|
||||
// Control registers
|
||||
ZYDIS_REGISTER_CR0, ZYDIS_REGISTER_CR1, ZYDIS_REGISTER_CR2, ZYDIS_REGISTER_CR3,
|
||||
ZYDIS_REGISTER_CR4, ZYDIS_REGISTER_CR5, ZYDIS_REGISTER_CR6, ZYDIS_REGISTER_CR7,
|
||||
|
@ -124,7 +129,8 @@ enum ZydisRegisters
|
|||
ZYDIS_REGISTER_K0, ZYDIS_REGISTER_K1, ZYDIS_REGISTER_K2, ZYDIS_REGISTER_K3,
|
||||
ZYDIS_REGISTER_K4, ZYDIS_REGISTER_K5, ZYDIS_REGISTER_K6, ZYDIS_REGISTER_K7,
|
||||
// Bounds 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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
@ -139,7 +145,7 @@ typedef uint8_t ZydisRegisterClass;
|
|||
*/
|
||||
enum ZydisRegisterClasses
|
||||
{
|
||||
ZYDIS_REGISTERCLASS_INVALID,
|
||||
ZYDIS_REGISTERCLASS_NONE,
|
||||
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8,
|
||||
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16,
|
||||
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32,
|
||||
|
@ -152,6 +158,8 @@ enum ZydisRegisterClasses
|
|||
ZYDIS_REGISTERCLASS_FLAGS,
|
||||
ZYDIS_REGISTERCLASS_IP,
|
||||
ZYDIS_REGISTERCLASS_SEGMENT,
|
||||
ZYDIS_REGISTERCLASS_TABLE,
|
||||
ZYDIS_REGISTERCLASS_TEST,
|
||||
ZYDIS_REGISTERCLASS_CONTROL,
|
||||
ZYDIS_REGISTERCLASS_DEBUG,
|
||||
ZYDIS_REGISTERCLASS_MASK,
|
||||
|
@ -184,6 +192,46 @@ enum ZydisRegisterSizes
|
|||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* 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)
|
||||
|
||||
// TODO: Add macros for all register-classes
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Exported functions */
|
||||
/* ============================================================================================== */
|
||||
|
@ -198,15 +246,6 @@ enum ZydisRegisterSizes
|
|||
*/
|
||||
ZYDIS_EXPORT ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass, uint8_t id);
|
||||
|
||||
/**
|
||||
* @brief Returns the specified register string.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return The register string or @c NULL, if an invalid register was passed.
|
||||
*/
|
||||
ZYDIS_EXPORT const char* ZydisRegisterGetString(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Returns the register-class of the specified register.
|
||||
*
|
||||
|
@ -226,166 +265,13 @@ ZYDIS_EXPORT ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg);
|
|||
ZYDIS_EXPORT ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a general purpose register.
|
||||
* @brief Returns the specified register string.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a general purpose register.
|
||||
* @return The register string or @c NULL, if an invalid register was passed.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsGPR(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 8-bit general purpose register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 8-bit general purpose register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsGPR8(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 16-bit general purpose register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 16-bit general purpose register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsGPR16(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 32-bit general purpose register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 32-bit general purpose register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsGPR32(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 64-bit general purpose register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 64-bit general purpose register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsGPR64(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a legacy floating-point register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a legacy floating-point register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsFPRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a multi-media register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a multi-media register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsMMRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a vector register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsVR(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 128-bit vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 128-bit vector register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsVR128(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 256-bit vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 256-bit vector register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsVR256(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 512-bit vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 512-bit vector register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsVR512(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a flags register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a flags register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsFlagsRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is an instruction-pointer register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a instruction-pointer register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsIPRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a segment register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a segment register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsSegmentRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a control register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a control register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsCR(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a debug register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a debug register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsDR(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a mask register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a mask register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsMaskRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a bound register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a bound register.
|
||||
*/
|
||||
ZYDIS_EXPORT bool ZydisRegisterIsBoundsRegister(ZydisRegister reg);
|
||||
ZYDIS_EXPORT const char* ZydisRegisterGetString(ZydisRegister reg);
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
|
|
280
src/Decoder.c
280
src/Decoder.c
|
@ -444,58 +444,58 @@ static ZydisDecoderStatus ZydisCollectOptionalPrefixes(ZydisInstructionDecoder*
|
|||
switch (prefixByte)
|
||||
{
|
||||
case 0xF0:
|
||||
info->prefixFlags |= ZYDIS_PREFIX_LOCK;
|
||||
info->prefixes |= ZYDIS_PREFIX_LOCK;
|
||||
++groups[0];
|
||||
break;
|
||||
case 0xF2:
|
||||
// 0xF2 and 0xF3 are mutally exclusive. The one that comes later has precedence.
|
||||
info->prefixFlags |= ZYDIS_PREFIX_REPNE;
|
||||
info->prefixFlags &= ~ZYDIS_PREFIX_REP;
|
||||
info->prefixes |= ZYDIS_PREFIX_REPNE;
|
||||
info->prefixes &= ~ZYDIS_PREFIX_REP;
|
||||
++groups[0];
|
||||
break;
|
||||
case 0xF3:
|
||||
// 0xF2 and 0xF3 are mutally exclusive. The one that comes later has precedence.
|
||||
info->prefixFlags |= ZYDIS_PREFIX_REP;
|
||||
info->prefixFlags &= ~ZYDIS_PREFIX_REPNE;
|
||||
info->prefixes |= ZYDIS_PREFIX_REP;
|
||||
info->prefixes &= ~ZYDIS_PREFIX_REPNE;
|
||||
++groups[0];
|
||||
break;
|
||||
case 0x2E:
|
||||
info->prefixFlags |= ZYDIS_PREFIX_SEGMENT_CS;
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_CS;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x36:
|
||||
info->prefixFlags |= ZYDIS_PREFIX_SEGMENT_SS;
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_SS;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x3E:
|
||||
info->prefixFlags |= ZYDIS_PREFIX_SEGMENT_DS;
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_DS;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x26:
|
||||
info->prefixFlags |= ZYDIS_PREFIX_SEGMENT_ES;
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_ES;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x64:
|
||||
info->prefixFlags |= ZYDIS_PREFIX_SEGMENT_FS;
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_FS;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x65:
|
||||
info->prefixFlags |= ZYDIS_PREFIX_SEGMENT_GS;
|
||||
info->prefixes |= ZYDIS_PREFIX_SEGMENT_GS;
|
||||
++groups[1];
|
||||
break;
|
||||
case 0x66:
|
||||
info->prefixFlags |= ZYDIS_PREFIX_OPERANDSIZE;
|
||||
info->prefixes |= ZYDIS_PREFIX_OPERANDSIZE;
|
||||
++groups[2];
|
||||
break;
|
||||
case 0x67:
|
||||
info->prefixFlags |= ZYDIS_PREFIX_ADDRESSSIZE;
|
||||
info->prefixes |= ZYDIS_PREFIX_ADDRESSSIZE;
|
||||
++groups[3];
|
||||
break;
|
||||
default:
|
||||
if ((decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT) &&
|
||||
(prefixByte & 0xF0) == 0x40)
|
||||
{
|
||||
info->prefixFlags |= ZYDIS_PREFIX_REX;
|
||||
info->prefixes |= ZYDIS_PREFIX_REX;
|
||||
info->details.rex.data[0] = prefixByte;
|
||||
} else
|
||||
{
|
||||
|
@ -509,26 +509,26 @@ static ZydisDecoderStatus ZydisCollectOptionalPrefixes(ZydisInstructionDecoder*
|
|||
}
|
||||
} while (!done);
|
||||
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_REX)
|
||||
if (info->prefixes & ZYDIS_PREFIX_REX)
|
||||
{
|
||||
ZydisDecodeRexPrefix(info, info->details.rex.data[0]);
|
||||
}
|
||||
|
||||
if (groups[0] > 1)
|
||||
{
|
||||
info->prefixFlags |= ZYDIS_PREFIX_MULTIPLE_GRP1;
|
||||
info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP1;
|
||||
}
|
||||
if (groups[1] > 1)
|
||||
{
|
||||
info->prefixFlags |= ZYDIS_PREFIX_MULTIPLE_GRP2;
|
||||
info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP2;
|
||||
}
|
||||
if (groups[2] > 1)
|
||||
{
|
||||
info->prefixFlags |= ZYDIS_PREFIX_MULTIPLE_GRP3;
|
||||
info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP3;
|
||||
}
|
||||
if (groups[3] > 1)
|
||||
{
|
||||
info->prefixFlags |= ZYDIS_PREFIX_MULTIPLE_GRP4;
|
||||
info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP4;
|
||||
}
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
|
@ -661,7 +661,7 @@ static ZydisDecoderStatus ZydisDecodeOperandRegister(ZydisInstructionInfo* info,
|
|||
operand->type = ZYDIS_OPERAND_TYPE_REGISTER;
|
||||
if (registerClass == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8)
|
||||
{
|
||||
if ((info->prefixFlags & ZYDIS_PREFIX_REX) && (registerId >= 4))
|
||||
if ((info->prefixes & ZYDIS_PREFIX_REX) && (registerId >= 4))
|
||||
{
|
||||
operand->reg = ZYDIS_REGISTER_SPL + (registerId - 4);
|
||||
} else
|
||||
|
@ -707,7 +707,22 @@ static ZydisDecoderStatus ZydisDecodeOperandModrmRm(ZydisInstructionDecoder* dec
|
|||
}
|
||||
operand->type = ZYDIS_OPERAND_TYPE_MEMORY;
|
||||
uint8_t displacementSize = 0;
|
||||
switch (info->addressMode)
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE;
|
||||
switch (decoder->disassemblerMode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 16;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 16 : 32;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 64;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
switch (operand->mem.addressSize)
|
||||
{
|
||||
case 16:
|
||||
{
|
||||
|
@ -965,7 +980,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
}
|
||||
|
||||
// Register operands
|
||||
ZydisRegisterClass registerClass = ZYDIS_REGISTERCLASS_INVALID;
|
||||
ZydisRegisterClass registerClass = ZYDIS_REGISTERCLASS_NONE;
|
||||
switch (type)
|
||||
{
|
||||
case ZYDIS_SEM_OPERAND_TYPE_GPR8:
|
||||
|
@ -1027,7 +1042,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (registerClass != ZYDIS_REGISTERCLASS_INVALID)
|
||||
if (registerClass != ZYDIS_REGISTERCLASS_NONE)
|
||||
{
|
||||
switch (encoding)
|
||||
{
|
||||
|
@ -1119,15 +1134,15 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
{
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM:
|
||||
operand->size = 0;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM8:
|
||||
operand->size = 8;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM16:
|
||||
operand->size = 16;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM32_BCST2:
|
||||
info->avx.broadcast = ZYDIS_AVX_BCSTMODE_2;
|
||||
|
@ -1148,7 +1163,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
}
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM32:
|
||||
operand->size = 32;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM64_BCST2:
|
||||
info->avx.broadcast = ZYDIS_AVX_BCSTMODE_2;
|
||||
|
@ -1169,73 +1184,73 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
}
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM64:
|
||||
operand->size = 64;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM80:
|
||||
ZYDIS_ASSERT(evexCD8Scale == 0);
|
||||
operand->size = 80;
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID);
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE);
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM112:
|
||||
ZYDIS_ASSERT(evexCD8Scale == 0);
|
||||
operand->size = 112;
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID);
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE);
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM128:
|
||||
operand->size = 128;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM224:
|
||||
ZYDIS_ASSERT(evexCD8Scale == 0);
|
||||
operand->size = 224;
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID);
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE);
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM256:
|
||||
operand->size = 256;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM512:
|
||||
operand->size = 512;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_M1616:
|
||||
ZYDIS_ASSERT(evexCD8Scale == 0);
|
||||
operand->size = 32;
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID);
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE);
|
||||
case ZYDIS_SEM_OPERAND_TYPE_M1632:
|
||||
ZYDIS_ASSERT(evexCD8Scale == 0);
|
||||
operand->size = 48;
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID);
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE);
|
||||
case ZYDIS_SEM_OPERAND_TYPE_M1664:
|
||||
ZYDIS_ASSERT(evexCD8Scale == 0);
|
||||
operand->size = 80;
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID);
|
||||
return ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE);
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM32_VSIBX:
|
||||
vsibBaseRegister = ZYDIS_REGISTER_XMM0;
|
||||
operand->size = 32;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM32_VSIBY:
|
||||
vsibBaseRegister = ZYDIS_REGISTER_YMM0;
|
||||
operand->size = 32;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM32_VSIBZ:
|
||||
vsibBaseRegister = ZYDIS_REGISTER_ZMM0;
|
||||
operand->size = 32;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM64_VSIBX:
|
||||
vsibBaseRegister = ZYDIS_REGISTER_XMM0;
|
||||
operand->size = 64;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM64_VSIBY:
|
||||
vsibBaseRegister = ZYDIS_REGISTER_YMM0;
|
||||
operand->size = 64;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
case ZYDIS_SEM_OPERAND_TYPE_MEM64_VSIBZ:
|
||||
vsibBaseRegister = ZYDIS_REGISTER_ZMM0;
|
||||
operand->size = 64;
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
|
||||
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_NONE));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1255,7 +1270,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB;
|
||||
return ZYDIS_STATUS_DECODER_INVALID_VSIB;
|
||||
}
|
||||
switch (info->addressMode)
|
||||
switch (operand->mem.addressSize)
|
||||
{
|
||||
case 16:
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB;
|
||||
|
@ -1450,8 +1465,23 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
|
|||
}
|
||||
if (srcidx || dstidx)
|
||||
{
|
||||
registerClass = ZYDIS_REGISTERCLASS_INVALID;
|
||||
switch (info->addressMode)
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE;
|
||||
switch (decoder->disassemblerMode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 16;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 16 : 32;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 64;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
registerClass = ZYDIS_REGISTERCLASS_NONE;
|
||||
switch (operand->mem.addressSize)
|
||||
{
|
||||
case 16:
|
||||
registerClass = ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16;
|
||||
|
@ -1528,27 +1558,27 @@ static ZydisDecoderStatus ZydisDecodeOperands(ZydisInstructionDecoder* decoder,
|
|||
// Adjust segment register for memory operands
|
||||
if (info->operand[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_SEGMENT_CS)
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_CS)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_CS;
|
||||
} else
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_SEGMENT_SS)
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_SS)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_SS;
|
||||
} else
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_SEGMENT_DS)
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_DS)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_DS;
|
||||
} else
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_SEGMENT_ES)
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_ES)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_ES;
|
||||
} else
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_SEGMENT_FS)
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_FS)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_FS;
|
||||
} else
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_SEGMENT_GS)
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_GS)
|
||||
{
|
||||
info->operand[i].mem.segment = ZYDIS_REGISTER_GS;
|
||||
} else
|
||||
|
@ -1578,46 +1608,6 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info)
|
|||
ZYDIS_ASSERT(info);
|
||||
|
||||
// TODO: Encode all these things in the instruction definition
|
||||
|
||||
// Adjust operand-mode
|
||||
/*if (info->mode == ZYDIS_DISASSEMBLER_MODE_64BIT)
|
||||
{
|
||||
if ((info->flags & ZYDIS_INSTRUCTION_RELATIVE) &&
|
||||
(info->operand[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
|
||||
{
|
||||
info->operandMode = 64;
|
||||
}
|
||||
if (info->opcodeMap == ZYDIS_OPCODE_MAP_DEFAULT)
|
||||
{
|
||||
if ((info->opcode == 0xC2) || (info->opcode == 0xC3) || (info->opcode == 0xC4) ||
|
||||
(info->opcode == 0xC5) || (info->opcode == 0xEA) ||
|
||||
(info->opcode == 0x50) || (info->opcode == 0x51) || (info->opcode == 0x52) ||
|
||||
(info->opcode == 0x53) || (info->opcode == 0x54) || (info->opcode == 0x55) ||
|
||||
(info->opcode == 0x56) || (info->opcode == 0x57) || (info->opcode == 0x58) ||
|
||||
(info->opcode == 0x59) || (info->opcode == 0x5A) || (info->opcode == 0x5B) ||
|
||||
(info->opcode == 0x5C) || (info->opcode == 0x5D) || (info->opcode == 0x5E) ||
|
||||
(info->opcode == 0x5F) || (info->opcode == 0x68) || (info->opcode == 0x6A) ||
|
||||
(info->opcode == 0x8F) || (info->opcode == 0x9C) || (info->opcode == 0x9D) ||
|
||||
(info->opcode == 0xC9))
|
||||
{
|
||||
info->operandMode = 64;
|
||||
} else if (info->opcode == 0xFF)
|
||||
{
|
||||
if ((info->details.modrm.reg == 0x02) || (info->details.modrm.reg == 0x04) ||
|
||||
(info->details.modrm.reg == 0x06))
|
||||
{
|
||||
info->operandMode = 64;
|
||||
}
|
||||
}
|
||||
} else if (info->opcodeMap == ZYDIS_OPCODE_MAP_0F)
|
||||
{
|
||||
if ((info->opcode == 0xA0) || (info->opcode == 0xA1) || (info->opcode == 0xA8) ||
|
||||
(info->opcode == 0xA9))
|
||||
{
|
||||
info->operandMode = 64;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// Adjust prefix flags
|
||||
switch (info->mnemonic)
|
||||
|
@ -1643,7 +1633,7 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info)
|
|||
case ZYDIS_MNEMONIC_XCHG:
|
||||
if (info->operand[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
info->prefixFlags |= ZYDIS_PREFIX_ACCEPTS_LOCK;
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_LOCK;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_MOVSB:
|
||||
|
@ -1672,7 +1662,7 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info)
|
|||
case ZYDIS_MNEMONIC_OUTSB:
|
||||
case ZYDIS_MNEMONIC_OUTSW:
|
||||
case ZYDIS_MNEMONIC_OUTSD:
|
||||
info->prefixFlags |= ZYDIS_PREFIX_ACCEPTS_REP | ZYDIS_PREFIX_ACCEPTS_REPNE;
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_REP | ZYDIS_PREFIX_ACCEPTS_REPNE;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_JO:
|
||||
case ZYDIS_MNEMONIC_JNO:
|
||||
|
@ -1693,44 +1683,44 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info)
|
|||
case ZYDIS_MNEMONIC_JCXZ:
|
||||
case ZYDIS_MNEMONIC_JECXZ:
|
||||
case ZYDIS_MNEMONIC_JRCXZ:
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_SEGMENT_CS)
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_CS)
|
||||
{
|
||||
info->prefixFlags &= ~ZYDIS_PREFIX_SEGMENT_CS;
|
||||
info->prefixFlags |= ZYDIS_PREFIX_BRANCH_NOT_TAKEN;
|
||||
info->prefixes &= ~ZYDIS_PREFIX_SEGMENT_CS;
|
||||
info->prefixes |= ZYDIS_PREFIX_BRANCH_NOT_TAKEN;
|
||||
} else
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_SEGMENT_DS)
|
||||
if (info->prefixes & ZYDIS_PREFIX_SEGMENT_DS)
|
||||
{
|
||||
info->prefixFlags &= ~ZYDIS_PREFIX_SEGMENT_DS;
|
||||
info->prefixFlags |= ZYDIS_PREFIX_BRANCH_TAKEN;
|
||||
info->prefixes &= ~ZYDIS_PREFIX_SEGMENT_DS;
|
||||
info->prefixes |= ZYDIS_PREFIX_BRANCH_TAKEN;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((info->prefixFlags & ZYDIS_PREFIX_ACCEPTS_LOCK) &&
|
||||
((info->prefixFlags & ZYDIS_PREFIX_REP) || (info->prefixFlags & ZYDIS_PREFIX_REPNE)))
|
||||
if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_LOCK) &&
|
||||
((info->prefixes & ZYDIS_PREFIX_REP) || (info->prefixes & ZYDIS_PREFIX_REPNE)))
|
||||
{
|
||||
if (info->mnemonic != ZYDIS_MNEMONIC_CMPXCHG16B)
|
||||
{
|
||||
if ((info->prefixFlags & ZYDIS_PREFIX_LOCK) || (info->mnemonic == ZYDIS_MNEMONIC_XCHG))
|
||||
if ((info->prefixes & ZYDIS_PREFIX_LOCK) || (info->mnemonic == ZYDIS_MNEMONIC_XCHG))
|
||||
{
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_REPNE)
|
||||
if (info->prefixes & ZYDIS_PREFIX_REPNE)
|
||||
{
|
||||
info->prefixFlags &= ~ZYDIS_PREFIX_REPNE;
|
||||
info->prefixFlags |= ZYDIS_PREFIX_XACQUIRE;
|
||||
info->prefixes &= ~ZYDIS_PREFIX_REPNE;
|
||||
info->prefixes |= ZYDIS_PREFIX_XACQUIRE;
|
||||
}
|
||||
{
|
||||
info->prefixFlags &= ~ZYDIS_PREFIX_REP;
|
||||
info->prefixFlags |= ZYDIS_PREFIX_XRELEASE;
|
||||
info->prefixes &= ~ZYDIS_PREFIX_REP;
|
||||
info->prefixes |= ZYDIS_PREFIX_XRELEASE;
|
||||
}
|
||||
} else
|
||||
if ((info->mnemonic == ZYDIS_MNEMONIC_MOV) && ((info->opcode == 0x88) ||
|
||||
(info->opcode == 0x89) || (info->opcode == 0xC6) || (info->opcode == 0xC7)))
|
||||
{
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_REP)
|
||||
if (info->prefixes & ZYDIS_PREFIX_REP)
|
||||
{
|
||||
info->prefixFlags &= ~ZYDIS_PREFIX_REP;
|
||||
info->prefixFlags |= ZYDIS_PREFIX_XRELEASE;
|
||||
info->prefixes &= ~ZYDIS_PREFIX_REP;
|
||||
info->prefixes |= ZYDIS_PREFIX_XRELEASE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1784,7 +1774,7 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
|
|||
if ((decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT) ||
|
||||
((nextInput & 0xF0) >= 0xC0))
|
||||
{
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_REX)
|
||||
if (info->prefixes & ZYDIS_PREFIX_REX)
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX;
|
||||
return ZYDIS_STATUS_DECODER_ILLEGAL_REX;
|
||||
|
@ -1819,7 +1809,7 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
|
|||
case 0xC5:
|
||||
// Decode vex-prefix
|
||||
info->encoding = ZYDIS_INSTRUCTION_ENCODING_VEX;
|
||||
info->prefixFlags |= ZYDIS_PREFIX_VEX;
|
||||
info->prefixes |= ZYDIS_PREFIX_VEX;
|
||||
if (!ZydisDecodeVexPrefix(info->opcode, prefixBytes[0], prefixBytes[1],
|
||||
info))
|
||||
{
|
||||
|
@ -1831,7 +1821,7 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
|
|||
case 0x62:
|
||||
// Decode evex-prefix
|
||||
info->encoding = ZYDIS_INSTRUCTION_ENCODING_EVEX;
|
||||
info->prefixFlags |= ZYDIS_PREFIX_EVEX;
|
||||
info->prefixes |= ZYDIS_PREFIX_EVEX;
|
||||
if (!ZydisDecodeEvexPrefix(prefixBytes[0], prefixBytes[1], prefixBytes[2],
|
||||
info))
|
||||
{
|
||||
|
@ -1852,7 +1842,7 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
|
|||
ZYDIS_CHECK(ZydisInputPeek(decoder, info, &nextInput));
|
||||
if (((nextInput >> 0) & 0x1F) >= 8)
|
||||
{
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_REX)
|
||||
if (info->prefixes & ZYDIS_PREFIX_REX)
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX;
|
||||
return ZYDIS_STATUS_DECODER_ILLEGAL_REX;
|
||||
|
@ -1864,7 +1854,7 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
|
|||
ZYDIS_CHECK(ZydisInputNext(decoder, info, &prefixBytes[1]));
|
||||
// Decode xop-prefix
|
||||
info->encoding = ZYDIS_INSTRUCTION_ENCODING_XOP;
|
||||
info->prefixFlags |= ZYDIS_PREFIX_XOP;
|
||||
info->prefixes |= ZYDIS_PREFIX_XOP;
|
||||
if (!ZydisDecodeXopPrefix(prefixBytes[0], prefixBytes[1], info))
|
||||
{
|
||||
info->flags |= ZYDIS_INSTRUCTION_ERROR_MALFORMED_XOP;
|
||||
|
@ -1980,18 +1970,18 @@ static ZydisDecoderStatus ZydisNodeHandlerMandatoryPrefix(ZydisInstructionInfo*
|
|||
ZYDIS_ASSERT(info);
|
||||
ZYDIS_ASSERT(index);
|
||||
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_REP)
|
||||
if (info->prefixes & ZYDIS_PREFIX_REP)
|
||||
{
|
||||
*index = 2;
|
||||
info->prefixFlags &= ~ ZYDIS_PREFIX_REP; // TODO: don't remove but mark as mandatory
|
||||
} else if (info->prefixFlags & ZYDIS_PREFIX_REPNE)
|
||||
info->prefixes &= ~ ZYDIS_PREFIX_REP; // TODO: don't remove but mark as mandatory
|
||||
} else if (info->prefixes & ZYDIS_PREFIX_REPNE)
|
||||
{
|
||||
*index = 3;
|
||||
info->prefixFlags &= ~ ZYDIS_PREFIX_REPNE; // TODO: don't remove but mark as mandatory
|
||||
} else if (info->prefixFlags & ZYDIS_PREFIX_OPERANDSIZE)
|
||||
info->prefixes &= ~ ZYDIS_PREFIX_REPNE; // TODO: don't remove but mark as mandatory
|
||||
} else if (info->prefixes & ZYDIS_PREFIX_OPERANDSIZE)
|
||||
{
|
||||
*index = 1;
|
||||
info->prefixFlags &= ~ ZYDIS_PREFIX_OPERANDSIZE; // TODO: don't remove but mark as mandatory
|
||||
info->prefixes &= ~ ZYDIS_PREFIX_OPERANDSIZE; // TODO: don't remove but mark as mandatory
|
||||
}
|
||||
return ZYDIS_STATUS_DECODER_SUCCESS;
|
||||
}
|
||||
|
@ -2054,14 +2044,16 @@ static ZydisDecoderStatus ZydisNodeHandlerOperandSize(ZydisInstructionDecoder* d
|
|||
ZYDIS_ASSERT(info);
|
||||
ZYDIS_ASSERT(index);
|
||||
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_OPERANDSIZE;
|
||||
|
||||
switch (decoder->disassemblerMode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
*index = (info->prefixFlags & ZYDIS_PREFIX_OPERANDSIZE) ? 1 : 0;
|
||||
*index = (info->prefixes & ZYDIS_PREFIX_OPERANDSIZE) ? 1 : 0;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
*index = (info->prefixFlags & ZYDIS_PREFIX_OPERANDSIZE) ? 0 : 1;
|
||||
*index = (info->prefixes & ZYDIS_PREFIX_OPERANDSIZE) ? 0 : 1;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
|
@ -2076,16 +2068,18 @@ static ZydisDecoderStatus ZydisNodeHandlerAddressSize(ZydisInstructionDecoder* d
|
|||
ZYDIS_ASSERT(info);
|
||||
ZYDIS_ASSERT(index);
|
||||
|
||||
info->prefixes |= ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE;
|
||||
|
||||
switch (decoder->disassemblerMode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
*index = (info->prefixFlags & ZYDIS_PREFIX_ADDRESSSIZE) ? 1 : 0;
|
||||
*index = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 1 : 0;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
*index = (info->prefixFlags & ZYDIS_PREFIX_ADDRESSSIZE) ? 0 : 1;
|
||||
*index = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 0 : 1;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
*index = (info->prefixFlags & ZYDIS_PREFIX_ADDRESSSIZE) ? 1 : 2;
|
||||
*index = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 1 : 2;
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
|
@ -2227,36 +2221,6 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
|
|||
//ZYDIS_ASSERT(definition); // TODO: Pointer?
|
||||
info->mnemonic = definition.mnemonic;
|
||||
|
||||
// TODO: Check for (un)accepted prefixes
|
||||
|
||||
// Determine effective operand- and address-mode
|
||||
switch (decoder->disassemblerMode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
info->addressMode = (info->prefixFlags & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 16;
|
||||
info->operandMode = (info->prefixFlags & ZYDIS_PREFIX_OPERANDSIZE) ? 32 : 16;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
info->addressMode = (info->prefixFlags & ZYDIS_PREFIX_ADDRESSSIZE) ? 16 : 32;
|
||||
info->operandMode = (info->prefixFlags & ZYDIS_PREFIX_OPERANDSIZE) ? 16 : 32;
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
info->addressMode = (info->prefixFlags & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 64;
|
||||
if (info->details.internal.w)
|
||||
{
|
||||
info->operandMode = 64;
|
||||
} else if ((info->prefixFlags & ZYDIS_PREFIX_OPERANDSIZE))
|
||||
{
|
||||
info->operandMode = 16;
|
||||
} else
|
||||
{
|
||||
info->operandMode = 32;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
|
||||
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW)
|
||||
{
|
||||
// Save input-buffer state and decode dummy operands
|
||||
|
@ -2529,8 +2493,6 @@ ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder,
|
|||
userData[5] = info->userData;
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->mode = decoder->disassemblerMode;
|
||||
info->operandMode = (decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_16BIT) ? 16 : 32;
|
||||
info->addressMode = decoder->disassemblerMode;
|
||||
info->instrAddress = decoder->instructionPointer;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
|
|
|
@ -196,22 +196,27 @@ static ZydisStatus ZydisBufferAppendAbsoluteAddress(const ZydisInstructionFormat
|
|||
buffer, bufferLen, offset, false, "%s-0x%02llX", symbol, -symbolOffset);
|
||||
}
|
||||
}
|
||||
if (info->operandMode == 16)
|
||||
{
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%04X", address);
|
||||
}
|
||||
switch (info->mode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%04X", address);
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%08lX", address);
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%016llX", address);
|
||||
switch (operand->size)
|
||||
{
|
||||
case 16:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%04X", address);
|
||||
case 32:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%08lX", address);
|
||||
case 64:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%016llX", address);
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -335,9 +340,9 @@ static ZydisStatus ZydisBufferAppendOperandIntelMemory(const ZydisInstructionFor
|
|||
{
|
||||
if ((formatter->flags & ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT) ||
|
||||
(((operand->mem.segment != ZYDIS_REGISTER_DS) ||
|
||||
(info->prefixFlags & ZYDIS_PREFIX_SEGMENT_DS)) &&
|
||||
(info->prefixes & ZYDIS_PREFIX_SEGMENT_DS)) &&
|
||||
((operand->mem.segment != ZYDIS_REGISTER_SS) ||
|
||||
(info->prefixFlags & ZYDIS_PREFIX_SEGMENT_SS))))
|
||||
(info->prefixes & ZYDIS_PREFIX_SEGMENT_SS))))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "%s:",
|
||||
|
@ -441,27 +446,27 @@ static ZydisStatus ZydisFormatterFormatInstructionIntel(ZydisInstructionFormatte
|
|||
{
|
||||
size_t offset = 0;
|
||||
|
||||
if ((info->prefixFlags & ZYDIS_PREFIX_ACCEPTS_REPNE) &&
|
||||
(info->prefixFlags & ZYDIS_PREFIX_REPNE))
|
||||
if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_REPNE) &&
|
||||
(info->prefixes & ZYDIS_PREFIX_REPNE))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "repne "));
|
||||
}
|
||||
if ((info->prefixFlags & ZYDIS_PREFIX_ACCEPTS_REP) && (info->prefixFlags & ZYDIS_PREFIX_REP))
|
||||
if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_REP) && (info->prefixes & ZYDIS_PREFIX_REP))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "rep "));
|
||||
}
|
||||
if ((info->prefixFlags & ZYDIS_PREFIX_ACCEPTS_LOCK) && (info->prefixFlags & ZYDIS_PREFIX_LOCK))
|
||||
if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_LOCK) && (info->prefixes & ZYDIS_PREFIX_LOCK))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "lock "));
|
||||
}
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_XACQUIRE)
|
||||
if (info->prefixes & ZYDIS_PREFIX_XACQUIRE)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "xacquire "));
|
||||
} else if (info->prefixFlags & ZYDIS_PREFIX_XRELEASE)
|
||||
} else if (info->prefixes & ZYDIS_PREFIX_XRELEASE)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "xrelease "));
|
||||
|
|
147
src/Register.c
147
src/Register.c
|
@ -90,11 +90,16 @@ const char* registerStrings[] =
|
|||
"xmm24", "xmm25", "xmm26", "xmm27",
|
||||
"xmm28", "xmm29", "xmm30", "xmm31",
|
||||
// Special registers
|
||||
"rflags", "eflags", "flags", "rip",
|
||||
"eip", "ip",
|
||||
"rflags", "eflags", "flags", "rip",
|
||||
"eip", "ip", "mxcsr",
|
||||
// Segment registers
|
||||
"es", "ss", "cs", "ds",
|
||||
"fs", "gs",
|
||||
// Table registers
|
||||
"gdtr", "ldtr", "idtr", "tr",
|
||||
// Test registers
|
||||
"tr0", "tr1", "tr2", "tr3",
|
||||
"tr4", "tr5", "tr6", "tr7",
|
||||
// Control registers
|
||||
"cr0", "cr1", "cr2", "cr3",
|
||||
"cr4", "cr5", "cr6", "cr7",
|
||||
|
@ -109,7 +114,8 @@ const char* registerStrings[] =
|
|||
"k0", "k1", "k2", "k3",
|
||||
"k4", "k5", "k6", "k7",
|
||||
// Bounds registers
|
||||
"bnd0", "bnd1", "bnd2", "bnd3"
|
||||
"bnd0", "bnd1", "bnd2", "bnd3",
|
||||
"bndcfg", "bndstatus"
|
||||
};
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
@ -170,6 +176,11 @@ ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass, uint8_t id)
|
|||
{
|
||||
return ZYDIS_REGISTER_ES + id;
|
||||
}
|
||||
case ZYDIS_REGISTERCLASS_TEST:
|
||||
if (id <= 7)
|
||||
{
|
||||
return ZYDIS_REGISTER_TR0 + id;
|
||||
}
|
||||
case ZYDIS_REGISTERCLASS_CONTROL:
|
||||
if (id <= 15)
|
||||
{
|
||||
|
@ -190,11 +201,8 @@ ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass, uint8_t id)
|
|||
{
|
||||
return ZYDIS_REGISTER_BND0 + id;
|
||||
}
|
||||
case ZYDIS_REGISTERCLASS_FLAGS:
|
||||
case ZYDIS_REGISTERCLASS_IP:
|
||||
// These registers are unique
|
||||
break;
|
||||
default:
|
||||
// The registers of the missing register-classes can not be encoded by the register-id.
|
||||
break;
|
||||
}
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
|
@ -255,6 +263,14 @@ ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg)
|
|||
{
|
||||
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;
|
||||
|
@ -267,11 +283,11 @@ ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg)
|
|||
{
|
||||
return ZYDIS_REGISTERCLASS_MASK;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_BND0) && (reg <= ZYDIS_REGISTER_BND3))
|
||||
if ((reg >= ZYDIS_REGISTER_BND0) && (reg <= ZYDIS_REGISTER_BNDSTATUS))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_BOUNDS;
|
||||
}
|
||||
return ZYDIS_REGISTERCLASS_INVALID;
|
||||
return ZYDIS_REGISTERCLASS_NONE;
|
||||
}
|
||||
|
||||
ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg)
|
||||
|
@ -303,6 +319,10 @@ ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg)
|
|||
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_INVALID; // TODO:
|
||||
case ZYDIS_REGISTERCLASS_CONTROL:
|
||||
return ZYDIS_REGISTERSIZE_DYNAMIC;
|
||||
case ZYDIS_REGISTERCLASS_DEBUG:
|
||||
|
@ -317,113 +337,4 @@ ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg)
|
|||
return ZYDIS_REGISTERSIZE_INVALID;
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsGPR(ZydisRegister reg)
|
||||
{
|
||||
switch (ZydisRegisterGetClass(reg))
|
||||
{
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64:
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32:
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16:
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsGPR8(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsGPR16(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsGPR32(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsGPR64(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsFPRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_FLOATING_POINT);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsMMRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_MULTIMEDIA);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsVR(ZydisRegister reg)
|
||||
{
|
||||
switch (ZydisRegisterGetClass(reg))
|
||||
{
|
||||
case ZYDIS_REGISTERCLASS_VECTOR512:
|
||||
case ZYDIS_REGISTERCLASS_VECTOR256:
|
||||
case ZYDIS_REGISTERCLASS_VECTOR128:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsVR128(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR128);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsVR256(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR256);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsVR512(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR512);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsFlagsRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_FLAGS);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsIPRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_IP);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsSegmentRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_SEGMENT);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsCR(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_CONTROL);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsDR(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_DEBUG);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsMaskRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_MASK);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsBoundsRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_BOUNDS);
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
|
|
@ -64,19 +64,23 @@ ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info
|
|||
if (operand->imm.isSigned || operand->imm.isRelative)
|
||||
{
|
||||
*address = (uint64_t)((int64_t)info->instrPointer + operand->imm.value.sqword);
|
||||
switch (info->operandMode)
|
||||
switch (operand->size)
|
||||
{
|
||||
case 16:
|
||||
*address = (uint16_t)*address;
|
||||
break;
|
||||
case 32:
|
||||
assert((info->mode != ZYDIS_DISASSEMBLER_MODE_64BIT)); // TODO: Remove after fuzzing
|
||||
if (info->mode != ZYDIS_DISASSEMBLER_MODE_64BIT)
|
||||
{
|
||||
*address = (uint32_t)*address;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case 64:
|
||||
assert((info->mode == ZYDIS_DISASSEMBLER_MODE_64BIT)); // TODO: Remove after fuzzing
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue