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/Formatter.h"
"include/Zydis/Input.h"
"include/Zydis/InstructionDetails.h"
"include/Zydis/InstructionInfo.h"
"include/Zydis/Mnemonic.h"
"include/Zydis/Register.h"
"include/Zydis/Status.h"
"include/Zydis/Types.h"
"include/Zydis/Utils.h"
"include/Zydis/Zydis.h"
"include/Zydis/Internal/InstructionTable.h")
@ -63,7 +63,6 @@ set(sources
"src/Decoder.c"
"src/Formatter.c"
"src/Input.c"
"src/InstructionDetails.c"
"src/InstructionTable.c"
"src/Mnemonic.c"
"src/Register.c"

View File

@ -699,9 +699,9 @@ begin
end;
end;
S := 'ZYDIS_EVEXB_FUNCTIONALITY_NONE'; T := 'false'; U := 'false';
if (ifAcceptsEvexAAA in Definition.Flags) then S := 'true';
if (ifAcceptsEvexZ in Definition.Flags) then T := 'true';
S := 'ZYDIS_EVEXB_FUNCTIONALITY_NONE'; T := 'ZYDIS_FALSE'; U := 'ZYDIS_FALSE';
if (ifAcceptsEvexAAA in Definition.Flags) then S := 'ZYDIS_TRUE';
if (ifAcceptsEvexZ in Definition.Flags) then T := 'ZYDIS_TRUE';
if (ifHasEvexBC in Definition.Flags) then U := 'ZYDIS_EVEXB_FUNCTIONALITY_BC'
else
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';
Buffer.Append(Format(' /*%.4x*/ ', [Index]));
Buffer.Append(Format('{ ZYDIS_MNEMONIC_%s, 0x%.4x, %s, %s, %s, %d, %d, %d, %d, %d, %d, %d }', [
AnsiUpperCase(Definition.Mnemonic), O, U, S, T,
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,
Byte(pfAcceptsLock in Definition.PrefixFlags),
Byte(pfAcceptsREP in Definition.PrefixFlags),
Byte(pfAcceptsREPEREPNE in Definition.PrefixFlags),
Byte(pfAcceptsBOUND in Definition.PrefixFlags),
Byte(pfAcceptsXACQUIRE in Definition.PrefixFlags),
Byte(pfAcceptsXRELEASE in Definition.PrefixFlags),
Byte(pfAcceptsHLEWithoutLock in Definition.PrefixFlags),
@ -994,7 +995,7 @@ procedure AppendOperand(Buffer: TStringBuffer; Operand: TInstructionOperand);
var
OperandType,
OperandEncoding,
OperandAccessMode: String;
OperandAction: String;
begin
OperandType := 'UNUSED';
case Operand.OperandType of
@ -1082,33 +1083,37 @@ begin
end;
OperandEncoding := 'NONE';
case Operand.Encoding of
opeModrmReg : OperandEncoding := 'REG';
opeModrmRm : OperandEncoding := 'RM';
opeModrmRmCD1 : OperandEncoding := 'RM';
opeModrmRmCD2 : OperandEncoding := 'RM_CD2';
opeModrmRmCD4 : OperandEncoding := 'RM_CD4';
opeModrmRmCD8 : OperandEncoding := 'RM_CD8';
opeModrmRmCD16: OperandEncoding := 'RM_CD16';
opeModrmRmCD32: OperandEncoding := 'RM_CD32';
opeModrmRmCD64: OperandEncoding := 'RM_CD64';
opeOpcodeBits : OperandEncoding := 'OPCODE';
opeVexVVVV : OperandEncoding := 'VVVV';
opeEvexAAA : OperandEncoding := 'AAA';
opeImm8Lo : OperandEncoding := 'IMM8_LO';
opeImm8Hi : OperandEncoding := 'IMM8_HI';
opeImm8 : OperandEncoding := 'IMM8';
opeImm16 : OperandEncoding := 'IMM16';
opeImm32 : OperandEncoding := 'IMM32';
opeImm64 : OperandEncoding := 'IMM64';
opeModrmReg : OperandEncoding := 'REG';
opeModrmRm : OperandEncoding := 'RM';
opeModrmRmCD1 : OperandEncoding := 'RM';
opeModrmRmCD2 : OperandEncoding := 'RM_CD2';
opeModrmRmCD4 : OperandEncoding := 'RM_CD4';
opeModrmRmCD8 : OperandEncoding := 'RM_CD8';
opeModrmRmCD16 : OperandEncoding := 'RM_CD16';
opeModrmRmCD32 : OperandEncoding := 'RM_CD32';
opeModrmRmCD64 : OperandEncoding := 'RM_CD64';
opeOpcodeBits : OperandEncoding := 'OPCODE';
opeVexVVVV : OperandEncoding := 'VVVV';
opeEvexAAA : OperandEncoding := 'AAA';
opeImm8Lo : OperandEncoding := 'IMM8_LO';
opeImm8Hi : OperandEncoding := 'IMM8_HI';
opeImm8 : OperandEncoding := 'IMM8';
opeImm16 : OperandEncoding := 'IMM16';
opeImm32 : OperandEncoding := 'IMM32';
opeImm64 : OperandEncoding := 'IMM64';
end;
OperandAccessMode := 'READ';
case Operand.AccessMode of
opaWrite : OperandAccessMode := 'WRITE';
opaReadWrite : OperandAccessMode := 'READWRITE';
OperandAction := 'READ';
case Operand.Action of
opaWrite : OperandAction := 'WRITE';
opaReadWrite : OperandAction := 'READWRITE';
opaCondRead : OperandAction := 'COND_READ';
opaCondWrite : OperandAction := 'COND_WRITE';
opaReadCondWrite: OperandAction := 'READ_COND_WRITE';
opaWriteCondRead: OperandAction := 'WRITE_COND_READ';
end;
Buffer.Append(Format('ZYDIS_OPERAND_DEFINITION(ZYDIS_SEM_OPERAND_TYPE_%s, ' +
'ZYDIS_OPERAND_ENCODING_%s, ZYDIS_OPERAND_ACCESS_%s)', [
OperandType, OperandEncoding, OperandAccessMode]));
'ZYDIS_OPERAND_ENCODING_%s, ZYDIS_OPERAND_ACTION_%s)', [
OperandType, OperandEncoding, OperandAction]));
end;
var

View File

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

View File

@ -326,9 +326,9 @@ begin
end;
if (Length(A) >= 1) then
begin
if (A[1] = 'r') then TInstructionOperand(GetOrdValue).AccessMode := opaRead
else if (A[1] = 'w') then TInstructionOperand(GetOrdValue).AccessMode := opaWrite
else if (A[1] = 'rw') then TInstructionOperand(GetOrdValue).AccessMode := opaReadWrite;
if (A[1] = 'r') then TInstructionOperand(GetOrdValue).Action := opaRead
else if (A[1] = 'w') then TInstructionOperand(GetOrdValue).Action := opaWrite
else if (A[1] = 'rw') then TInstructionOperand(GetOrdValue).Action := opaReadWrite;
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
@ -98,9 +98,9 @@ static ZydisStatus ZydisFormatterPrintMnemonic(ZydisInstructionFormatter* format
info->userData = (void*)1;
// 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)
{
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)
{
switch (info->mnemonic)
@ -203,11 +203,6 @@ void disassembleBuffer(uint8_t* data, size_t length, bool installHooks)
while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info)))
{
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));
printf(" %s\n", &buffer[0]);
}

