1
- /* diStorm 3.4.0 */
1
+ /* diStorm 3.5.2 */
2
2
3
3
/*
4
4
distorm.h
5
5
6
6
diStorm3 - Powerful disassembler for X86/AMD64
7
7
http://ragestorm.net/distorm/
8
8
distorm at gmail dot com
9
- Copyright (C) 2003-2018 Gil Dabah
9
+ Copyright (C) 2003-2021 Gil Dabah
10
10
This library is licensed under the BSD license. See the file COPYING.
11
11
*/
12
12
@@ -33,29 +33,27 @@ This library is licensed under the BSD license. See the file COPYING.
33
33
#undef SUPPORT_64BIT_OFFSET
34
34
#endif
35
35
36
- /* If your compiler doesn't support stdint.h, define your own 64 bits type. */
37
- #ifdef SUPPORT_64BIT_OFFSET
38
- #ifdef _MSC_VER
39
- #define OFFSET_INTEGER unsigned __int64
40
- #else
41
- #include <stdint.h>
42
- #define OFFSET_INTEGER uint64_t
43
- #endif
36
+ #ifndef _MSC_VER
37
+ #include <stdint.h>
44
38
#else
45
- /* 32 bit offsets are used. */
46
- #define OFFSET_INTEGER unsigned long
39
+ /* Since MSVC < 2010 isn't shipped with stdint.h,
40
+ * here are those from MSVC 2017, which also match
41
+ * those in tinycc/libc. */
42
+ typedef signed char int8_t ;
43
+ typedef short int16_t ;
44
+ typedef int int32_t ;
45
+ typedef long long int64_t ;
46
+ typedef unsigned char uint8_t ;
47
+ typedef unsigned short uint16_t ;
48
+ typedef unsigned int uint32_t ;
49
+ typedef unsigned long long uint64_t ;
47
50
#endif
48
51
49
- #ifdef _MSC_VER
50
- /* Since MSVC isn't shipped with stdint.h, we will have our own: */
51
- typedef signed __int64 int64_t ;
52
- typedef unsigned __int64 uint64_t ;
53
- typedef signed __int32 int32_t ;
54
- typedef unsigned __int32 uint32_t ;
55
- typedef signed __int16 int16_t ;
56
- typedef unsigned __int16 uint16_t ;
57
- typedef signed __int8 int8_t ;
58
- typedef unsigned __int8 uint8_t ;
52
+ #ifdef SUPPORT_64BIT_OFFSET
53
+ #define OFFSET_INTEGER uint64_t
54
+ #else
55
+ /* 32 bit offsets are used. */
56
+ #define OFFSET_INTEGER uint32_t
59
57
#endif
60
58
61
59
/* Support C++ compilers */
@@ -67,10 +65,10 @@ typedef unsigned __int8 uint8_t;
67
65
/* *** Helper Macros *** */
68
66
69
67
/* Get the ISC of the instruction, used with the definitions below. */
70
- #define META_GET_ISC (meta ) (((meta) >> 3 ) & 0x1f)
71
- #define META_SET_ISC (di , isc ) (((di)->meta) |= ((isc) << 3 ))
68
+ #define META_GET_ISC (meta ) (((meta) >> 8 ) & 0x1f)
69
+ #define META_SET_ISC (di , isc ) (((di)->meta) |= ((isc) << 8 ))
72
70
/* Get the flow control flags of the instruction, see 'features for decompose' below. */
73
- #define META_GET_FC (meta ) ((meta) & 0x7 )
71
+ #define META_GET_FC (meta ) ((meta) & 0xf )
74
72
75
73
/* Get the target address of a branching instruction. O_PC operand type. */
76
74
#define INSTRUCTION_GET_TARGET (di ) ((_OffsetType)(((di)->addr + (di)->imm.addr + (di)->size)))
@@ -91,26 +89,27 @@ typedef unsigned __int8 uint8_t;
91
89
#define FLAG_GET_OPSIZE (flags ) (((flags) >> 8) & 3)
92
90
#define FLAG_GET_ADDRSIZE (flags ) (((flags) >> 10) & 3)
93
91
/* To get the LOCK/REPNZ/REP prefixes. */
94
- #define FLAG_GET_PREFIX (flags ) ((flags) & 7)
92
+ #define FLAG_GET_PREFIX (flags ) (((unsigned int)((int16_t) flags) ) & 7)
95
93
/* Indicates whether the instruction is privileged. */
96
94
#define FLAG_GET_PRIVILEGED (flags ) (((flags) & FLAG_PRIVILEGED_INSTRUCTION) != 0)
97
95
98
96
/*
99
97
* Macros to extract segment registers from 'segment':
100
98
*/
101
99
#define SEGMENT_DEFAULT 0x80
102
- #define SEGMENT_SET (di , seg ) ((di->segment) |= seg)
103
100
#define SEGMENT_GET (segment ) (((segment) == R_NONE) ? R_NONE : ((segment) & 0x7f))
104
- #define SEGMENT_IS_DEFAULT (segment ) (((segment) & SEGMENT_DEFAULT) == SEGMENT_DEFAULT)
105
-
101
+ #define SEGMENT_GET_UNSAFE (segment ) ((segment) & 0x7f)
102
+ #define SEGMENT_IS_DEFAULT (segment ) (((int8_t)segment) < -1) /* Quick check it's a negative number that isn't -1, so it's (0x80 | SEGREG). */
103
+ #define SEGMENT_IS_DEFAULT_OR_NONE (segment ) (((uint8_t)(segment)) > 0x80)
106
104
107
105
/* Decodes modes of the disassembler, 16 bits or 32 bits or 64 bits for AMD64, x86-64. */
108
106
typedef enum { Decode16Bits = 0 , Decode32Bits = 1 , Decode64Bits = 2 } _DecodeType ;
109
107
110
108
typedef OFFSET_INTEGER _OffsetType ;
111
109
112
110
typedef struct {
113
- _OffsetType codeOffset , nextOffset ; /* nextOffset is OUT only. */
111
+ _OffsetType codeOffset , addrMask ;
112
+ _OffsetType nextOffset ; /* nextOffset is OUT only. */
114
113
const uint8_t * code ;
115
114
int codeLen ; /* Using signed integer makes it easier to detect an underflow. */
116
115
_DecodeType dt ;
@@ -243,6 +242,8 @@ typedef struct {
243
242
uint16_t opcode ;
244
243
/* Up to four operands per instruction, ignored if ops[n].type == O_NONE. */
245
244
_Operand ops [OPERANDS_NO ];
245
+ /* Number of valid ops entries. */
246
+ uint8_t opsNo ;
246
247
/* Size of the whole instruction in bytes. */
247
248
uint8_t size ;
248
249
/* Segment information of memory indirection, default segment, or overriden one, can be -1. Use SEGMENT macros. */
@@ -251,8 +252,8 @@ typedef struct {
251
252
uint8_t base , scale ;
252
253
uint8_t dispSize ;
253
254
/* Meta defines the instruction set class, and the flow control flags. Use META macros. */
254
- uint8_t meta ;
255
- /* The CPU flags that the instruction operates upon. */
255
+ uint16_t meta ;
256
+ /* The CPU flags that the instruction operates upon, set only with DF_FILL_EFLAGS enabled, otherwise 0 . */
256
257
uint16_t modifiedFlagsMask , testedFlagsMask , undefinedFlagsMask ;
257
258
} _DInst ;
258
259
@@ -271,11 +272,11 @@ typedef struct {
271
272
* This structure holds all information the disassembler generates per instruction.
272
273
*/
273
274
typedef struct {
275
+ _OffsetType offset ; /* Start offset of the decoded instruction. */
276
+ unsigned int size ; /* Size of decoded instruction in bytes. */
274
277
_WString mnemonic ; /* Mnemonic of decoded instruction, prefixed if required by REP, LOCK etc. */
275
278
_WString operands ; /* Operands of the decoded instruction, up to 3 operands, comma-seperated. */
276
279
_WString instructionHex ; /* Hex dump - little endian, including prefixes. */
277
- unsigned int size ; /* Size of decoded instruction in bytes. */
278
- _OffsetType offset ; /* Start offset of the decoded instruction. */
279
280
} _DecodedInst ;
280
281
281
282
#endif /* DISTORM_LIGHT */
@@ -285,7 +286,7 @@ typedef struct {
285
286
#define RM_CX 2 /* CL, CH, CX, ECX, RCX */
286
287
#define RM_DX 4 /* DL, DH, DX, EDX, RDX */
287
288
#define RM_BX 8 /* BL, BH, BX, EBX, RBX */
288
- #define RM_SP 0x10 /* SPL, SP, ESP, RSP */
289
+ #define RM_SP 0x10 /* SPL, SP, ESP, RSP */
289
290
#define RM_BP 0x20 /* BPL, BP, EBP, RBP */
290
291
#define RM_SI 0x40 /* SIL, SI, ESI, RSI */
291
292
#define RM_DI 0x80 /* DIL, DI, EDI, RDI */
@@ -303,6 +304,7 @@ typedef struct {
303
304
#define RM_R13 0x80000 /* R13B, R13W, R13D, R13 */
304
305
#define RM_R14 0x100000 /* R14B, R14W, R14D, R14 */
305
306
#define RM_R15 0x200000 /* R15B, R15W, R15D, R15 */
307
+ #define RM_SEG 0x400000 /* CS, SS, DS, ES, FS, GS */
306
308
307
309
/* RIP should be checked using the 'flags' field and FLAG_RIP_RELATIVE.
308
310
* Segments should be checked using the segment macros.
@@ -384,8 +386,21 @@ typedef struct {
384
386
#define DF_STOP_ON_INT 0x100
385
387
/* The decoder will stop and return to the caller when any of the 'CMOVxx' instruction was decoded. */
386
388
#define DF_STOP_ON_CMOV 0x200
389
+ /* The decoder will stop and return to the caller when it encounters the HLT instruction. */
390
+ #define DF_STOP_ON_HLT 0x400
391
+ /* The decoder will stop and return to the caller when it encounters a privileged instruction. */
392
+ #define DF_STOP_ON_PRIVILEGED 0x800
393
+ /* The decoder will stop and return to the caller when an instruction couldn't be decoded. */
394
+ #define DF_STOP_ON_UNDECODEABLE 0x1000
395
+ /* The decoder will not synchronize to the next byte after the previosuly decoded instruction, instead it will start decoding at the next byte. */
396
+ #define DF_SINGLE_BYTE_STEP 0x2000
397
+ /* The decoder will fill in the eflags fields for the decoded instruction. */
398
+ #define DF_FILL_EFLAGS 0x4000
399
+ /* The decoder will use the addrMask in CodeInfo structure instead of DF_MAXIMUM_ADDR16/32. */
400
+ #define DF_USE_ADDR_MASK 0x8000
401
+
387
402
/* The decoder will stop and return to the caller when any flow control instruction was decoded. */
388
- #define DF_STOP_ON_FLOW_CONTROL (DF_STOP_ON_CALL | DF_STOP_ON_RET | DF_STOP_ON_SYS | DF_STOP_ON_UNC_BRANCH | DF_STOP_ON_CND_BRANCH | DF_STOP_ON_INT | DF_STOP_ON_CMOV)
403
+ #define DF_STOP_ON_FLOW_CONTROL (DF_STOP_ON_CALL | DF_STOP_ON_RET | DF_STOP_ON_SYS | DF_STOP_ON_UNC_BRANCH | DF_STOP_ON_CND_BRANCH | DF_STOP_ON_INT | DF_STOP_ON_CMOV | DF_STOP_ON_HLT )
389
404
390
405
/* Indicates the instruction is not a flow-control instruction. */
391
406
#define FC_NONE 0
@@ -406,9 +421,11 @@ typedef struct {
406
421
#define FC_INT 6
407
422
/* Indicates the instruction is one of: CMOVxx. */
408
423
#define FC_CMOV 7
424
+ /* Indicates the instruction is HLT. */
425
+ #define FC_HLT 8
409
426
410
427
/* Return code of the decoding function. */
411
- typedef enum { DECRES_NONE , DECRES_SUCCESS , DECRES_MEMORYERR , DECRES_INPUTERR , DECRES_FILTERED } _DecodeResult ;
428
+ typedef enum { DECRES_NONE , DECRES_SUCCESS , DECRES_MEMORYERR , DECRES_INPUTERR } _DecodeResult ;
412
429
413
430
/* Define the following interface functions only for outer projects. */
414
431
#if !(defined(DISTORM_STATIC ) || defined(DISTORM_DYNAMIC ))
@@ -431,7 +448,7 @@ typedef enum { DECRES_NONE, DECRES_SUCCESS, DECRES_MEMORYERR, DECRES_INPUTERR, D
431
448
* Notes: 1)The minimal size of maxInstructions is 15.
432
449
* 2)You will have to synchronize the offset,code and length by yourself if you pass code fragments and not a complete code block!
433
450
*/
434
-
451
+
435
452
/* distorm_decompose
436
453
* See more documentation online at the GitHub project's wiki.
437
454
*
0 commit comments