This file is indexed.

/usr/include/distorm64/instructions.h is in libdistorm64-dev 1.7.30-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
/*
instructions.h

Copyright (C) 2003-2008 Gil Dabah, http://ragestorm.net/distorm/
This library is licensed under the BSD license. See the file COPYING.
*/


#ifndef INSTRUCTIONS_H
#define INSTRUCTIONS_H

#include "../config.h"

#include "decoder.h"
#include "prefix.h"

/*
 * Operand type possibilities:
 * Note "_FULL" suffix indicates to decode the operand as 16 bits or 32 bits depends on DecodeType -
 * actually, it depends on the decoding mode, unless there's an operand/address size prefix.
 * For example, the code: 33 c0 could be decoded/executed as XOR AX, AX or XOR EAX, EAX.
 */
typedef enum OpType {
	/* No operand is set */
	OT_NONE = 0,

	/* Read a byte(8 bits) immediate */
	OT_IMM8,
	/* Force a read of a word(16 bits) immediate, used by ret only */
	OT_IMM16,
	/* Read a word/dword immediate */
	OT_IMM_FULL,
	/* Read a double-word(32 bits) immediate */
	OT_IMM32,

	/* Special immediate for two instructions, AAM, AAD which will output the byte only if it's not 0xa (base 10) */
	OT_IMM_AADM,

	/* Read a signed extended byte(8 bits) immediate */
	OT_SEIMM8,

	/* Use a 8bit register */
	OT_REG8,
	/* Use a 16bit register */
	OT_REG16,
	/* Use a 16/32/64bit register */
	OT_REG_FULL,
	/* Use a 32bit register */
	OT_REG32,
	/* MOVSXD uses 64 bits register */
	OT_REG64,
	/*
	 * If used with REX the reg operand size becomes 64 bits, otherwise 32 bits.
	 * VMX instructions are promoted automatically without a REX prefix.
	 */
	OT_REG32_64,
	/* Extract a 32bit register from the RM field, used for instructions with register operands only */
	OT_REG32_RM,
	/* Used only by MOV CR/DR(n). Promoted with REX onlly. */
	OT_FREG32_64_RM,

	/* Use or read (indirection) a 8bit register or immediate byte */
	OT_RM8,
	/* Some instructions force 16 bits (mov sreg, rm16) */
	OT_RM16,
	/* Use or read a 16/32/64bit register or immediate word/dword/qword */
	OT_RM_FULL,
	/* Use or read a 32bit register or immediate dword */
	OT_RM32,
	/*
	 * 32 or 64 bits (with REX) operand size indirection memory operand.
	 * Some instructions are promoted automatically without a REX prefix.
	 */
	OT_RM32_64,
	/* 16 or 32 bits RM. This is used only with MOVZXD instruction in 64bits. */
	OT_RM16_32,
	/* Same as OT_RMXX but POINTS to 16 bits [cannot use GENERAL-PURPOSE REG!] */
	OT_FPUM16,
	/* Same as OT_RMXX but POINTS to 32 bits (single precision) [cannot use GENERAL-PURPOSE REG!] */
	OT_FPUM32,
	/* Same as OT_RMXX but POINTS to 64 bits (double precision) [cannot use GENERAL-PURPOSE REG!] */
	OT_FPUM64,
	/* Same as OT_RMXX but POINTS to 80 bits (extended precision) [cannot use GENERAL-PURPOSE REG!] */
	OT_FPUM80,

	/*
	 * Special operand type for SSE4 where the ModR/M might
	 * be a 32 bits register or 8 bits memory indirection operand.
	 */
	OT_R32_M8,
	/*
	 * Special ModR/M for PINSRW, which need a 16 bits memory operand or 32 bits register.
	 * In 16 bits decoding mode R32 becomes R16, operand size cannot affect this.
	 */
	OT_R32_M16,
	/*
	 * Special type for SSE4, ModR/M might be a 32 bits or 64 bits (with REX) register or
	 * a 8 bits memory indirection operand.
	 */
	OT_R32_64_M8,
	/*
	 * Special type for SSE4, ModR/M might be a 32 bits or 64 bits (with REX) register or
	 * a 16 bits memory indirection operand.
	 */
	OT_R32_64_M16,
	/*
	 * Special operand type for MOV reg16/32/64/mem16, segReg 8C /r. and SMSW.
	 * It supports all decoding modes, but if used as a memory indirection it's a 16 bit ModR/M indirection.
	 */
	OT_RFULL_M16,

	/* Use a control register */
	OT_CREG,
	/* Use a debug register */
	OT_DREG,
	/* Use a segment register */
	OT_SREG,
	/*
	 * SEG is encoded in the flags of the opcode itself!
	 * This is used for specific "push SS" where SS is a segment where
	 * each "push SS" has an absolutely different opcode byte.
	 * We need this to detect whether an operand size prefix is used.
	 */
	OT_SEG,
	
	/* Use AL */
	OT_ACC8,
	/* Use AX (FSTSW) */
	OT_ACC16,
	/* Use AX/EAX/RAX */
	OT_ACC_FULL,
	/* Use AX/EAX, no REX is possible for RAX, used only with IN/OUT which don't support 64 bit registers */
	OT_ACC_FULL_NOT64,

	/*
	 * Read one word (seg), and a word/dword/qword (depends on operand size) from memory.
	 * JMP FAR [EBX] means EBX point to 16:32 ptr.
	 */
	OT_MEM16_FULL,
	/* Read one word (seg) and a word/dword/qword (depends on operand size), usually SEG:OFF, JMP 1234:1234 */
	OT_PTR16_FULL,
	/* Read one word (limit) and a dword/qword (limit) (depends on operand size), used by SGDT, SIDT, LGDT, LIDT. */
	OT_MEM16_3264,

	/* Read a byte(8 bits) immediate and calculate it relatively to the current offset of the instruction being decoded */
	OT_RELCB,
	/* Read a word/dword immediate and calculate it relatively to the current offset of the instruction being decoded */
	OT_RELC_FULL,

	/* Use general memory indirection, with varying sizes: */
	OT_MEM,
	OT_MEM32,
	/* Memory dereference for MOVNTI, either 32 or 64 bits (with REX). */
	OT_MEM32_64,
	OT_MEM64,
	OT_MEM128,
	/* Used for cmpxchg8b/16b. */
	OT_MEM64_128,

	/* Read an immediate as an absolute address, size is known by instruction, used by MOV (offset) only */
	OT_MOFFS,
	/* Use an immediate of 1, as for SHR R/M, 1 */
	OT_CONST1,
	/* Use CL, as for SHR R/M, CL */
	OT_REGCL,

	/*
	 * Instruction-Block for one byte long instructions, used by INC/DEC/PUSH/POP/XCHG,
	 * REG is extracted from the value of opcode
	 * Use a 8bit register
	 */
	OT_IB_RB,
	/* Use a 32 or 64bit (with REX) register, used by BSWAP */
	OT_IB_R_DW_QW,
	/* Use a 16/32/64bit register */
	OT_IB_R_FULL,

	/* Use [(r)SI] as INDIRECTION, for repeatable instructions */
	OT_REGI_ESI,
	/* Use [(r)DI] as INDIRECTION, for repeatable instructions */
	OT_REGI_EDI,
	/* Use [(r)BX + AL] as INDIRECTIOM, used by XLAT only */
	OT_REGI_EBXAL,
	/* Use [(r)AX] as INDIRECTION, used by AMD's SVM instructions */
	OT_REGI_EAX,
	/* Use DX, as for OUTS DX, BYTE [SI] */
	OT_REGDX,
	/* Use ECX in INVLPGA instruction */
	OT_REGECX,

	/* FPU registers: */
	OT_FPU_SI, /* ST(i) */
	OT_FPU_SSI, /* ST(0), ST(i) */
	OT_FPU_SIS, /* ST(i), ST(0) */

	/* MMX registers: */
	OT_MM,
	/* Extract the MMX register from the RM bits this time (used when the REG bits are used for opcode extension) */
	OT_MM_RM,
	/* ModR/M points to 32 bits MMX variable */
	OT_MM32,
	/* ModR/M points to 32 bits MMX variable */
	OT_MM64,

	/* SSE registers: */
	OT_XMM,
	/* Extract the SSE register from the RM bits this time (used when the REG bits are used for opcode extension) */
	OT_XMM_RM,
	/* ModR/M points to 16 bits SSE variable */
	OT_XMM16,
	/* ModR/M points to 32 bits SSE variable */
	OT_XMM32,
	/* ModR/M points to 64 bits SSE variable */
	OT_XMM64,
	/* ModR/M points to 128 bits SSE variable */
	OT_XMM128,
	/* Implied XMM0 register as operand, used in SSE4. */
	OT_REGXMM0,

	/*
	 * DUMMY for cases like CALL WORD [BX+DI], we would like to omit this "WORD". It's useless,
	 * because the DWORD/WORD/BYTE mechanism is being done automatically, we need some way to disable it in such cases...
	 */
	OT_DUMMY
} _OpType;