View File

@ -1,6 +1,6 @@
/***************************************************************************************************
Zyan Disassembler Engine (Zydis)
Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd
@ -27,8 +27,8 @@
#ifndef ZYDIS_DECODER_H
#define ZYDIS_DECODER_H
#include <stdint.h>
#include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h>
#include <Zydis/Input.h>
#include <Zydis/InstructionInfo.h>
@ -55,40 +55,6 @@ typedef uint32_t ZydisDecoderFlags;
* have one of the @c ZYDIS_INSTRFLAG_ERROR_MASK flags set.
*/
#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.
*/
bool imm8initialized;
ZydisBool imm8initialized;
/**
* @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.
*/
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.
*/

View File

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

View File

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

View File

@ -1,6 +1,6 @@
/***************************************************************************************************
Zyan Disassembler Engine (Zydis)
Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd
@ -27,10 +27,9 @@
#ifndef ZYDIS_INPUT_H
#define ZYDIS_INPUT_H
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h>
#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
* 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.

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 acceptsREP : 1;
uint32_t acceptsREPEREPNE : 1;
uint32_t acceptsBOUND : 1;
uint32_t acceptsXACQUIRE : 1;
uint32_t acceptsXRELEASE : 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
@ -27,7 +27,6 @@
#ifndef ZYDIS_INSTRUCTIONTABLE_H
#define ZYDIS_INSTRUCTIONTABLE_H
#include <stdint.h>
#include <Zydis/Defines.h>
#include <Zydis/Mnemonic.h>
#include <Zydis/InstructionInfo.h>
@ -89,7 +88,7 @@ typedef struct ZydisOperandDefinition_
{
ZydisSemanticOperandType type : 7;
ZydisOperandEncoding encoding : 5;
ZydisOperandAccess access : 2;
ZydisOperandAction action : 3;
} ZydisOperandDefinition;
#include <Zydis/Internal/GeneratedTypes.inc>
@ -139,7 +138,7 @@ enum ZydisInstructionTableNodeTypes
*/
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,
/**
@ -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.
*/
ZYDIS_NO_EXPORT bool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
ZYDIS_NO_EXPORT ZydisBool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
const ZydisInstructionDefinition** definition, const ZydisOperandDefinition** operands,
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
@ -27,8 +27,8 @@
#ifndef ZYDIS_MNEMONIC_H
#define ZYDIS_MNEMONIC_H
#include <stdint.h>
#include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h>
#ifdef __cplusplus
@ -59,17 +59,6 @@ typedef uint16_t ZydisInstructionMnemonic;
*/
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

