rallhook 0.7.5 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,38 @@
1
+ /*
2
+ operands.h
3
+
4
+ diStorm3 - Powerful disassembler for X86/AMD64
5
+ http://ragestorm.net/distorm/
6
+ distorm at gmail dot com
7
+ Copyright (C) 2010 Gil Dabah
8
+
9
+ This program is free software: you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License as published by
11
+ the Free Software Foundation, either version 3 of the License, or
12
+ (at your option) any later version.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ You should have received a copy of the GNU General Public License
20
+ along with this program. If not, see <http://www.gnu.org/licenses/>
21
+ */
22
+
23
+
24
+ #ifndef OPERANDS_H
25
+ #define OPERANDS_H
26
+
27
+ #include "../config.h"
28
+
29
+ #include "decoder.h"
30
+ #include "prefix.h"
31
+ #include "instructions.h"
32
+
33
+ int operands_extract(_CodeInfo* ci, _DInst* di, _InstInfo* ii,
34
+ _OpType type, _OperandNumberType opNum,
35
+ unsigned int modrm, _PrefixState* ps, _DecodeType effOpSz,
36
+ _DecodeType effAdrSz, int* lockableInstruction);
37
+
38
+ #endif /* OPERANDS_H */
@@ -0,0 +1,380 @@
1
+ /*
2
+ prefix.c
3
+
4
+ diStorm3 - Powerful disassembler for X86/AMD64
5
+ http://ragestorm.net/distorm/
6
+ distorm at gmail dot com
7
+ Copyright (C) 2010 Gil Dabah
8
+
9
+ This program is free software: you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License as published by
11
+ the Free Software Foundation, either version 3 of the License, or
12
+ (at your option) any later version.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ You should have received a copy of the GNU General Public License
20
+ along with this program. If not, see <http://www.gnu.org/licenses/>
21
+ */
22
+
23
+
24
+ #include "prefix.h"
25
+
26
+ #include "x86defs.h"
27
+ #include "instructions.h"
28
+ #include "../mnemonics.h"
29
+
30
+
31
+ /*
32
+ * The main purpose of this module is to keep track of all kind of prefixes a single instruction may have.
33
+ * The problem is that a single instruction may have up to six different prefix-types.
34
+ * That's why I have to detect such cases and drop those excess prefixes.
35
+ */
36
+
37
+ int prefixes_is_valid(unsigned int ch, _DecodeType dt)
38
+ {
39
+ switch (ch) {
40
+ /* for i in xrange(0x40, 0x50): print "case 0x%2x:" % i */
41
+ case 0x40: /* REX: */
42
+ case 0x41:
43
+ case 0x42:
44
+ case 0x43:
45
+ case 0x44:
46
+ case 0x45:
47
+ case 0x46:
48
+ case 0x47:
49
+ case 0x48:
50
+ case 0x49:
51
+ case 0x4a:
52
+ case 0x4b:
53
+ case 0x4c:
54
+ case 0x4d:
55
+ case 0x4e:
56
+ case 0x4f: return (dt == Decode64Bits);
57
+ case PREFIX_LOCK: return TRUE;
58
+ case PREFIX_REPNZ: return TRUE;
59
+ case PREFIX_REP: return TRUE;
60
+ case PREFIX_CS: return TRUE;
61
+ case PREFIX_SS: return TRUE;
62
+ case PREFIX_DS: return TRUE;
63
+ case PREFIX_ES: return TRUE;
64
+ case PREFIX_FS: return TRUE;
65
+ case PREFIX_GS: return TRUE;
66
+ case PREFIX_OP_SIZE: return TRUE;
67
+ case PREFIX_ADDR_SIZE: return TRUE;
68
+ /* The VEXs might be false positives, the decode_perfixes will determine for sure. */
69
+ case PREFIX_VEX2b: /* VEX is supported for all modes, because 16 bits Pmode is included. */
70
+ case PREFIX_VEX3b: return TRUE;
71
+ }
72
+ return FALSE;
73
+ }
74
+
75
+ /* Ignore a specific prefix type. */
76
+ void prefixes_ignore(_PrefixState* ps, _PrefixIndexer pi)
77
+ {
78
+ /*
79
+ * If that type of prefix appeared already, set the bit of that *former* prefix.
80
+ * Anyway, set the new index of that prefix type to the current index, so next time we know its position.
81
+ */
82
+ if (ps->pfxIndexer[pi] != PFXIDX_NONE) ps->unusedPrefixesMask |= (1 << ps->pfxIndexer[pi]);
83
+ }
84
+
85
+ /* Ignore all prefix. */
86
+ void prefixes_ignore_all(_PrefixState* ps)
87
+ {
88
+ int i;
89
+ for (i = 0; i < PFXIDX_MAX; i++)
90
+ prefixes_ignore(ps, i);
91
+ }
92
+
93
+ /* Calculates which prefixes weren't used and accordingly sets the bits in the unusedPrefixesMask. */
94
+ uint16_t prefixes_set_unused_mask(_PrefixState* ps)
95
+ {
96
+ /*
97
+ * The decodedPrefixes represents the prefixes that were *read* from the binary stream for the instruction.
98
+ * The usedPrefixes represents the prefixes that were actually used by the instruction in the *decode* phase.
99
+ * Xoring between the two will result in a 'diff' which returns the prefixes that were read
100
+ * from the stream *and* that were never used in the actual decoding.
101
+ *
102
+ * Only one prefix per type can be set in decodedPrefixes from the stream.
103
+ * Therefore it's enough to check each type once and set the flag accordingly.
104
+ * That's why we had to book-keep each prefix type and its position.
105
+ * So now we know which bits we need to set exactly in the mask.
106
+ */
107
+ _iflags unusedPrefixesDiff = ps->decodedPrefixes ^ ps->usedPrefixes;
108
+
109
+ /* Examine unused prefixes by type: */
110
+ /*
111
+ * About REX: it might be set in the diff although it was never in the stream itself.
112
+ * This is because the vrex is shared between VEX and REX and some places flag it as REX usage, while
113
+ * we were really decoding an AVX instruction.
114
+ * It's not a big problem, because the prefixes_ignore func will ignore it anyway,
115
+ * since it wasn't seen earlier. But it's important to know this.
116
+ */
117
+ if (unusedPrefixesDiff & INST_PRE_REX) prefixes_ignore(ps, PFXIDX_REX);
118
+ if (unusedPrefixesDiff & INST_PRE_SEGOVRD_MASK) prefixes_ignore(ps, PFXIDX_SEG);
119
+ if (unusedPrefixesDiff & INST_PRE_LOKREP_MASK) prefixes_ignore(ps, PFXIDX_LOREP);
120
+ if (unusedPrefixesDiff & INST_PRE_OP_SIZE) prefixes_ignore(ps, PFXIDX_OP_SIZE);
121
+ if (unusedPrefixesDiff & INST_PRE_ADDR_SIZE) prefixes_ignore(ps, PFXIDX_ADRS);
122
+ /* If a VEX instruction was found, its prefix is considered as used, therefore no point for checking for it. */
123
+
124
+ return ps->unusedPrefixesMask;
125
+ }
126
+
127
+ /*
128
+ * Mark a prefix as unused, and bookkeep where we last saw this same type,
129
+ * because in the future we might want to disable it too.
130
+ */
131
+ _INLINE_ void prefixes_track_unused(_PrefixState* ps, int index, _PrefixIndexer pi)
132
+ {
133
+ prefixes_ignore(ps, pi);
134
+ /* Book-keep the current index for this type. */
135
+ ps->pfxIndexer[pi] = index;
136
+ }
137
+
138
+ /*
139
+ * Read as many prefixes as possible, up to 15 bytes, and halt when we encounter non-prefix byte.
140
+ * This algorithm tries to imitate a real processor, where the same prefix can appear a few times, etc.
141
+ * The tiny complexity is that we want to know when a prefix was superfluous and mark any copy of it as unused.
142
+ * Note that the last prefix of its type will be considered as used, and all the others (of same type) before it as unused.
143
+ */
144
+ void prefixes_decode(const uint8_t* code, int codeLen, _PrefixState* ps, _DecodeType dt)
145
+ {
146
+ int index, done;
147
+ uint8_t vex;
148
+
149
+ /*
150
+ * First thing to do, scan for prefixes, there are six types of prefixes.
151
+ * There may be up to six prefixes before a single instruction, not the same type, no special order,
152
+ * except REX/VEX must precede immediately the first opcode byte.
153
+ * BTW - This is the reason why I didn't make the REP prefixes part of the instructions (STOS/SCAS/etc).
154
+ *
155
+ * Another thing, the instruction maximum size is 15 bytes, thus if we read more than 15 bytes, we will halt.
156
+ *
157
+ * We attach all prefixes to the next instruction, there might be two or more occurrences from the same prefix.
158
+ * Also, since VEX can be allowed only once we will test it separately.
159
+ */
160
+ for (index = 0, done = FALSE;
161
+ (codeLen > 0) && (code - ps->start < INST_MAXIMUM_SIZE);
162
+ code++, codeLen--, index++) {
163
+ /*
164
+ NOTE: AMD treat lock/rep as two different groups... But I am based on Intel.
165
+
166
+ - Lock and Repeat:
167
+ - 0xF0 � LOCK
168
+ - 0xF2 � REPNE/REPNZ
169
+ - 0xF3 - REP/REPE/REPZ
170
+ - Segment Override:
171
+ - 0x2E - CS
172
+ - 0x36 - SS
173
+ - 0x3E - DS
174
+ - 0x26 - ES
175
+ - 0x64 - FS
176
+ - 0x65 - GS
177
+ - Operand-Size Override: 0x66, switching default size.
178
+ - Address-Size Override: 0x67, switching default size.
179
+
180
+ 64 Bits:
181
+ - REX: 0x40 - 0x4f, extends register access.
182
+ - 2 Bytes VEX: 0xc4
183
+ - 3 Bytes VEX: 0xc5
184
+ 32 Bits:
185
+ - 2 Bytes VEX: 0xc4 11xx-xxxx
186
+ - 3 Bytes VEX: 0xc5 11xx-xxxx
187
+ */
188
+
189
+ /* Examine what type of prefix we got. */
190
+ switch (*code)
191
+ {
192
+ /* REX type, 64 bits decoding mode only: */
193
+ case 0x40:
194
+ case 0x41:
195
+ case 0x42:
196
+ case 0x43:
197
+ case 0x44:
198
+ case 0x45:
199
+ case 0x46:
200
+ case 0x47:
201
+ case 0x48:
202
+ case 0x49:
203
+ case 0x4a:
204
+ case 0x4b:
205
+ case 0x4c:
206
+ case 0x4d:
207
+ case 0x4e:
208
+ case 0x4f:
209
+ if (dt == Decode64Bits) {
210
+ ps->decodedPrefixes |= INST_PRE_REX;
211
+ ps->vrex = *code & 0xf; /* Keep only BXRW. */
212
+ ps->rexPos = code;
213
+ ps->prefixExtType = PET_REX;
214
+ prefixes_track_unused(ps, index, PFXIDX_REX);
215
+ } else done = TRUE; /* If we are not in 64 bits mode, it's an instruction, then halt. */
216
+ break;
217
+
218
+ /* LOCK and REPx type: */
219
+ case PREFIX_LOCK:
220
+ ps->decodedPrefixes |= INST_PRE_LOCK;
221
+ prefixes_track_unused(ps, index, PFXIDX_LOREP);
222
+ break;
223
+ case PREFIX_REPNZ:
224
+ ps->decodedPrefixes |= INST_PRE_REPNZ;
225
+ prefixes_track_unused(ps, index, PFXIDX_LOREP);
226
+ break;
227
+ case PREFIX_REP:
228
+ ps->decodedPrefixes |= INST_PRE_REP;
229
+ prefixes_track_unused(ps, index, PFXIDX_LOREP);
230
+ break;
231
+
232
+ /* Seg Overide type: */
233
+ case PREFIX_CS:
234
+ ps->decodedPrefixes |= INST_PRE_CS;
235
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
236
+ break;
237
+ case PREFIX_SS:
238
+ ps->decodedPrefixes |= INST_PRE_SS;
239
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
240
+ break;
241
+ case PREFIX_DS:
242
+ ps->decodedPrefixes |= INST_PRE_DS;
243
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
244
+ break;
245
+ case PREFIX_ES:
246
+ ps->decodedPrefixes |= INST_PRE_ES;
247
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
248
+ break;
249
+ case PREFIX_FS:
250
+ ps->decodedPrefixes |= INST_PRE_FS;
251
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
252
+ break;
253
+ case PREFIX_GS:
254
+ ps->decodedPrefixes |= INST_PRE_GS;
255
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
256
+ break;
257
+
258
+ /* Op Size type: */
259
+ case PREFIX_OP_SIZE:
260
+ ps->decodedPrefixes |= INST_PRE_OP_SIZE;
261
+ prefixes_track_unused(ps, index, PFXIDX_OP_SIZE);
262
+ break;
263
+
264
+ /* Addr Size type: */
265
+ case PREFIX_ADDR_SIZE:
266
+ ps->decodedPrefixes |= INST_PRE_ADDR_SIZE;
267
+ prefixes_track_unused(ps, index, PFXIDX_ADRS);
268
+ break;
269
+
270
+ /* Non-prefix byte now, so break 2. */
271
+ default: done = TRUE; break;
272
+ }
273
+ if (done) break;
274
+ }
275
+
276
+ /* 2 Bytes VEX: */
277
+ if ((codeLen >= 2) &&
278
+ (*code == PREFIX_VEX2b) &&
279
+ ((code - ps->start) <= INST_MAXIMUM_SIZE - 2)) {
280
+ /*
281
+ * In 32 bits the second byte has to be in the special range of Mod=11.
282
+ * Otherwise it might be a normal LDS instruction.
283
+ */
284
+ if ((dt == Decode64Bits) || (*(code + 1) >= INST_DIVIDED_MODRM)) {
285
+ ps->vexPos = code + 1;
286
+ ps->decodedPrefixes |= INST_PRE_VEX;
287
+ ps->prefixExtType = PET_VEX2BYTES;
288
+
289
+ /*
290
+ * VEX 1 byte bits:
291
+ * |7-6--3-2-10|
292
+ * |R|vvvv|L|pp|
293
+ * |-----------|
294
+ */
295
+
296
+ /* -- Convert from VEX prefix to VREX flags -- */
297
+ vex = *ps->vexPos;
298
+ if (~vex & 0x80 && dt == Decode64Bits) ps->vrex |= PREFIX_EX_R; /* Convert VEX.R. */
299
+ if (vex & 4) ps->vrex |= PREFIX_EX_L; /* Convert VEX.L. */
300
+
301
+ code += 2;
302
+ }
303
+ }
304
+
305
+ /* 3 Bytes VEX: */
306
+ if ((codeLen >= 3) &&
307
+ (*code == PREFIX_VEX3b) &&
308
+ ((code - ps->start) <= INST_MAXIMUM_SIZE - 3) &&
309
+ (~ps->decodedPrefixes & INST_PRE_VEX)) {
310
+ /*
311
+ * In 32 bits the second byte has to be in the special range of Mod=11.
312
+ * Otherwise it might be a normal LES instruction.
313
+ * And we don't care now about the 3rd byte.
314
+ */
315
+ if ((dt == Decode64Bits) || (*(code + 1) >= INST_DIVIDED_MODRM)) {
316
+ ps->vexPos = code + 1;
317
+ ps->decodedPrefixes |= INST_PRE_VEX;
318
+ ps->prefixExtType = PET_VEX3BYTES;
319
+
320
+ /*
321
+ * VEX first and second bytes:
322
+ * |7-6-5-4----0| |7-6--3-2-10|
323
+ * |R|X|B|m-mmmm| |W|vvvv|L|pp|
324
+ * |------------| |-----------|
325
+ */
326
+
327
+ /* -- Convert from VEX prefix to VREX flags -- */
328
+ vex = *ps->vexPos;
329
+ ps->vrex |= ((~vex >> 5) & 0x7); /* Shift and invert VEX.R/X/B to their place */
330
+ vex = *(ps->vexPos + 1);
331
+ if (vex & 4) ps->vrex |= PREFIX_EX_L; /* Convert VEX.L. */
332
+ if (vex & 0x80) ps->vrex |= PREFIX_EX_W; /* Convert VEX.W. */
333
+
334
+ /* Clear some flags if the mode isn't 64 bits. */
335
+ if (dt != Decode64Bits) ps->vrex &= ~(PREFIX_EX_B | PREFIX_EX_X | PREFIX_EX_R | PREFIX_EX_W);
336
+
337
+ code += 3;
338
+ }
339
+ }
340
+
341
+ /*
342
+ * Save last byte scanned address, so the decoder could keep on scanning from this point and on and on and on.
343
+ * In addition the decoder is able to know that the last byte could lead to MMX/SSE instructions (preceding REX if exists).
344
+ */
345
+ ps->last = code; /* ps->last points to an opcode byte. */
346
+ }
347
+
348
+ /*
349
+ * For every memory-indirection operand we want to set its corresponding default segment.
350
+ * If the segment is being overrided, we need to see whether we use it or not.
351
+ * We will use it only if it's not the default one already.
352
+ */
353
+ void prefixes_use_segment(_iflags defaultSeg, _PrefixState* ps, _DecodeType dt, _DInst* di)
354
+ {
355
+ _iflags flags = 0;
356
+ if (dt == Decode64Bits) flags = ps->decodedPrefixes & INST_PRE_SEGOVRD_MASK64;
357
+ else flags = ps->decodedPrefixes & INST_PRE_SEGOVRD_MASK;
358
+
359
+ if ((flags == 0) || (flags == defaultSeg)) {
360
+ flags = defaultSeg;
361
+ di->segment |= SEGMENT_DEFAULT;
362
+ } else if (flags != defaultSeg) {
363
+ /* Use it only if it's non-default segment. */
364
+ ps->usedPrefixes |= flags;
365
+ }
366
+
367
+ /* ASSERT: R_XX must be below 128. */
368
+ switch (flags)
369
+ {
370
+ case INST_PRE_ES: di->segment |= R_ES; break;
371
+ case INST_PRE_CS: di->segment |= R_CS; break;
372
+ case INST_PRE_SS: di->segment |= R_SS; break;
373
+ case INST_PRE_DS: di->segment |= R_DS; break;
374
+ case INST_PRE_FS: di->segment |= R_FS; break;
375
+ case INST_PRE_GS: di->segment |= R_GS; break;
376
+ }
377
+
378
+ /* If it's one of the CS,SS,DS,ES and the mode is 64 bits, set segment it to none, since it's ignored. */
379
+ if ((dt == Decode64Bits) && (flags & INST_PRE_SEGOVRD_MASK32)) di->segment = R_NONE;
380
+ }
@@ -0,0 +1,76 @@
1
+ /*
2
+ prefix.h
3
+
4
+ diStorm3 - Powerful disassembler for X86/AMD64
5
+ http://ragestorm.net/distorm/
6
+ distorm at gmail dot com
7
+ Copyright (C) 2010 Gil Dabah
8
+
9
+ This program is free software: you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License as published by
11
+ the Free Software Foundation, either version 3 of the License, or
12
+ (at your option) any later version.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ You should have received a copy of the GNU General Public License
20
+ along with this program. If not, see <http://www.gnu.org/licenses/>
21
+ */
22
+
23
+
24
+ #ifndef PREFIX_H
25
+ #define PREFIX_H
26
+
27
+ #include "../config.h"
28
+
29
+ #include "decoder.h"
30
+
31
+ /* Specifies the type of the extension prefix, such as: REX, 2 bytes VEX, 3 bytes VEX. */
32
+ typedef enum {PET_NONE = 0, PET_REX, PET_VEX2BYTES, PET_VEX3BYTES} _PrefixExtType;
33
+
34
+ /* Specifies an index into a table of prefixes by their type. */
35
+ typedef enum {PFXIDX_NONE = -1, PFXIDX_REX, PFXIDX_LOREP, PFXIDX_SEG, PFXIDX_OP_SIZE, PFXIDX_ADRS, PFXIDX_MAX} _PrefixIndexer;
36
+
37
+ /*
38
+ * This holds the prefixes state for the current instruction we decode.
39
+ * decodedPrefixes includes all specific prefixes that the instruction got.
40
+ * start is a pointer to the first prefix to take into account.
41
+ * last is a pointer to the last byte we scanned.
42
+ * Other pointers are used to keep track of prefixes positions and help us know if they appeared already and where.
43
+ */
44
+ typedef struct {
45
+ _iflags decodedPrefixes, usedPrefixes;
46
+ const uint8_t *start, *last, *vexPos, *rexPos;
47
+ _PrefixExtType prefixExtType;
48
+ uint16_t unusedPrefixesMask;
49
+ /* Indicates whether the operand size prefix (0x66) was used as a mandatory prefix. */
50
+ int isOpSizeMandatory;
51
+ /* If VEX prefix is used, store the VEX.vvvv field. */
52
+ unsigned int vexV;
53
+ /* The fields B/X/R/W/L of REX and VEX are stored together in this byte. */
54
+ unsigned int vrex;
55
+
56
+ /* !! Make sure pfxIndexer is LAST! Otherwise memset won't work well with it. !! */
57
+
58
+ /* Holds the offset to the prefix byte by its type. */
59
+ int pfxIndexer[PFXIDX_MAX];
60
+ } _PrefixState;
61
+
62
+ /*
63
+ * Intel supports 6 types of prefixes, whereas AMD supports 5 types (lock is seperated from rep/nz).
64
+ * REX is the fifth prefix type, this time I'm based on AMD64.
65
+ * VEX is the 6th, though it can't be repeated.
66
+ */
67
+ #define MAX_PREFIXES (5)
68
+
69
+ int prefixes_is_valid(unsigned int ch, _DecodeType dt);
70
+ void prefixes_ignore(_PrefixState* ps, _PrefixIndexer pi);
71
+ void prefixes_ignore_all(_PrefixState* ps);
72
+ uint16_t prefixes_set_unused_mask(_PrefixState* ps);
73
+ void prefixes_decode(const uint8_t* code, int codeLen, _PrefixState* ps, _DecodeType dt);
74
+ void prefixes_use_segment(_iflags defaultSeg, _PrefixState* ps, _DecodeType dt, _DInst* di);
75
+
76
+ #endif /* PREFIX_H */