/* Flags for instruction: */

/* Empty flags indicator: */
#define INST_FLAGS_NONE ((_iflags)-1)

/*
 * Explicitly define that the instruction doesn't require a ModRM byte.
 * NOTE its value is 0! you can't do much with it, it is used for instructions that for sure don't use the ModR/M byte.
 */
#define INST_EXCLUDE_MODRM (0)
/* The instruction we are going to decode has a ModR/M byte. */
#define INST_INCLUDE_MODRM (1)
/* Special treatment for instructions which are in the divided-category but still needs the whole byte for ModR/M... */
#define INST_NOT_DIVIDED (1 << 1)
/*
 * Used explicitly in repeatable instructions,
 * which needs a suffix letter in their mnemonic to specify operation-size (depend on operands).
 */
#define INST_16BITS (1 << 2)
/* If the opcode is supported by 80286 and upper models (16/32 bits). */
#define INST_32BITS (1 << 3)
/*
 * Prefix flags (4 types: lock/rep, seg override, addr-size, oper-size)
 * There are several specific instructions that can follow LOCK prefix,
 * note that they must be using a memory operand form, otherwise they generate an exception.
 */
#define INST_PRE_LOCK (1 << 4)
/* REPNZ prefix for string instructions only - means an instruction can follow it. */
#define INST_PRE_REPNZ (1 << 5)
/* REP prefix for string instructions only - means an instruction can follow it. */
#define INST_PRE_REP (1 << 6)
/* CS override prefix. */
#define INST_PRE_CS (1 << 7)
/* SS override prefix. */
#define INST_PRE_SS (1 << 8)
/* DS override prefix. */
#define INST_PRE_DS (1 << 9)
/* ES override prefix. */
#define INST_PRE_ES (1 << 10)
/* FS override prefix. Funky Segment :) */
#define INST_PRE_FS (1 << 11)
/* GS override prefix. Groovy Segment, of course not, duh ! */
#define INST_PRE_GS (1 << 12)
/* Switch operand size from 32 to 16 and vice versa. */
#define INST_PRE_OP_SIZE (1 << 13)
/* Switch address size from 32 to 16 and vice versa. */
#define INST_PRE_ADDR_SIZE (1 << 14)
/* Native instructions which needs suffix letter to indicate their operation-size (and don't depend on operands). */
#define INST_NATIVE (1 << 15)
/* Use extended mnemonic, means it's an _InstInfoEx structure, which contains another mnemonic for 32 bits specifically. */
#define INST_USE_EXMNEMONIC (1 << 16)
/* Use third operand, means it's an _InstInfoEx structure, which contains another operand for special instructions. */
#define INST_USE_OP3 (1 << 17)
/* Use fourth operand, means it's an _InstInfoEx structure, which contains another operand for special instructions. */
#define INST_USE_OP4 (1 << 18)
/* The instruction's mnemonic depends on the mod value of the ModR/M byte (mod=11, mod!=11). */
#define INST_MODRM_BASED (1 << 19)
/* The instruction uses a ModR/M byte which the MOD must be 11 (for registers operands only). */
#define INST_MODRR (1 << 20)
/* The way of 3DNow! instructions are built, we have to handle their locating specially. Suffix imm8 tells which instruction it is. */
#define INST_3DNOW_FETCH (1 << 21)
/* The instruction needs two suffixes, one for the comparison type (imm8) and the second for its operation size indication (second mnemonic). */
#define INST_PSEUDO_OPCODE (1 << 22)
/* Invalid instruction at 64 bits decoding mode. */
#define INST_INVALID_64BITS (1 << 23)
/* Specific instruction is can be promoted to 64 bits (without REX it is promoted automatically). */
#define INST_64BITS (1 << 24)
/* Indicates the instruction must be REX prefixed in order to use 64 bits operands. */
#define INST_PRE_REX (1 << 25)
/* Third mnemonic is set. */
#define INST_USE_EXMNEMONIC2 (1 << 26)
/* Instruction is only valid in 64 bits decoding mode. */
#define INST_64BITS_FETCH (1 << 27)

