Skip to content

Instantly share code, notes, and snippets.

@HoShiMin
Last active February 16, 2019 21:06
Show Gist options
  • Save HoShiMin/0dfa6f30b24baefa0804 to your computer and use it in GitHub Desktop.
Save HoShiMin/0dfa6f30b24baefa0804 to your computer and use it in GitHub Desktop.
Минималистичный и очень быстрый дизассемблер длин
unit MicroDAsm;
interface
type
TREXStruct = record
B: Boolean; // Extension of the ModR/M r/m field, SIB base field, or Opcode reg field
X: Boolean; // Extension of the SIB index field
R: Boolean; // Extension of the ModR/M reg field
W: Boolean; // 0 = Operand size determined by CS.D; 1 = 64 Bit Operand Size
end;
type
TInstruction = record
PrefixesSize : Byte;
LegacyPrefixes : array [0..3] of Byte;
REXPresent : Boolean;
REXOffset : Byte;
REXPrefix : Byte;
REXStruct : TREXStruct;
OpcodeOffset : Byte;
OpcodeIsExtended : Boolean;
OpcodeFlags : Byte;
OpcodeSize : Byte;
Opcode : array [0..2] of Byte;
FullOpcode : LongWord;
ModRMPresent : Boolean;
ModRMOffset : Byte;
ModRM : Byte;
SIBPresent : Boolean;
SIBOffset : Byte;
SIB : Byte;
AddressDisplacementPresent : Boolean;
AddressDisplacementOffset : Byte;
AddressDisplacementSize : Byte;
AddressDisplacement : UInt64;
ImmediateDataPresent : Boolean;
ImmediateDataOffset : Byte;
ImmediateDataSize : Byte;
ImmediateData : UInt64;
ScaleIndex : Byte;
DisplacementWithBase : Boolean;
end;
// GRP:
const
GRP1 = 0;
GRP2 = 1;
GRP3 = 2;
GRP4 = 3;
// Legacy Prefixes:
const
PrefixNone = $00;
// Legacy Prefix GRP 1:
LockPrefix = $F0;
RepneRepnzPrefix = $F2;
RepeRepzPrefix = $F3;
// Legacy Prefix GRP 2:
CSOverridePrefix = $2E;
SSOverridePrefix = $36;
DSOverridePrefix = $3E;
ESOverridePrefix = $26;
FSOverridePrefix = $64;
GSOverridePrefix = $65;
BranchNotTakenPrefix = $2E; // Только с Jcc
BranchTakenPrefix = $3E; // Только с Jcc
// Legacy Prefix GRP 3:
OperandSizeOverridePrefix = $66;
// Legacy Prefix GRP 4:
AddressSizeOverridePrefix = $67;
// REX Prefix - определяет 64х-битный размер операндов, расширенные контрольные регистры:
const
REXNone = $00;
RexDiapason = [$40..$4F];
// Опкоды:
const
EXTENDED_OPCODE = $0F;
ThirdByteOpcodeSignature = [$66, $F2, $F3];
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
function LDasm(Code: Pointer; Is64Bit: Boolean; out Instruction: TInstruction): Byte;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
{$I MicroDAsmTables.inc}
implementation
{$IFDEF CPUX64}
type
NativeUInt = UInt64;
{$ELSE}
type
NativeUInt = LongWord;
{$ENDIF}
function GetByte(BaseAddress: Pointer; Offset: NativeUInt): Byte; inline;
begin
Result := Byte((Pointer(NativeUInt(BaseAddress) + Offset))^);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function GetWord(BaseAddress: Pointer; Offset: NativeUInt): Word; inline;
begin
Result := Word((Pointer(NativeUInt(BaseAddress) + Offset))^);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function GetDWord(BaseAddress: Pointer; Offset: NativeUInt): LongWord; inline;
begin
Result := LongWord((Pointer(NativeUInt(BaseAddress) + Offset))^);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function GetQWord(BaseAddress: Pointer; Offset: NativeUInt): UInt64; inline;
begin
Result := UInt64((Pointer(NativeUInt(BaseAddress) + Offset))^);
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
function IsBitSet(Number, BitNumber: LongWord): Boolean; inline;
begin
Result := (Number and (1 shl BitNumber)) <> 0;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IsNumberContains(Number, SubNumber: LongWord): Boolean; inline;
begin
Result := (Number and SubNumber) = SubNumber;
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
procedure GetModRmParts(ModRM: Byte; out _Mod, _Reg, _RM: Byte); inline;
begin
// 192 = 11 000 000
// 56 = 111 000
// 7 = 111
_Mod := (ModRM and 192) shr 6;
_Reg := (ModRM and 56) shr 3;
_RM := (ModRM and 7);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure GetSibParts(SIB: Byte; out _Scale, _Index, _Base: Byte); inline;
begin
// 192 = 11 000 000
// 56 = 111 000
// 7 = 111
_Scale := (SIB and 192) shr 6;
_Index := (SIB and 56) shr 3;
_Base := (SIB and 7);
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
function IsModRmPresent(Opcode: LongWord; Size: LongWord): Boolean; //inline;
begin
Result := False;
case Size of
1: Result := (OneByteOpcodeFlags[Opcode] and OP_MODRM) = OP_MODRM;
2: Result := (TwoBytesOpcodeFlags[Opcode] and OP_MODRM) = OP_MODRM;
//3: ...
end;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function IsSibPresent(ModRM: Byte): Boolean; inline;
begin
// Mod Reg R/M
// 192 = 11 000 000b - Mod
// 4 = 100b - R/M
Result := ((ModRM and 192) <> 192) and ((ModRM and $7) = 4);
end;
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
function LDasm(Code: Pointer; Is64Bit: Boolean; out Instruction: TInstruction): Byte;
var
TempByte : Byte;
RexByte : Byte;
OpCodeByte : Byte;
ModRmByte : Byte;
SibByte : Byte;
I : Byte;
//OperandSize : Byte;
_Mod, _Reg, _RM : Byte;
_Scale, _Index, _Base : Byte;
begin
{
Структура инструкции:
GRP 1, 2, 3, 4 7.....0 7.....0 7.....0
+------------------------+-------------------+---------------------------+
| Legacy Prefixes (opt.) | REX Prefix (opt.) | = OPCODE (1, 2, 3 byte) = +--+
+------------------------+-------------------+---------------------------+ |
|
+-----------------------------------------------------------------------+
|
| +-----+-----+-----+ +-------+-------+------+
+-->| Mod | Reg | R/M | + | Scale | Index | Base | + d32|16|8|N + d32|16|8|N
+-----+-----+-----+ +-------+-------+------+ Address Immediate
7-6 5-3 2-0 7-6 5-3 2-0 Displacement Data
Mod R/M Byte SIB Byte
Принцип разбора:
1) Получить префиксы (опциональные, до 4х байт)
2) Если код х64 - получить опциональный REX-префикс, отвечающий за 64х-битную адресацию.
3) Спарсить опкод (от одного до трёх байт, в зависимости от префиксов и первого байта опкода)
4) По таблице опкодов определить наличие байта ModRM и размер данных
5) По таблице ModRM (если инструкция использует ModRM) определить наличие SIB
}
Result := 0;
FillChar(Instruction, SizeOf(Instruction), #0);
//OperandSize := 0;
// Получаем Legacy Prefix всех групп (GRP 1 - GRP 4):
for I := 0 to 3 do
begin
case GetByte(Code, I) of
LockPrefix : Instruction.LegacyPrefixes[I] := LockPrefix;
RepneRepnzPrefix : Instruction.LegacyPrefixes[I] := RepneRepnzPrefix;
RepeRepzPrefix : Instruction.LegacyPrefixes[I] := RepeRepzPrefix;
CSOverridePrefix : Instruction.LegacyPrefixes[I] := CSOverridePrefix;
SSOverridePrefix : Instruction.LegacyPrefixes[I] := SSOverridePrefix;
DSOverridePrefix : Instruction.LegacyPrefixes[I] := DSOverridePrefix;
ESOverridePrefix : Instruction.LegacyPrefixes[I] := ESOverridePrefix;
FSOverridePrefix : Instruction.LegacyPrefixes[I] := FSOverridePrefix;
GSOverridePrefix : Instruction.LegacyPrefixes[I] := GSOverridePrefix;
// BranchNotTakenPrefix : Instruction.LegacyPrefixes[I] := BranchNotTakenPrefix;
// BranchTakenPrefix : Instruction.LegacyPrefixes[I] := BranchTakenPrefix;
OperandSizeOverridePrefix : Instruction.LegacyPrefixes[I] := OperandSizeOverridePrefix;
AddressSizeOverridePrefix : Instruction.LegacyPrefixes[I] := AddressSizeOverridePrefix;
else
Break;
end;
Inc(Instruction.PrefixesSize);
end;
Instruction.REXOffset := Instruction.PrefixesSize;
// Выставляем смещение опкода равное REX'у - вдруг REX'a нет,
// а смещение опкода уже стоит:
Instruction.OpcodeOffset := Instruction.REXOffset;
// Получаем REX-префикс:
if Is64Bit then
begin
TempByte := GetByte(Code, Instruction.REXOffset);
// Проверяем, является ли байт REX-префиксом [$40..$4F]:
if TempByte in RexDiapason then
begin
Inc(Result);
RexByte := TempByte;
Instruction.REXPrefix := RexByte;
Instruction.REXPresent := True;
Instruction.REXStruct.B := IsBitSet(RexByte, 0);
Instruction.REXStruct.X := IsBitSet(RexByte, 1);
Instruction.REXStruct.R := IsBitSet(RexByte, 2);
Instruction.REXStruct.W := IsBitSet(RexByte, 3);
{
// Обрабатываем REX:
case Instruction.REXStruct.W of
True: if (Instruction.LegacyPrefixes[GRP1] = OperandSizeOverridePrefix) or
(Instruction.LegacyPrefixes[GRP2] = OperandSizeOverridePrefix) or
(Instruction.LegacyPrefixes[GRP3] = OperandSizeOverridePrefix) or
(Instruction.LegacyPrefixes[GRP4] = OperandSizeOverridePrefix)
then
OperandSize := 4 // 4 байта = 32 бита
else
OperandSize := 0; // Размер операнда определяется через CS.D
False: OperandSize := 8; // 8 байт = 64 бита
end;
}
// Увеличиваем смещение опкода:
Inc(Instruction.OpcodeOffset);
// if byte is REX-byte <-
end;
// if Is64Bit then <-
end;
// Разбираем опкод:
OpCodeByte := GetByte(Code, Instruction.OpcodeOffset);
Instruction.OpcodeIsExtended := OpCodeByte = EXTENDED_OPCODE;
case Instruction.OpcodeIsExtended of
True:
begin
// Разделяем двухбайтные и трёхбайтные опкоды:
if Instruction.OpcodeOffset > 0 then
begin
if GetByte(Code, Instruction.OpcodeOffset - 1) in ThirdByteOpcodeSignature then
begin
// Трёхбайтный опкод:
Instruction.LegacyPrefixes[Instruction.PrefixesSize - 1] := PrefixNone;
Dec(Instruction.OpcodeOffset);
Instruction.OpcodeSize := 3;
Instruction.Opcode[0] := GetByte(Code, Instruction.OpcodeOffset);
Instruction.Opcode[1] := GetByte(Code, Instruction.OpcodeOffset + 1);
Instruction.Opcode[2] := GetByte(Code, Instruction.OpcodeOffset + 2);
end
else
begin
// Двухбайтный опкод:
Instruction.OpcodeSize := 2;
Instruction.Opcode[0] := OpCodeByte;
Instruction.Opcode[1] := GetByte(Code, Instruction.OpcodeOffset + 1);
end;
end
else
begin
// Двухбайтный опкод:
Instruction.OpcodeSize := 2;
Instruction.Opcode[0] := OpCodeByte;
Instruction.Opcode[1] := GetByte(Code, Instruction.OpcodeOffset + 1);
end;
end;
False:
begin
Instruction.OpcodeSize := 1;
Instruction.Opcode[0] := OpCodeByte;
end;
end;
// Получаем полный опкод:
for I := 0 to Instruction.OpcodeSize - 1 do
begin
Instruction.FullOpcode := Instruction.FullOpcode shl 8;
Instruction.FullOpcode := Instruction.FullOpcode + Instruction.Opcode[I];
end;
Instruction.ModRMPresent := IsModRmPresent(Instruction.FullOpcode, Instruction.OpcodeSize);
if Instruction.ModRMPresent then
begin
Inc(Result);
Instruction.ModRMOffset := Instruction.OpcodeOffset + Instruction.OpcodeSize;
// Разбираем байт ModR/M:
ModRmByte := GetByte(Code, Instruction.ModRMOffset);
Instruction.SIBPresent := IsSibPresent(ModRmByte);
GetModRmParts(ModRmByte, _Mod, _Reg, _RM);
if Instruction.SIBPresent then
begin
Inc(Result);
Instruction.SIBOffset := Instruction.ModRMOffset + 1;
SibByte := GetByte(Code, Instruction.SIBOffset);
GetSibParts(SibByte, _Scale, _Index, _Base);
Instruction.ScaleIndex := _Scale * 2; // [Регистр * ScaleIndex]
if _Base = 5 { 101b } then
begin
if (_Mod = 1 { 01b } ) or (_Mod = 2 { 10b } ) then
Instruction.DisplacementWithBase := True;
end;
end;
case _Mod of
0: { 00b }
with Instruction do
begin
if (_RM = 5 { 101b } ) or (Instruction.SIBPresent and (_Base = 5 { 101b } )) then
begin
Instruction.AddressDisplacementPresent := True;
AddressDisplacementSize := 4;
AddressDisplacementOffset := SIBOffset + 1;
AddressDisplacement := GetDWord(Code, AddressDisplacementOffset);
end;
end;
1: { 01b }
with Instruction do
begin
Instruction.AddressDisplacementPresent := True;
AddressDisplacementSize := 1;
AddressDisplacementOffset := SIBOffset + 1;
AddressDisplacement := GetByte(Code, AddressDisplacementOffset);
end;
2: { 10b }
with Instruction do
begin
Instruction.AddressDisplacementPresent := True;
AddressDisplacementSize := 4;
AddressDisplacementOffset := SIBOffset + 1;
AddressDisplacement := GetDWord(Code, AddressDisplacementOffset);
end;
end;
end;
// Получаем флаги опкода:
case Instruction.OpcodeSize of
1: Instruction.OpcodeFlags := OneByteOpcodeFlags[Instruction.FullOpcode];
2: Instruction.OpcodeFlags := TwoBytesOpcodeFlags[Instruction.FullOpcode];
//3: ...
end;
// Получаем Immediate Data:
if IsNumberContains(Instruction.OpcodeFlags, OP_DATA_I8) then
begin
Instruction.ImmediateDataPresent := True;
Instruction.ImmediateDataOffset := Instruction.OpcodeOffset +
Instruction.OpcodeSize +
Byte(Instruction.ModRMPresent) +
Byte(Instruction.SIBPresent) +
Instruction.AddressDisplacementSize;
Instruction.ImmediateDataSize := 1;
Instruction.ImmediateData := GetByte(Code, Instruction.ImmediateDataOffset);
end;
if IsNumberContains(Instruction.OpcodeFlags, OP_DATA_I16) then
begin
Instruction.ImmediateDataPresent := True;
Instruction.ImmediateDataOffset := Instruction.OpcodeOffset +
Instruction.OpcodeSize +
Byte(Instruction.ModRMPresent) +
Byte(Instruction.SIBPresent) +
Instruction.AddressDisplacementSize;
Instruction.ImmediateDataSize := 2;
Instruction.ImmediateData := GetWord(Code, Instruction.ImmediateDataOffset);
end;
if IsNumberContains(Instruction.OpcodeFlags, OP_DATA_I16_I32) then
begin
Instruction.ImmediateDataPresent := True;
Instruction.ImmediateDataOffset := Instruction.OpcodeOffset +
Instruction.OpcodeSize +
Byte(Instruction.ModRMPresent) +
Byte(Instruction.SIBPresent) +
Instruction.AddressDisplacementSize;
if (Instruction.LegacyPrefixes[GRP1] = OperandSizeOverridePrefix) or
(Instruction.LegacyPrefixes[GRP2] = OperandSizeOverridePrefix) or
(Instruction.LegacyPrefixes[GRP3] = OperandSizeOverridePrefix) or
(Instruction.LegacyPrefixes[GRP4] = OperandSizeOverridePrefix)
then
begin
Instruction.ImmediateDataSize := 2;
Instruction.ImmediateData := GetWord(Code, Instruction.ImmediateDataOffset);
end
else
begin
Instruction.ImmediateDataSize := 4;
Instruction.ImmediateData := GetDWord(Code, Instruction.ImmediateDataOffset);
end;
end;
if IsNumberContains(Instruction.OpcodeFlags, OP_DATA_I16_I32_I64) then
begin
Instruction.ImmediateDataPresent := True;
Instruction.ImmediateDataOffset := Instruction.OpcodeOffset +
Instruction.OpcodeSize +
Byte(Instruction.ModRMPresent) +
Byte(Instruction.SIBPresent) +
Instruction.AddressDisplacementSize;
if (Instruction.LegacyPrefixes[GRP1] = OperandSizeOverridePrefix) or
(Instruction.LegacyPrefixes[GRP2] = OperandSizeOverridePrefix) or
(Instruction.LegacyPrefixes[GRP3] = OperandSizeOverridePrefix) or
(Instruction.LegacyPrefixes[GRP4] = OperandSizeOverridePrefix)
then
begin
if Instruction.REXPresent then
begin
Instruction.ImmediateDataSize := 4;
Instruction.ImmediateData := GetDWord(Code, Instruction.ImmediateDataOffset);
end
else
begin
Instruction.ImmediateDataSize := 2;
Instruction.ImmediateData := GetWord(Code, Instruction.ImmediateDataOffset);
end;
end
else
begin
if Instruction.REXPresent then
begin
Instruction.ImmediateDataSize := 8;
Instruction.ImmediateData := GetDWord(Code, Instruction.ImmediateDataOffset);
end
else
begin
Instruction.ImmediateDataSize := 4;
Instruction.ImmediateData := GetWord(Code, Instruction.ImmediateDataOffset);
end;
end;
end;
// Выводим результат:
Result := Result +
Instruction.PrefixesSize +
Instruction.OpcodeSize +
Instruction.AddressDisplacementSize +
Instruction.ImmediateDataSize;
end;
end.
// Таблицы позаимствованы из проекта libsplice (автор - Vol4ok)
const
OP_NONE = $00;
OP_INVALID = $80;
OP_DATA_I8 = $01;
OP_DATA_I16 = $02;
OP_DATA_I16_I32 = $04;
OP_DATA_I16_I32_I64 = $08;
OP_EXTENDED = $10;
OP_RELATIVE = $20;
OP_MODRM = $40;
OP_PREFIX = $80;
OneByteOpcodeFlags: array [0..255] of Byte = (
(* 00 *) OP_MODRM,
(* 01 *) OP_MODRM,
(* 02 *) OP_MODRM,
(* 03 *) OP_MODRM,
(* 04 *) OP_DATA_I8,
(* 05 *) OP_DATA_I16_I32,
(* 06 *) OP_NONE,
(* 07 *) OP_NONE,
(* 08 *) OP_MODRM,
(* 09 *) OP_MODRM,
(* 0A *) OP_MODRM,
(* 0B *) OP_MODRM,
(* 0C *) OP_DATA_I8,
(* 0D *) OP_DATA_I16_I32,
(* 0E *) OP_NONE,
(* 0F *) OP_NONE,
(* 10 *) OP_MODRM,
(* 11 *) OP_MODRM,
(* 12 *) OP_MODRM,
(* 13 *) OP_MODRM,
(* 14 *) OP_DATA_I8,
(* 15 *) OP_DATA_I16_I32,
(* 16 *) OP_NONE,
(* 17 *) OP_NONE,
(* 18 *) OP_MODRM,
(* 19 *) OP_MODRM,
(* 1A *) OP_MODRM,
(* 1B *) OP_MODRM,
(* 1C *) OP_DATA_I8,
(* 1D *) OP_DATA_I16_I32,
(* 1E *) OP_NONE,
(* 1F *) OP_NONE,
(* 20 *) OP_MODRM,
(* 21 *) OP_MODRM,
(* 22 *) OP_MODRM,
(* 23 *) OP_MODRM,
(* 24 *) OP_DATA_I8,
(* 25 *) OP_DATA_I16_I32,
(* 26 *) OP_PREFIX,
(* 27 *) OP_NONE,
(* 28 *) OP_MODRM,
(* 29 *) OP_MODRM,
(* 2A *) OP_MODRM,
(* 2B *) OP_MODRM,
(* 2C *) OP_DATA_I8,
(* 2D *) OP_DATA_I16_I32,
(* 2E *) OP_PREFIX,
(* 2F *) OP_NONE,
(* 30 *) OP_MODRM,
(* 31 *) OP_MODRM,
(* 32 *) OP_MODRM,
(* 33 *) OP_MODRM,
(* 34 *) OP_DATA_I8,
(* 35 *) OP_DATA_I16_I32,
(* 36 *) OP_PREFIX,
(* 37 *) OP_NONE,
(* 38 *) OP_MODRM,
(* 39 *) OP_MODRM,
(* 3A *) OP_MODRM,
(* 3B *) OP_MODRM,
(* 3C *) OP_DATA_I8,
(* 3D *) OP_DATA_I16_I32,
(* 3E *) OP_PREFIX,
(* 3F *) OP_NONE,
(* 40 *) OP_NONE,
(* 41 *) OP_NONE,
(* 42 *) OP_NONE,
(* 43 *) OP_NONE,
(* 44 *) OP_NONE,
(* 45 *) OP_NONE,
(* 46 *) OP_NONE,
(* 47 *) OP_NONE,
(* 48 *) OP_NONE,
(* 49 *) OP_NONE,
(* 4A *) OP_NONE,
(* 4B *) OP_NONE,
(* 4C *) OP_NONE,
(* 4D *) OP_NONE,
(* 4E *) OP_NONE,
(* 4F *) OP_NONE,
(* 50 *) OP_NONE,
(* 51 *) OP_NONE,
(* 52 *) OP_NONE,
(* 53 *) OP_NONE,
(* 54 *) OP_NONE,
(* 55 *) OP_NONE,
(* 56 *) OP_NONE,
(* 57 *) OP_NONE,
(* 58 *) OP_NONE,
(* 59 *) OP_NONE,
(* 5A *) OP_NONE,
(* 5B *) OP_NONE,
(* 5C *) OP_NONE,
(* 5D *) OP_NONE,
(* 5E *) OP_NONE,
(* 5F *) OP_NONE,
(* 60 *) OP_NONE,
(* 61 *) OP_NONE,
(* 62 *) OP_MODRM,
(* 63 *) OP_MODRM,
(* 64 *) OP_PREFIX,
(* 65 *) OP_PREFIX,
(* 66 *) OP_PREFIX,
(* 67 *) OP_PREFIX,
(* 68 *) OP_DATA_I16_I32,
(* 69 *) OP_MODRM or OP_DATA_I16_I32,
(* 6A *) OP_DATA_I8,
(* 6B *) OP_MODRM or OP_DATA_I8,
(* 6C *) OP_NONE,
(* 6D *) OP_NONE,
(* 6E *) OP_NONE,
(* 6F *) OP_NONE,
(* 70 *) OP_RELATIVE or OP_DATA_I8,
(* 71 *) OP_RELATIVE or OP_DATA_I8,
(* 72 *) OP_RELATIVE or OP_DATA_I8,
(* 73 *) OP_RELATIVE or OP_DATA_I8,
(* 74 *) OP_RELATIVE or OP_DATA_I8,
(* 75 *) OP_RELATIVE or OP_DATA_I8,
(* 76 *) OP_RELATIVE or OP_DATA_I8,
(* 77 *) OP_RELATIVE or OP_DATA_I8,
(* 78 *) OP_RELATIVE or OP_DATA_I8,
(* 79 *) OP_RELATIVE or OP_DATA_I8,
(* 7A *) OP_RELATIVE or OP_DATA_I8,
(* 7B *) OP_RELATIVE or OP_DATA_I8,
(* 7C *) OP_RELATIVE or OP_DATA_I8,
(* 7D *) OP_RELATIVE or OP_DATA_I8,
(* 7E *) OP_RELATIVE or OP_DATA_I8,
(* 7F *) OP_RELATIVE or OP_DATA_I8,
(* 80 *) OP_MODRM or OP_DATA_I8,
(* 81 *) OP_MODRM or OP_DATA_I16_I32,
(* 82 *) OP_MODRM or OP_DATA_I8,
(* 83 *) OP_MODRM or OP_DATA_I8,
(* 84 *) OP_MODRM,
(* 85 *) OP_MODRM,
(* 86 *) OP_MODRM,
(* 87 *) OP_MODRM,
(* 88 *) OP_MODRM,
(* 89 *) OP_MODRM,
(* 8A *) OP_MODRM,
(* 8B *) OP_MODRM,
(* 8C *) OP_MODRM,
(* 8D *) OP_MODRM,
(* 8E *) OP_MODRM,
(* 8F *) OP_MODRM,
(* 90 *) OP_NONE,
(* 91 *) OP_NONE,
(* 92 *) OP_NONE,
(* 93 *) OP_NONE,
(* 94 *) OP_NONE,
(* 95 *) OP_NONE,
(* 96 *) OP_NONE,
(* 97 *) OP_NONE,
(* 98 *) OP_NONE,
(* 99 *) OP_NONE,
(* 9A *) OP_DATA_I16 or OP_DATA_I16_I32,
(* 9B *) OP_NONE,
(* 9C *) OP_NONE,
(* 9D *) OP_NONE,
(* 9E *) OP_NONE,
(* 9F *) OP_NONE,
(* A0 *) OP_DATA_I8,
(* A1 *) OP_DATA_I16_I32_I64,
(* A2 *) OP_DATA_I8,
(* A3 *) OP_DATA_I16_I32_I64,
(* A4 *) OP_NONE,
(* A5 *) OP_NONE,
(* A6 *) OP_NONE,
(* A7 *) OP_NONE,
(* A8 *) OP_DATA_I8,
(* A9 *) OP_DATA_I16_I32,
(* AA *) OP_NONE,
(* AB *) OP_NONE,
(* AC *) OP_NONE,
(* AD *) OP_NONE,
(* AE *) OP_NONE,
(* AF *) OP_NONE,
(* B0 *) OP_DATA_I8,
(* B1 *) OP_DATA_I8,
(* B2 *) OP_DATA_I8,
(* B3 *) OP_DATA_I8,
(* B4 *) OP_DATA_I8,
(* B5 *) OP_DATA_I8,
(* B6 *) OP_DATA_I8,
(* B7 *) OP_DATA_I8,
(* B8 *) OP_DATA_I16_I32_I64,
(* B9 *) OP_DATA_I16_I32_I64,
(* BA *) OP_DATA_I16_I32_I64,
(* BB *) OP_DATA_I16_I32_I64,
(* BC *) OP_DATA_I16_I32_I64,
(* BD *) OP_DATA_I16_I32_I64,
(* BE *) OP_DATA_I16_I32_I64,
(* BF *) OP_DATA_I16_I32_I64,
(* C0 *) OP_MODRM or OP_DATA_I8,
(* C1 *) OP_MODRM or OP_DATA_I8,
(* C2 *) OP_DATA_I16,
(* C3 *) OP_NONE,
(* C4 *) OP_MODRM,
(* C5 *) OP_MODRM,
(* C6 *) OP_MODRM or OP_DATA_I8,
(* C7 *) OP_MODRM or OP_DATA_I16_I32,
(* C8 *) OP_DATA_I8 or OP_DATA_I16,
(* C9 *) OP_NONE,
(* CA *) OP_DATA_I16,
(* CB *) OP_NONE,
(* CC *) OP_NONE,
(* CD *) OP_DATA_I8,
(* CE *) OP_NONE,
(* CF *) OP_NONE,
(* D0 *) OP_MODRM,
(* D1 *) OP_MODRM,
(* D2 *) OP_MODRM,
(* D3 *) OP_MODRM,
(* D4 *) OP_DATA_I8,
(* D5 *) OP_DATA_I8,
(* D6 *) OP_NONE,
(* D7 *) OP_NONE,
(* D8 *) OP_MODRM,
(* D9 *) OP_MODRM,
(* DA *) OP_MODRM,
(* DB *) OP_MODRM,
(* DC *) OP_MODRM,
(* DD *) OP_MODRM,
(* DE *) OP_MODRM,
(* DF *) OP_MODRM,
(* E0 *) OP_RELATIVE or OP_DATA_I8,
(* E1 *) OP_RELATIVE or OP_DATA_I8,
(* E2 *) OP_RELATIVE or OP_DATA_I8,
(* E3 *) OP_RELATIVE or OP_DATA_I8,
(* E4 *) OP_DATA_I8,
(* E5 *) OP_DATA_I8,
(* E6 *) OP_DATA_I8,
(* E7 *) OP_DATA_I8,
(* E8 *) OP_RELATIVE or OP_DATA_I16_I32,
(* E9 *) OP_RELATIVE or OP_DATA_I16_I32,
(* EA *) OP_DATA_I16 or OP_DATA_I16_I32,
(* EB *) OP_RELATIVE or OP_DATA_I8,
(* EC *) OP_NONE,
(* ED *) OP_NONE,
(* EE *) OP_NONE,
(* EF *) OP_NONE,
(* F0 *) OP_PREFIX,
(* F1 *) OP_NONE,
(* F2 *) OP_PREFIX,
(* F3 *) OP_PREFIX,
(* F4 *) OP_NONE,
(* F5 *) OP_NONE,
(* F6 *) OP_MODRM,
(* F7 *) OP_MODRM,
(* F8 *) OP_NONE,
(* F9 *) OP_NONE,
(* FA *) OP_NONE,
(* FB *) OP_NONE,
(* FC *) OP_NONE,
(* FD *) OP_NONE,
(* FE *) OP_MODRM,
(* FF *) OP_MODRM
);
TwoBytesOpcodeFlags: array [$F00..$FFF] of Byte = (
(* 0F00 *) OP_MODRM,
(* 0F01 *) OP_MODRM,
(* 0F02 *) OP_MODRM,
(* 0F03 *) OP_MODRM,
(* 0F04 *) OP_INVALID,
(* 0F05 *) OP_NONE,
(* 0F06 *) OP_NONE,
(* 0F07 *) OP_NONE,
(* 0F08 *) OP_NONE,
(* 0F09 *) OP_NONE,
(* 0F0A *) OP_INVALID,
(* 0F0B *) OP_NONE,
(* 0F0C *) OP_INVALID,
(* 0F0D *) OP_MODRM,
(* 0F0E *) OP_INVALID,
(* 0F0F *) OP_MODRM or OP_DATA_I8, //3Dnow
(* 0F10 *) OP_MODRM,
(* 0F11 *) OP_MODRM,
(* 0F12 *) OP_MODRM,
(* 0F13 *) OP_MODRM,
(* 0F14 *) OP_MODRM,
(* 0F15 *) OP_MODRM,
(* 0F16 *) OP_MODRM,
(* 0F17 *) OP_MODRM,
(* 0F18 *) OP_MODRM,
(* 0F19 *) OP_INVALID,
(* 0F1A *) OP_INVALID,
(* 0F1B *) OP_INVALID,
(* 0F1C *) OP_INVALID,
(* 0F1D *) OP_INVALID,
(* 0F1E *) OP_INVALID,
(* 0F1F *) OP_NONE,
(* 0F20 *) OP_MODRM,
(* 0F21 *) OP_MODRM,
(* 0F22 *) OP_MODRM,
(* 0F23 *) OP_MODRM,
(* 0F24 *) OP_MODRM or OP_EXTENDED, //SSE5
(* 0F25 *) OP_INVALID,
(* 0F26 *) OP_MODRM,
(* 0F27 *) OP_INVALID,
(* 0F28 *) OP_MODRM,
(* 0F29 *) OP_MODRM,
(* 0F2A *) OP_MODRM,
(* 0F2B *) OP_MODRM,
(* 0F2C *) OP_MODRM,
(* 0F2D *) OP_MODRM,
(* 0F2E *) OP_MODRM,
(* 0F2F *) OP_MODRM,
(* 0F30 *) OP_NONE,
(* 0F31 *) OP_NONE,
(* 0F32 *) OP_NONE,
(* 0F33 *) OP_NONE,
(* 0F34 *) OP_NONE,
(* 0F35 *) OP_NONE,
(* 0F36 *) OP_INVALID,
(* 0F37 *) OP_NONE,
(* 0F38 *) OP_MODRM or OP_EXTENDED,
(* 0F39 *) OP_INVALID,
(* 0F3A *) OP_MODRM or OP_EXTENDED or OP_DATA_I8,
(* 0F3B *) OP_INVALID,
(* 0F3C *) OP_INVALID,
(* 0F3D *) OP_INVALID,
(* 0F3E *) OP_INVALID,
(* 0F3F *) OP_INVALID,
(* 0F40 *) OP_MODRM,
(* 0F41 *) OP_MODRM,
(* 0F42 *) OP_MODRM,
(* 0F43 *) OP_MODRM,
(* 0F44 *) OP_MODRM,
(* 0F45 *) OP_MODRM,
(* 0F46 *) OP_MODRM,
(* 0F47 *) OP_MODRM,
(* 0F48 *) OP_MODRM,
(* 0F49 *) OP_MODRM,
(* 0F4A *) OP_MODRM,
(* 0F4B *) OP_MODRM,
(* 0F4C *) OP_MODRM,
(* 0F4D *) OP_MODRM,
(* 0F4E *) OP_MODRM,
(* 0F4F *) OP_MODRM,
(* 0F50 *) OP_MODRM,
(* 0F51 *) OP_MODRM,
(* 0F52 *) OP_MODRM,
(* 0F53 *) OP_MODRM,
(* 0F54 *) OP_MODRM,
(* 0F55 *) OP_MODRM,
(* 0F56 *) OP_MODRM,
(* 0F57 *) OP_MODRM,
(* 0F58 *) OP_MODRM,
(* 0F59 *) OP_MODRM,
(* 0F5A *) OP_MODRM,
(* 0F5B *) OP_MODRM,
(* 0F5C *) OP_MODRM,
(* 0F5D *) OP_MODRM,
(* 0F5E *) OP_MODRM,
(* 0F5F *) OP_MODRM,
(* 0F60 *) OP_MODRM,
(* 0F61 *) OP_MODRM,
(* 0F62 *) OP_MODRM,
(* 0F63 *) OP_MODRM,
(* 0F64 *) OP_MODRM,
(* 0F65 *) OP_MODRM,
(* 0F66 *) OP_MODRM,
(* 0F67 *) OP_MODRM,
(* 0F68 *) OP_MODRM,
(* 0F69 *) OP_MODRM,
(* 0F6A *) OP_MODRM,
(* 0F6B *) OP_MODRM,
(* 0F6C *) OP_MODRM,
(* 0F6D *) OP_MODRM,
(* 0F6E *) OP_MODRM,
(* 0F6F *) OP_MODRM,
(* 0F70 *) OP_MODRM or OP_DATA_I8,
(* 0F71 *) OP_MODRM or OP_DATA_I8,
(* 0F72 *) OP_MODRM or OP_DATA_I8,
(* 0F73 *) OP_MODRM or OP_DATA_I8,
(* 0F74 *) OP_MODRM,
(* 0F75 *) OP_MODRM,
(* 0F76 *) OP_MODRM,
(* 0F77 *) OP_NONE,
(* 0F78 *) OP_MODRM,
(* 0F79 *) OP_MODRM,
(* 0F7A *) OP_INVALID,
(* 0F7B *) OP_INVALID,
(* 0F7C *) OP_MODRM,
(* 0F7D *) OP_MODRM,
(* 0F7E *) OP_MODRM,
(* 0F7F *) OP_MODRM,
(* 0F80 *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F81 *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F82 *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F83 *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F84 *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F85 *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F86 *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F87 *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F88 *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F89 *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F8A *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F8B *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F8C *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F8D *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F8E *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F8F *) OP_RELATIVE or OP_DATA_I16_I32,
(* 0F90 *) OP_MODRM,
(* 0F91 *) OP_MODRM,
(* 0F92 *) OP_MODRM,
(* 0F93 *) OP_MODRM,
(* 0F94 *) OP_MODRM,
(* 0F95 *) OP_MODRM,
(* 0F96 *) OP_MODRM,
(* 0F97 *) OP_MODRM,
(* 0F98 *) OP_MODRM,
(* 0F99 *) OP_MODRM,
(* 0F9A *) OP_MODRM,
(* 0F9B *) OP_MODRM,
(* 0F9C *) OP_MODRM,
(* 0F9D *) OP_MODRM,
(* 0F9E *) OP_MODRM,
(* 0F9F *) OP_MODRM,
(* 0FA0 *) OP_NONE,
(* 0FA1 *) OP_NONE,
(* 0FA2 *) OP_NONE,
(* 0FA3 *) OP_MODRM,
(* 0FA4 *) OP_MODRM or OP_DATA_I8,
(* 0FA5 *) OP_MODRM,
(* 0FA6 *) OP_INVALID,
(* 0FA7 *) OP_INVALID,
(* 0FA8 *) OP_NONE,
(* 0FA9 *) OP_NONE,
(* 0FAA *) OP_NONE,
(* 0FAB *) OP_MODRM,
(* 0FAC *) OP_MODRM or OP_DATA_I8,
(* 0FAD *) OP_MODRM,
(* 0FAE *) OP_MODRM,
(* 0FAF *) OP_MODRM,
(* 0FB0 *) OP_MODRM,
(* 0FB1 *) OP_MODRM,
(* 0FB2 *) OP_MODRM,
(* 0FB3 *) OP_MODRM,
(* 0FB4 *) OP_MODRM,
(* 0FB5 *) OP_MODRM,
(* 0FB6 *) OP_MODRM,
(* 0FB7 *) OP_MODRM,
(* 0FB8 *) OP_MODRM,
(* 0FB9 *) OP_MODRM,
(* 0FBA *) OP_MODRM or OP_DATA_I8,
(* 0FBB *) OP_MODRM,
(* 0FBC *) OP_MODRM,
(* 0FBD *) OP_MODRM,
(* 0FBE *) OP_MODRM,
(* 0FBF *) OP_MODRM,
(* 0FC0 *) OP_MODRM,
(* 0FC1 *) OP_MODRM,
(* 0FC2 *) OP_MODRM or OP_DATA_I8,
(* 0FC3 *) OP_MODRM,
(* 0FC4 *) OP_MODRM or OP_DATA_I8,
(* 0FC5 *) OP_MODRM or OP_DATA_I8,
(* 0FC6 *) OP_MODRM or OP_DATA_I8,
(* 0FC7 *) OP_MODRM,
(* 0FC8 *) OP_NONE,
(* 0FC9 *) OP_NONE,
(* 0FCA *) OP_NONE,
(* 0FCB *) OP_NONE,
(* 0FCC *) OP_NONE,
(* 0FCD *) OP_NONE,
(* 0FCE *) OP_NONE,
(* 0FCF *) OP_NONE,
(* 0FD0 *) OP_MODRM,
(* 0FD1 *) OP_MODRM,
(* 0FD2 *) OP_MODRM,
(* 0FD3 *) OP_MODRM,
(* 0FD4 *) OP_MODRM,
(* 0FD5 *) OP_MODRM,
(* 0FD6 *) OP_MODRM,
(* 0FD7 *) OP_MODRM,
(* 0FD8 *) OP_MODRM,
(* 0FD9 *) OP_MODRM,
(* 0FDA *) OP_MODRM,
(* 0FDB *) OP_MODRM,
(* 0FDC *) OP_MODRM,
(* 0FDD *) OP_MODRM,
(* 0FDE *) OP_MODRM,
(* 0FDF *) OP_MODRM,
(* 0FE0 *) OP_MODRM,
(* 0FE1 *) OP_MODRM,
(* 0FE2 *) OP_MODRM,
(* 0FE3 *) OP_MODRM,
(* 0FE4 *) OP_MODRM,
(* 0FE5 *) OP_MODRM,
(* 0FE6 *) OP_MODRM,
(* 0FE7 *) OP_MODRM,
(* 0FE8 *) OP_MODRM,
(* 0FE9 *) OP_MODRM,
(* 0FEA *) OP_MODRM,
(* 0FEB *) OP_MODRM,
(* 0FEC *) OP_MODRM,
(* 0FED *) OP_MODRM,
(* 0FEE *) OP_MODRM,
(* 0FEF *) OP_MODRM,
(* 0FF0 *) OP_MODRM,
(* 0FF1 *) OP_MODRM,
(* 0FF2 *) OP_MODRM,
(* 0FF3 *) OP_MODRM,
(* 0FF4 *) OP_MODRM,
(* 0FF5 *) OP_MODRM,
(* 0FF6 *) OP_MODRM,
(* 0FF7 *) OP_MODRM,
(* 0FF8 *) OP_MODRM,
(* 0FF9 *) OP_MODRM,
(* 0FFA *) OP_MODRM,
(* 0FFB *) OP_MODRM,
(* 0FFC *) OP_MODRM,
(* 0FFD *) OP_MODRM,
(* 0FFE *) OP_MODRM,
(* 0FFF *) OP_INVALID
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment