-
Notifications
You must be signed in to change notification settings - Fork 0
/
inst.h
160 lines (137 loc) · 4.46 KB
/
inst.h
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
#if !defined INST_H
#define INST_H
#include "common.h"
#define F_W (0b1 << 0)
#define F_D (0b1 << 1)
#define F_S (0b1 << 2)
#define F_V (0b1 << 3)
#define F_ES (0b00 << 4)
#define F_CS (0b01 << 4)
#define F_SS (0b10 << 4)
#define F_DS (0b11 << 4)
#define F_MO (0b1 << 6) // memory only
#define F_LB (0b1 << 7) // has label
#define SR_OP(flags) (((flags) >> 4) & 0b11)
// implicit prefixes
#define PFX_WIDE (0b1 << 0)
#define PFX_FAR (0b1 << 1)
// explicit prefixes
#define PFX_LOCK (0b1 << 2)
#define PFX_SGMNT (0b1 << 3)
#define PFX_SGMNT_ES (0b00 << 4)
#define PFX_SGMNT_CS (0b01 << 4)
#define PFX_SGMNT_SS (0b10 << 4)
#define PFX_SGMNT_DS (0b11 << 4)
#define PFX_REP (0b1 << 6)
#define PFX_REPNE (0b1 << 7)
#define SGMNT_OP(prefixes) (((prefixes) >> 4) & 0b11)
#define FIELD_MOD(fields) (((fields) >> 0) & 0b11)
#define FIELD_SR(fields) (((fields) >> 2) & 0b11)
#define FIELD_RM(fields) (((fields) >> 4) & 0b111)
#define FIELD_REG(fields) (((fields) >> 7) & 0b111)
#define FIELD_ESC(fields) (((fields) >> 10) & 0b111111)
#define MODE_MEM0 0b00
#define MODE_MEM8 0b01
#define MODE_MEM16 0b10
#define MODE_REG 0b11
enum inst_format
{
INST_FMT_NONE,
// [mod ... r/m] [disp-lo] [disp-hi]
INST_FMT_RM,
// [mod ... r/m] [disp-lo] [disp-hi] (store 1/cl)
INST_FMT_RM_V,
// [mod 0 sr r/m] [disp-lo] [disp-hi]
INST_FMT_RM_SR,
// [mod reg r/m] [disp-lo] [disp-hi]
INST_FMT_RM_REG,
// [mod ... r/m] [disp-lo] [disp-hi] [data]
INST_FMT_RM_IMM,
// [... xxx] [mod yyy r/m] [disp-lo] [disp-hi]
INST_FMT_RM_ESC,
INST_FMT_ACC_DX,
// [data-8]
INST_FMT_ACC_IMM8,
// [data-lo] [data-hi]
INST_FMT_ACC_IMM,
// [... reg]
INST_FMT_ACC_REG,
// [addr-lo] [addr-hi]
INST_FMT_ACC_MEM,
// [... reg]
INST_FMT_REG,
// [...reg] [data-hi] [data-lo]
INST_FMT_REG_IMM,
// [... sr ...]
INST_FMT_SR,
// [data-lo] [data-hi]
INST_FMT_IMM,
// [ip-inc-8]
INST_FMT_JMP_SHORT,
// [ip-inc-lo] [ip-inc-hi]
INST_FMT_JMP_NEAR,
// [ip-lo] [ip-hi] [cs-lo] [cs-hi]
INST_FMT_JMP_FAR,
};
enum inst_type
{
INST_UNK = 0,
INST_AAA, INST_AAD, INST_AAM, INST_AAS,
INST_ADC, INST_ADD, INST_AND, INST_CALL,
INST_CALLF, INST_CBW, INST_CLC, INST_CLD,
INST_CLI, INST_CMC, INST_CMP, INST_CMPSB,
INST_CMPSW, INST_CWD, INST_DAA, INST_DAS,
INST_DEC, INST_DIV, INST_ESC, INST_HLT,
INST_IDIV, INST_IMUL, INST_IN, INST_INC,
INST_INT, INST_INT3, INST_INTO, INST_IRET,
INST_JA, INST_JAE, INST_JB, INST_JBE,
INST_JCXZ, INST_JE, INST_JG, INST_JGE,
INST_JL, INST_JLE, INST_JMP, INST_JMPF,
INST_JNE, INST_JNO, INST_JNS, INST_JO,
INST_JP, INST_JPO, INST_JS, INST_LAHF,
INST_LDS, INST_LEA, INST_LES, INST_LOCK,
INST_LODSB, INST_LODSW, INST_LOOP, INST_LOOPZ,
INST_LOOPNZ, INST_MOV, INST_MOVSB, INST_MOVSW,
INST_MUL, INST_NEG, INST_NOP, INST_NOT,
INST_OR, INST_OUT, INST_POP, INST_POPF,
INST_PUSH, INST_PUSHF, INST_RCL, INST_RCR,
INST_REP, INST_REPNE, INST_RET, INST_RETF,
INST_ROL, INST_ROR, INST_SAHF, INST_SAR,
INST_SBB, INST_SCASB, INST_SCASW, INST_SGMNT,
INST_SHL, INST_SHR, INST_STC, INST_STD,
INST_STOSB, INST_STOSW, INST_STI, INST_SUB,
INST_TEST, INST_WAIT, INST_XCHG, INST_XLAT,
INST_XOR,
INST_EXTD,
};
struct inst_data
{
enum inst_type type;
enum inst_format fmt;
uint8 flags; // w, d, s, v, sr, mo, lb
uint8 prefixes; // lock, sgmnt, rep, repne
uint8 size;
};
struct inst
{
struct inst_data base;
uint16 disp;
uint16 data; // addr, imm
uint16 data_ext; // if instruction size is 6 bytes
uint16 fields; // mod, reg, r/m, sr, esc
uint offset; // location in image
};
// Calculates target offset of a jmp instruction (call, jmp, jne etc). Returns
// offset on success and negative if it's not a jmp instruction.
extern int get_jmp_offset(struct inst *inst);
// Extracts instruction data from 'image' at given 'offset'. Returns 0 on
// success and negative value if error occurred.
extern int get_inst(struct inst *inst, uint8 * const image, uint size,
uint offset);
// Extracts instructions from 'image' and writes 'count' instructions into
// 'insts' array. If 'insts' is NULL, function returns instruction count. If
// invalid instruction is encountered or error occurred negative value is
// returned. Returns 0 on success.
extern int inst_scan_image(struct inst * const insts, uint count,
uint8 * const image, uint size);
#endif /* INST_H */