#define INST_PRE_REPS (INST_PRE_REPNZ | INST_PRE_REP)
#define INST_PRE_LOKREP_MASK (INST_PRE_LOCK | INST_PRE_REPNZ | INST_PRE_REP)
#define INST_PRE_SEGOVRD_MASK (INST_PRE_CS | INST_PRE_SS | INST_PRE_DS | INST_PRE_ES | INST_PRE_FS | INST_PRE_GS)

/* Instructions Set classes: */
/* Indicates the instruction belongs to the General Integer set. */
#define ISCT_INTEGER 1
/* Indicates the instruction belongs to the 387 FPU set. */
#define ISCT_FPU 2
/* Indicates the instruction belongs to the P6 set. */
#define ISCT_P6 3
/* Indicates the instruction belongs to the MMX set. */
#define ISCT_MMX 4
/* Indicates the instruction belongs to the SSE set. */
#define ISCT_SSE 5
/* Indicates the instruction belongs to the SSE2 set. */
#define ISCT_SSE2 6
/* Indicates the instruction belongs to the SSE3 set. */
#define ISCT_SSE3 7
/* Indicates the instruction belongs to the SSSE3 set. */
#define ISCT_SSSE3 8
/* Indicates the instruction belongs to the SSE4.1 set. */
#define ISCT_SSE4_1 9
/* Indicates the instruction belongs to the SSE4.2 set. */
#define ISCT_SSE4_2 10
/* Indicates the instruction belongs to the AMD's SSE4.A set. */
#define ISCT_SSE4_A 11
/* Indicates the instruction belongs to the 3DNow! set. */
#define ISCT_3DNOW 12
/* Indicates the instruction belongs to the 3DNow! Extensions set. */
#define ISCT_3DNOWEXT 13
/* Indicates the instruction belongs to the VMX (Intel) set. */
#define ISCT_VMX 14
/* Indicates the instruction belongs to the SVM (AMD) set. */
#define ISCT_SVM 15

