Last active
February 16, 2019 21:06
-
-
Save HoShiMin/0dfa6f30b24baefa0804 to your computer and use it in GitHub Desktop.
Минималистичный и очень быстрый дизассемблер длин
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Таблицы позаимствованы из проекта 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