1- /* diStorm 3.4.0 */
1+ /* diStorm 3.5.2 */
22
33/*
44distorm.h
55
66diStorm3 - Powerful disassembler for X86/AMD64
77http://ragestorm.net/distorm/
88distorm at gmail dot com
9- Copyright (C) 2003-2018 Gil Dabah
9+ Copyright (C) 2003-2021 Gil Dabah
1010This library is licensed under the BSD license. See the file COPYING.
1111*/
1212
@@ -33,29 +33,27 @@ This library is licensed under the BSD license. See the file COPYING.
3333 #undef SUPPORT_64BIT_OFFSET
3434#endif
3535
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>
4438#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 ;
4750#endif
4851
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
5957#endif
6058
6159/* Support C++ compilers */
@@ -67,10 +65,10 @@ typedef unsigned __int8 uint8_t;
6765/* *** Helper Macros *** */
6866
6967/* 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 ))
7270/* 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 )
7472
7573/* Get the target address of a branching instruction. O_PC operand type. */
7674#define INSTRUCTION_GET_TARGET (di ) ((_OffsetType)(((di)->addr + (di)->imm.addr + (di)->size)))
@@ -91,26 +89,27 @@ typedef unsigned __int8 uint8_t;
9189#define FLAG_GET_OPSIZE (flags ) (((flags) >> 8) & 3)
9290#define FLAG_GET_ADDRSIZE (flags ) (((flags) >> 10) & 3)
9391/* 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)
9593/* Indicates whether the instruction is privileged. */
9694#define FLAG_GET_PRIVILEGED (flags ) (((flags) & FLAG_PRIVILEGED_INSTRUCTION) != 0)
9795
9896/*
9997 * Macros to extract segment registers from 'segment':
10098 */
10199#define SEGMENT_DEFAULT 0x80
102- #define SEGMENT_SET (di , seg ) ((di->segment) |= seg)
103100#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)
106104
107105/* Decodes modes of the disassembler, 16 bits or 32 bits or 64 bits for AMD64, x86-64. */
108106typedef enum { Decode16Bits = 0 , Decode32Bits = 1 , Decode64Bits = 2 } _DecodeType ;
109107
110108typedef OFFSET_INTEGER _OffsetType ;
111109
112110typedef struct {
113- _OffsetType codeOffset , nextOffset ; /* nextOffset is OUT only. */
111+ _OffsetType codeOffset , addrMask ;
112+ _OffsetType nextOffset ; /* nextOffset is OUT only. */
114113 const uint8_t * code ;
115114 int codeLen ; /* Using signed integer makes it easier to detect an underflow. */
116115 _DecodeType dt ;
@@ -243,6 +242,8 @@ typedef struct {
243242 uint16_t opcode ;
244243 /* Up to four operands per instruction, ignored if ops[n].type == O_NONE. */
245244 _Operand ops [OPERANDS_NO ];
245+ /* Number of valid ops entries. */
246+ uint8_t opsNo ;
246247 /* Size of the whole instruction in bytes. */
247248 uint8_t size ;
248249 /* Segment information of memory indirection, default segment, or overriden one, can be -1. Use SEGMENT macros. */
@@ -251,8 +252,8 @@ typedef struct {
251252 uint8_t base , scale ;
252253 uint8_t dispSize ;
253254 /* 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 . */
256257 uint16_t modifiedFlagsMask , testedFlagsMask , undefinedFlagsMask ;
257258} _DInst ;
258259
@@ -271,11 +272,11 @@ typedef struct {
271272 * This structure holds all information the disassembler generates per instruction.
272273 */
273274typedef struct {
275+ _OffsetType offset ; /* Start offset of the decoded instruction. */
276+ unsigned int size ; /* Size of decoded instruction in bytes. */
274277 _WString mnemonic ; /* Mnemonic of decoded instruction, prefixed if required by REP, LOCK etc. */
275278 _WString operands ; /* Operands of the decoded instruction, up to 3 operands, comma-seperated. */
276279 _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. */
279280} _DecodedInst ;
280281
281282#endif /* DISTORM_LIGHT */
@@ -285,7 +286,7 @@ typedef struct {
285286#define RM_CX 2 /* CL, CH, CX, ECX, RCX */
286287#define RM_DX 4 /* DL, DH, DX, EDX, RDX */
287288#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 */
289290#define RM_BP 0x20 /* BPL, BP, EBP, RBP */
290291#define RM_SI 0x40 /* SIL, SI, ESI, RSI */
291292#define RM_DI 0x80 /* DIL, DI, EDI, RDI */
@@ -303,6 +304,7 @@ typedef struct {
303304#define RM_R13 0x80000 /* R13B, R13W, R13D, R13 */
304305#define RM_R14 0x100000 /* R14B, R14W, R14D, R14 */
305306#define RM_R15 0x200000 /* R15B, R15W, R15D, R15 */
307+ #define RM_SEG 0x400000 /* CS, SS, DS, ES, FS, GS */
306308
307309/* RIP should be checked using the 'flags' field and FLAG_RIP_RELATIVE.
308310 * Segments should be checked using the segment macros.
@@ -384,8 +386,21 @@ typedef struct {
384386#define DF_STOP_ON_INT 0x100
385387/* The decoder will stop and return to the caller when any of the 'CMOVxx' instruction was decoded. */
386388#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+ 387402/* 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 )
389404
390405/* Indicates the instruction is not a flow-control instruction. */
391406#define FC_NONE 0
@@ -406,9 +421,11 @@ typedef struct {
406421#define FC_INT 6
407422/* Indicates the instruction is one of: CMOVxx. */
408423#define FC_CMOV 7
424+ /* Indicates the instruction is HLT. */
425+ #define FC_HLT 8
409426
410427/* 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 ;
412429
413430/* Define the following interface functions only for outer projects. */
414431#if !(defined(DISTORM_STATIC ) || defined(DISTORM_DYNAMIC ))
@@ -431,7 +448,7 @@ typedef enum { DECRES_NONE, DECRES_SUCCESS, DECRES_MEMORYERR, DECRES_INPUTERR, D
431448 * Notes: 1)The minimal size of maxInstructions is 15.
432449 * 2)You will have to synchronize the offset,code and length by yourself if you pass code fragments and not a complete code block!
433450 */
434-
451+ 435452/* distorm_decompose
436453 * See more documentation online at the GitHub project's wiki.
437454 *
0 commit comments