View File

@ -1,6 +1,6 @@
/***************************************************************************************************
Zyan Disassembler Engine (Zydis)
Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd
@ -27,9 +27,9 @@
#ifndef ZYDIS_REGISTER_H
#define ZYDIS_REGISTER_H
#include <stdint.h>
#include <stdbool.h>
#include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h>
#ifdef __cplusplus
extern "C" {
@ -39,6 +39,10 @@ extern "C" {
/* Enums and types */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Registers */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisRegister datatype.
*/
@ -58,7 +62,7 @@ enum ZydisRegisters
// General purpose registers 32-bit
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_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,
// General purpose registers 16-bit
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_XMM24, ZYDIS_REGISTER_XMM25, ZYDIS_REGISTER_XMM26, ZYDIS_REGISTER_XMM27,
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
ZYDIS_REGISTER_RFLAGS, ZYDIS_REGISTER_EFLAGS, ZYDIS_REGISTER_FLAGS, ZYDIS_REGISTER_RIP,
ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_IP, ZYDIS_REGISTER_MXCSR, ZYDIS_REGISTER_PKRU,
ZYDIS_REGISTER_XCR0,
ZYDIS_REGISTER_MXCSR, ZYDIS_REGISTER_PKRU, ZYDIS_REGISTER_XCR0,
// Segment registers
ZYDIS_REGISTER_ES, ZYDIS_REGISTER_SS, ZYDIS_REGISTER_CS, ZYDIS_REGISTER_DS,
ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS,
@ -129,11 +135,13 @@ enum ZydisRegisters
// Mask registers
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
// Bound registers
ZYDIS_REGISTER_BND0, ZYDIS_REGISTER_BND1, ZYDIS_REGISTER_BND2, ZYDIS_REGISTER_BND3,
ZYDIS_REGISTER_BNDCFG, ZYDIS_REGISTER_BNDSTATUS
};
/* ---------------------------------------------------------------------------------------------- */
/* Register classes */
/* ---------------------------------------------------------------------------------------------- */
/**
@ -146,210 +154,87 @@ typedef uint8_t ZydisRegisterClass;
*/
enum ZydisRegisterClasses
{
ZYDIS_REGISTERCLASS_NONE,
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8,
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16,
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32,
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64,
ZYDIS_REGISTERCLASS_FLOATING_POINT,
ZYDIS_REGISTERCLASS_MULTIMEDIA,
ZYDIS_REGISTERCLASS_VECTOR128,
ZYDIS_REGISTERCLASS_VECTOR256,
ZYDIS_REGISTERCLASS_VECTOR512,
ZYDIS_REGISTERCLASS_FLAGS,
ZYDIS_REGISTERCLASS_IP,
ZYDIS_REGISTERCLASS_SEGMENT,
ZYDIS_REGISTERCLASS_TABLE,
ZYDIS_REGISTERCLASS_TEST,
ZYDIS_REGISTERCLASS_CONTROL,
ZYDIS_REGISTERCLASS_DEBUG,
ZYDIS_REGISTERCLASS_MASK,
ZYDIS_REGISTERCLASS_BOUNDS
ZYDIS_REGCLASS_INVALID,
/**
* @brief 8-bit general-purpose registers.
*/
ZYDIS_REGCLASS_GPR8,
/**
* @brief 16-bit general-purpose registers.
*/
ZYDIS_REGCLASS_GPR16,
/**
* @brief 32-bit general-purpose registers.
*/
ZYDIS_REGCLASS_GPR32,
/**
* @brief 64-bit general-purpose registers.
*/
ZYDIS_REGCLASS_GPR64,
/**
* @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 */
@ -361,9 +246,19 @@ enum ZydisRegisterSizes
* @param registerClass The register class.
* @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.
@ -375,13 +270,22 @@ ZYDIS_EXPORT ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass
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.
*
* @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.

View File

@ -1,6 +1,6 @@
/***************************************************************************************************
Zyan Disassembler Engine (Zydis)
Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd
@ -27,7 +27,7 @@
#ifndef ZYDIS_STATUS_H
#define ZYDIS_STATUS_H
#include <stdint.h>
#include <Zydis/Types.h>
#ifdef __cplusplus
extern "C" {
@ -47,36 +47,86 @@ typedef uint32_t ZydisStatus;
*/
enum ZydisStatusCode
{
/* ------------------------------------------------------------------------------------------ */
/* General */
/* ------------------------------------------------------------------------------------------ */
/**
* @brief The operation completed successfully.
*/
ZYDIS_STATUS_SUCCESS = 0x00000000,
ZYDIS_STATUS_SUCCESS = 0x00000000,
/**
* @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.
*/
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
* 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
* field of the @c ZydisInstructionInfo struct for further details.
* @brief An general error occured while decoding the current instruction. The instruction
* 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.
*/
ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE = 0x00000005,
ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE,
/* ------------------------------------------------------------------------------------------ */
/* Misc */
/* ------------------------------------------------------------------------------------------ */
/**
* @brief The base value for user-defined status codes.
*/
ZYDIS_STATUS_USER = 0x10000000
ZYDIS_STATUS_USER = 0x10000000
};
/* ============================================================================================== */
@ -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)