/*
 * Indicates which operand is being decoded.
 * Destination (1st), Source (2nd), op3 (3rd), op4 (4th).
 * Its main purpose to help the decode-operands function know whether its the first operand (+ it's indirection + there's a lock prefix).
 */
typedef enum {ONT_NONE = -1, ONT_1, ONT_2, ONT_3, ONT_4} _OperandNumberType;

#define MAX_MNEMONIC_LENGTH (32)

#ifdef _MSC_VER
 #pragma pack(push, 1)
#endif

/*
 * Info about the instruction, source/dest types, its name in text and flags.
 * This structure is used for the instructions DB and NOT for the disassembled result code!
 * This is the BASE structure, there are extentions to this structure below.
 */

typedef struct _PACKED_ {
	uint8_t type;
	uint8_t isc;
	uint8_t s, d; /* OpType */
	int8_t* mnemonic;
	_iflags flags;
} _InstInfo;

/*
 * There are merely few instructions which need a second mnemonic for 32 bits.
 * Or a third for 64 bits. Therefore sometimes the second mnemonic is empty but not the third.
 * In all decoding modes the first mnemonic is the default.
 * A flag will indicate it uses another mnemonic.
 *
 * There are a couple of (SSE4) instructions in the whole DB which need both op3 and 3rd mnemonic for 64bits,
 * therefore, I decided to make the extended structure contain all extra info in the same structure.
 * There are a few instructions (SHLD/SHRD/IMUL and SSE too) which use third operand (or a fourth).
 * A flag will indicate it uses a third/fourth operand.
 *
 */
typedef struct _PACKED_ {
	uint8_t type;
	uint8_t isc;
	uint8_t s, d; /* OpType */
	int8_t* mnemonic;
	_iflags flags;
	uint8_t op3, op4; /* OpType */
	int8_t* mnemonic2;
	int8_t* mnemonic3;
} _InstInfoEx;

/* Trie data structure node type: */
typedef enum {
	INT_NOTEXISTS = -1, /* Not exists (this is used for a return code only). */
	INT_NONE, /* No instruction info or list set. */
	INT_INFO, /* It's an instruction info. */
	INT_LIST_GROUP,
	INT_LIST_FULL,
	INT_LIST_DIVIDED
} _InstNodeType;

/*
 * A node in the instructions DB;
 * Can be both a node or an info, depends on type.
 */
typedef struct _PACKED_ InstNode{
	uint8_t type;
	uint8_t* ids;
	_InstInfo** list; /* The second level might point to _InstNode, this is determined by type in runtime. */
} _InstNode;

#ifdef _MSC_VER
 #pragma pack(pop)
#endif

typedef enum {OPERAND_SIZE_NONE = 0, OPERAND_SIZE8, OPERAND_SIZE16, OPERAND_SIZE32, OPERAND_SIZE64, OPERAND_SIZE80, OPERAND_SIZE128} _OperandSizeType;

/*
 * Used for letting the extract operand know the type of operands without knowing the
 * instruction itself yet, because of the way those instructions work.
 */
extern _InstInfo II_3dnow;

_InstInfo* locate_inst(const uint8_t** code, int* codeLen, _OffsetType* codeOffset, _WString* instructionHex, _PrefixState* ps, _DecodeType dt);
_InstInfo* locate_3dnow_inst(_CodeInfo* ci, _WString* instructionHex);

/* Concatenates a text describing the size used for indirections form. (MOV *WORD* [BX], 0x12) when it's not cleared from operands. */
void str_indirection_text(_WString* s, _OperandSizeType opSize);

#endif /* INSTRUCTIONS_H */