View File

@ -1,6 +1,6 @@
/***************************************************************************************************
Zyan Disassembler Engine (Zydis)
Zyan Disassembler Library (Zydis)
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)
{
(void)info;
(void)featureFlag;
return false;
/**
* size_t, ptrdiff_t
*/
#include <stddef.h>
/* ============================================================================================== */
/* 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,
ZydisCPUIDFeatureFlag* featureFlag)
{
(void)info;
(void)featureFlag;
return false;
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
#endif /* ZYDIS_TYPES_H */

View File

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

View File

@ -1,6 +1,6 @@
/***************************************************************************************************
Zyan Disassembler Engine (Zydis)
Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd
@ -27,17 +27,16 @@
#ifndef ZYDIS_H
#define ZYDIS_H
#include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h>
#include <Zydis/Mnemonic.h>
#include <Zydis/Register.h>
#include <Zydis/InstructionDetails.h>
#include <Zydis/InstructionInfo.h>
#include <Zydis/Input.h>
#include <Zydis/Decoder.h>
#include <Zydis/Formatter.h>
// TODO: Replace "bool" with a custom - compiler-unspecific sized - zype
#ifdef __cplusplus
extern "C" {
#endif
@ -94,7 +93,7 @@ extern "C" {
/* ============================================================================================== */
/**
* @brief Defines the zydis feature datatype.
* @brief Defines the @c ZydisFeature datatype.
*/
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.
*/
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
@ -26,12 +26,9 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>
#include <assert.h>
#include <Zydis/Status.h>
#include <Zydis/Formatter.h>
#include <Zydis/Utils.h>
@ -206,33 +203,34 @@ static ZydisStatus ZydisFormatterPrintPrefixesIntel(ZydisInstructionFormatter* f
return ZYDIS_STATUS_INVALID_PARAMETER;
}
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_LOCK) &&
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_LOCK))
if (info->attributes & ZYDIS_ATTRIB_HAS_LOCK)
{
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "lock ");
}
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REP) &&
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP))
if (info->attributes & ZYDIS_ATTRIB_HAS_REP)
{
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "rep ");
}
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REPE) &&
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPE))
if (info->attributes & ZYDIS_ATTRIB_HAS_REPE)
{
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "repe ");
}
if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REPNE) &&
(info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE))
if (info->attributes & ZYDIS_ATTRIB_HAS_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 ");
}
if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_XRELEASE)
if (info->attributes & ZYDIS_ATTRIB_HAS_XRELEASE)
{
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "xrelease ");
}
@ -287,8 +285,10 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(ZydisInstructionFormatter
ZYDIS_CHECK(
ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "["));
if ((operand->mem.disp.dataSize != 0) && ((operand->mem.base == ZYDIS_REGISTER_NONE) ||
(operand->mem.base == ZYDIS_REGISTER_EIP) || (operand->mem.base == ZYDIS_REGISTER_RIP)) &&
if ((operand->mem.disp.dataSize != 0) && (
(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))
{
// Address operand
@ -362,7 +362,7 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(ZydisInstructionFormatter
// The immediate operand contains an address
if (operand->imm.isRelative)
{
bool printSignedHEX = false;
ZydisBool printSignedHEX = ZYDIS_FALSE;
switch (formatter->addressFormat)
{
case ZYDIS_FORMATTER_ADDR_DEFAULT:
@ -374,7 +374,7 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(ZydisInstructionFormatter
address);
}
case ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED:
printSignedHEX = true;
printSignedHEX = ZYDIS_TRUE;
break;
case ZYDIS_FORMATTER_ADDR_RELATIVE_UNSIGNED:
break;
@ -426,11 +426,13 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(ZydisInstructionFormatte
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
if ((operand->mem.disp.dataSize) && ((operand->mem.disp.value.sqword) ||
((operand->mem.base == ZYDIS_REGISTER_NONE) &&
(operand->mem.index == ZYDIS_REGISTER_NONE))))
{
bool printSignedHEX = (formatter->displacementFormat != ZYDIS_FORMATTER_DISP_HEX_UNSIGNED);
ZydisBool printSignedHEX =
(formatter->displacementFormat != ZYDIS_FORMATTER_DISP_HEX_UNSIGNED);
if (printSignedHEX && (operand->mem.disp.value.sqword < 0) && (
(operand->mem.base != ZYDIS_REGISTER_NONE) ||
(operand->mem.index != ZYDIS_REGISTER_NONE)))
@ -438,12 +440,13 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(ZydisInstructionFormatte
return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "-0x%02"PRIX32, -operand->mem.disp.value.sdword);
}
const char* sign =
((operand->mem.base == ZYDIS_REGISTER_NONE) &&
(operand->mem.index == ZYDIS_REGISTER_NONE)) ? "" : "+";
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"%s0x%02"PRIX32, sign, operand->mem.disp.value.sdword);
}
const char* sign =
((operand->mem.base == ZYDIS_REGISTER_NONE) &&
(operand->mem.index == ZYDIS_REGISTER_NONE)) ? "" : "+";
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"%s0x%02"PRIX32, sign, operand->mem.disp.value.sdword);
return ZYDIS_STATUS_SUCCESS;
}
static ZydisStatus ZydisFormatterPrintImmediateIntel(ZydisInstructionFormatter* formatter,
@ -454,7 +457,7 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(ZydisInstructionFormatter*
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)
{
printSignedHEX = operand->imm.isSigned;
@ -511,21 +514,21 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(ZydisInstructionFormatter
uint32_t typecast = 0;
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)
{
case 0:
typecast = ((info->operand[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
(info->operand[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
(info->operand[0].size != info->operand[1].size)) ? info->operand[0].size : 0;
typecast = ((info->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
(info->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
(info->operands[0].size != info->operands[1].size)) ? info->operands[0].size : 0;
if (!typecast &&
(info->operand[1].type == ZYDIS_OPERAND_TYPE_REGISTER) &&
(info->operand[1].reg == ZYDIS_REGISTER_CL))
(info->operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER) &&
(info->operands[1].reg == ZYDIS_REGISTER_CL))
{
switch (info->mnemonic)
{
@ -536,7 +539,7 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(ZydisInstructionFormatter
case ZYDIS_MNEMONIC_SHL:
case ZYDIS_MNEMONIC_SHR:
case ZYDIS_MNEMONIC_SAR:
typecast = info->operand[0].size;
typecast = info->operands[0].size;
default:
break;
}
@ -545,8 +548,8 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(ZydisInstructionFormatter
case 1:
case 2:
typecast =
(info->operand[operand->id - 1].size != info->operand[operand->id].size) ?
info->operand[operand->id].size : 0;
(info->operands[operand->id - 1].size != info->operands[operand->id].size) ?
info->operands[operand->id].size : 0;
break;
default:
break;
@ -610,7 +613,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(ZydisInstructionFormatter* fo
ZydisRegisterGetString(operand->mem.segment));
case ZYDIS_REGISTER_CS:
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:",
ZydisRegisterGetString(operand->mem.segment));
@ -618,7 +621,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(ZydisInstructionFormatter* fo
break;
case ZYDIS_REGISTER_DS:
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:",
ZydisRegisterGetString(operand->mem.segment));
@ -627,7 +630,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(ZydisInstructionFormatter* fo
default:
break;
}
return ZYDIS_STATUS_INVALID_PARAMETER;
return ZYDIS_STATUS_SUCCESS;
}
static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter* formatter,
@ -652,32 +655,32 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter*
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE,
" {%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_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
}
} 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)
{
case ZYDIS_AVX_BCSTMODE_INVALID:
case ZYDIS_AVX512_BCSTMODE_INVALID:
break;
case ZYDIS_AVX_BCSTMODE_2:
case ZYDIS_AVX512_BCSTMODE_2:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
break;
case ZYDIS_AVX_BCSTMODE_4:
case ZYDIS_AVX512_BCSTMODE_4:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
break;
case ZYDIS_AVX_BCSTMODE_8:
case ZYDIS_AVX512_BCSTMODE_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
break;
case ZYDIS_AVX_BCSTMODE_16:
case ZYDIS_AVX512_BCSTMODE_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
break;
@ -688,12 +691,12 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(ZydisInstructionFormatter*
if ((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)
{
case ZYDIS_AVX_RNDMODE_INVALID:
if (info->avx.sae)
if (info->avx.hasSAE)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sae}"));
@ -751,23 +754,23 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
}
const char* bufPreOperand = *buffer;
switch (info->operand[i].type)
switch (info->operands[i].type)
{
case ZYDIS_OPERAND_TYPE_UNUSED:
return ZYDIS_STATUS_INVALID_PARAMETER;
case ZYDIS_OPERAND_TYPE_REGISTER:
ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i]));
info, &info->operands[i]));
break;
case ZYDIS_OPERAND_TYPE_MEMORY:
{
ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i]));
info, &info->operands[i]));
ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i]));
info, &info->operands[i]));
const char* bufTemp = *buffer;
ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i]));
info, &info->operands[i]));
if (bufTemp == *buffer)
{
*buffer = (char*)bufPreOperand;
@ -776,11 +779,11 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
}
case ZYDIS_OPERAND_TYPE_POINTER:
ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i]));
info, &info->operands[i]));
break;
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer, bufEnd - *buffer,
info, &info->operand[i]));
info, &info->operands[i]));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
@ -788,7 +791,7 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
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[0] = 0;
} else
@ -796,7 +799,7 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(ZydisInstructionFormatter* for
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX)
{
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
@ -24,8 +24,6 @@
***************************************************************************************************/
#include <assert.h>
#include <Zydis/Status.h>
#include <Zydis/Input.h>
/* ============================================================================================== */
@ -36,14 +34,14 @@
/* Internal functions */
/* ---------------------------------------------------------------------------------------------- */
static bool ZydisMemoryInputNext(ZydisMemoryInput* input, uint8_t* data)
static ZydisBool ZydisMemoryInputNext(ZydisMemoryInput* input, uint8_t* data)
{
if (input->inputBufferPos >= input->inputBufferLen)
{
return false;
return ZYDIS_FALSE;
}
*data = input->inputBuffer[input->inputBufferPos++];
return true;
return ZYDIS_TRUE;
}
/* ---------------------------------------------------------------------------------------------- */
@ -73,7 +71,7 @@ ZydisStatus ZydisInputInitMemoryInput(ZydisMemoryInput* input, const void* buffe
/* Internal functions */
/* ---------------------------------------------------------------------------------------------- */
static bool ZydisFileInputNext(ZydisFileInput* input, uint8_t* data)
static ZydisBool ZydisFileInputNext(ZydisFileInput* input, uint8_t* data)
{
int c = fgetc(input->file);
*data = (uint8_t)c;

View File

@ -1,6 +1,6 @@
/***************************************************************************************************
Zyan Disassembler Engine (Zydis)
Zyan Disassembler Library (Zydis)
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];
@ -264,7 +264,7 @@ const ZydisInstructionTableNode* ZydisInstructionTableGetChildNode(
return &invalid;
}
bool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
ZydisBool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
const ZydisInstructionDefinition** definition, const ZydisOperandDefinition** operands,
uint8_t* operandCount)
{
@ -296,9 +296,9 @@ bool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
break;
default:
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
@ -24,8 +24,6 @@
***************************************************************************************************/
#include <stddef.h>
#include <Zydis/Defines.h>
#include <Zydis/Mnemonic.h>
/* ============================================================================================== */
@ -50,12 +48,4 @@ const char* ZydisMnemonicGetString(ZydisInstructionMnemonic 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
@ -24,8 +24,6 @@
***************************************************************************************************/
#include <stddef.h>
#include <stdbool.h>
#include <Zydis/Register.h>
/* ============================================================================================== */
@ -119,96 +117,121 @@ const char* registerStrings[] =
"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 */
/* ============================================================================================== */
ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass, uint8_t id)
ZydisRegister ZydisRegisterEncode(ZydisRegisterClass registerClass, uint8_t id)
{
switch (registerClass)
{
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8:
if (id <= 19)
{
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.
case ZYDIS_REGCLASS_INVALID:
case ZYDIS_REGCLASS_FLAGS:
case ZYDIS_REGCLASS_IP:
break;
default:
if ((registerClass < registerMapCount) &&
(id < (registerMap[registerClass].hi - registerMap[registerClass].lo)))
{
return registerMap[registerClass].lo + id;
}
}
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)
{
if ((reg == 0) || (reg > (sizeof(registerStrings) / sizeof(registerStrings[0])) - 1))
@ -218,124 +241,4 @@ const char* ZydisRegisterGetString(ZydisRegister 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
@ -74,7 +74,6 @@ ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info
}
break;
case ZYDIS_DISASSEMBLER_MODE_64BIT:
assert((operand->size == 64)); // TODO: Remove after fuzzing
break;
default:
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
@ -35,32 +35,32 @@ uint64_t ZydisGetVersion()
return ZYDIS_VERSION;
}
bool ZydisIsFeatureEnabled(ZydisFeature feature)
ZydisBool ZydisIsFeatureEnabled(ZydisFeature feature)
{
switch (feature)
{
case ZYDIS_FEATURE_IMPLICITLY_USED_REGISTERS:
#ifdef ZYDIS_ENABLE_FEATURE_IMPLICITLY_USED_REGISTERS
return true;
return ZYDIS_TRUE;
#else
return false;
return ZYDIS_FALSE;
#endif
case ZYDIS_FEATURE_AFFECTED_FLAGS:
#ifdef ZYDIS_ENABLE_FEATURE_AFFECTED_FLAGS
return true;
return ZYDIS_TRUE;
#else
return false;
return ZYDIS_FALSE;
#endif
case ZYDIS_FEATURE_CPUID:
#ifdef ZYDIS_ENABLE_FEATURE_CPUID
return true;
return ZYDIS_TRUE;
#else
return false;
return ZYDIS_FALSE;
#endif
default:
break;
}
return false;
return ZYDIS_FALSE;
}
/* ============================================================================================== */