1
|
1 /* -----------------------------------------------------------------------------
|
|
2 * decode.c
|
|
3 *
|
|
4 * Copyright (c) 2005, 2006, Vivek Mohan <vivek@sig9.com>
|
|
5 * All rights reserved. See LICENSE
|
|
6 * -----------------------------------------------------------------------------
|
|
7 */
|
|
8
|
|
9 #include <string.h>
|
|
10 #include "types.h"
|
|
11 #include "input.h"
|
|
12 #include "opcmap.h"
|
|
13 #include "mnemonics.h"
|
|
14
|
|
15 /* The max number of prefixes to an instruction */
|
|
16 #define MAX_PREFIXES 15
|
|
17
|
|
18 /* register types */
|
|
19 #define T_NONE 0
|
|
20 #define T_GPR 1
|
|
21 #define T_MMX 2
|
|
22 #define T_CRG 3
|
|
23 #define T_DBG 4
|
|
24 #define T_SEG 5
|
|
25 #define T_XMM 6
|
|
26
|
|
27 struct map_entry* ud_me_db();
|
|
28 struct map_entry* ud_me_invalid();
|
|
29
|
|
30 /* -----------------------------------------------------------------------------
|
|
31 * resolve_oprsize()- Resolves the size of operand depending on the current
|
|
32 * disassembly mode, effective operand sizes, etc.
|
|
33 * -----------------------------------------------------------------------------
|
|
34 */
|
|
35 static unsigned int
|
|
36 resolve_oprsize(register struct ud* u, unsigned int s)
|
|
37 {
|
|
38 switch (s) {
|
|
39 case SZ_V: return (u->opr_mode);
|
|
40 case SZ_Z: return (u->opr_mode == 16) ? 16 : 32;
|
|
41 case SZ_P: return (u->opr_mode == 16) ? SZ_WP : SZ_DP;
|
|
42 case SZ_MDQ: return (u->opr_mode == 16) ? 32 : u->opr_mode;
|
|
43 case SZ_RDQ: return (u->dis_mode == 64) ? 64 : 32;
|
|
44 default: return s;
|
|
45 }
|
|
46 }
|
|
47
|
|
48 /* -----------------------------------------------------------------------------
|
|
49 * resolve_mnemonic()- Resolves the correct mnemonic that depends on the
|
|
50 * current effective operand or address mode.
|
|
51 * -----------------------------------------------------------------------------
|
|
52 */
|
|
53 static enum ud_mnemonic_code
|
|
54 resolve_mnemonic(register struct ud* u)
|
|
55 {
|
|
56
|
|
57 if (u->opr_mode == 32) {
|
|
58 switch(u->mnemonic) {
|
|
59 case UD_Icbw: return UD_Icwde;
|
|
60 case UD_Icwd: return UD_Icdq;
|
|
61 case UD_Ilodsw: return UD_Ilodsd;
|
|
62 case UD_Imovsw: return UD_Imovsd;
|
|
63 case UD_Icmpsw: return UD_Icmpsd;
|
|
64 case UD_Iinsw: return UD_Iinsd;
|
|
65 case UD_Ioutsw: return UD_Ioutsd;
|
|
66 case UD_Ipushfw: return UD_Ipushfd;
|
|
67 case UD_Ipopfw: return UD_Ipopfd;
|
|
68 case UD_Istosw: return UD_Istosd;
|
|
69 case UD_Iscasw: return UD_Iscasd;
|
|
70 case UD_Iiretw: return UD_Iiretd;
|
|
71 case UD_Ipusha: return UD_Ipushad;
|
|
72 case UD_Ipopa: return UD_Ipopad;
|
|
73 default: break;
|
|
74 }
|
|
75 }
|
|
76
|
|
77 if (u->opr_mode == 64) {
|
|
78 switch(u->mnemonic) {
|
|
79 case UD_Icbw: return UD_Icdqe;
|
|
80 case UD_Icwd: return UD_Icqo;
|
|
81 case UD_Ilodsw: return UD_Ilodsq;
|
|
82 case UD_Imovsw: return UD_Imovsq;
|
|
83 case UD_Icmpsw: return UD_Icmpsq;
|
|
84 case UD_Iinsw: return UD_Iinsd;
|
|
85 case UD_Ioutsw: return UD_Ioutsd;
|
|
86 case UD_Icmpxchg8b: return UD_Icmpxchg16b;
|
|
87 case UD_Istosw: return UD_Istosq;
|
|
88 case UD_Iscasw: return UD_Iscasq;
|
|
89 case UD_Iiretw: return UD_Iiretq;
|
|
90 case UD_Ipushfw: return UD_Ipushfq;
|
|
91 case UD_Ipopfw: return UD_Ipopfq;
|
|
92 default: break;
|
|
93 }
|
|
94 }
|
|
95
|
|
96 if (u->mnemonic == UD_Iswapgs && u->dis_mode != 64) {
|
|
97 u->error = 1;
|
|
98 }
|
|
99
|
|
100 if (u->adr_mode == 32) {
|
|
101 switch(u->mnemonic) {
|
|
102 case UD_Ijcxz: return UD_Ijecxz;
|
|
103 default: break;
|
|
104 }
|
|
105 }
|
|
106
|
|
107 if (u->adr_mode == 64) {
|
|
108 switch(u->mnemonic) {
|
|
109 case UD_Ijcxz: return UD_Ijrcxz;
|
|
110 default: break;
|
|
111 }
|
|
112 }
|
|
113
|
|
114 return u->mnemonic;
|
|
115 }
|
|
116
|
|
117
|
|
118 /* -----------------------------------------------------------------------------
|
|
119 * decode_a()- Decodes operands of the type seg:offset
|
|
120 * -----------------------------------------------------------------------------
|
|
121 */
|
|
122 static void
|
|
123 decode_a(struct ud* u, struct ud_operand *op)
|
|
124 {
|
|
125 if (u->opr_mode == 16) {
|
|
126 /* seg16:off16 */
|
|
127 op->type = UD_OP_PTR;
|
|
128 op->size = 32;
|
|
129 op->lval.ptr.off = inp_uint16(u);
|
|
130 op->lval.ptr.seg = inp_uint16(u);
|
|
131 } else {
|
|
132 /* seg16:off32 */
|
|
133 op->type = UD_OP_PTR;
|
|
134 op->size = 48;
|
|
135 op->lval.ptr.off = inp_uint32(u);
|
|
136 op->lval.ptr.seg = inp_uint16(u);
|
|
137 }
|
|
138 }
|
|
139
|
|
140 /* -----------------------------------------------------------------------------
|
|
141 * decode_gpr() - Returns decoded General Purpose Register
|
|
142 * -----------------------------------------------------------------------------
|
|
143 */
|
|
144 static enum ud_type
|
|
145 decode_gpr(register struct ud* u, unsigned int s, unsigned char rm)
|
|
146 {
|
|
147 s = resolve_oprsize(u, s);
|
|
148
|
|
149 switch (s) {
|
|
150 case 64:
|
|
151 return UD_R_RAX + rm;
|
|
152 case SZ_DP:
|
|
153 case 32:
|
|
154 return UD_R_EAX + rm;
|
|
155 case SZ_WP:
|
|
156 case 16:
|
|
157 return UD_R_AX + rm;
|
|
158 case 8:
|
|
159 if (u->dis_mode == 64 && u->pfx_rex) {
|
|
160 if (rm >= 4)
|
|
161 return UD_R_SPL + (rm-4);
|
|
162 return UD_R_AL + rm;
|
|
163 } else return UD_R_AL + rm;
|
|
164 default:
|
|
165 return 0;
|
|
166 }
|
|
167 }
|
|
168
|
|
169 /* -----------------------------------------------------------------------------
|
|
170 * resolve_gpr64() - 64bit General Purpose Register-Selection.
|
|
171 * -----------------------------------------------------------------------------
|
|
172 */
|
|
173 static enum ud_type
|
|
174 resolve_gpr64(struct ud* u, enum map_operand_type gpr_op)
|
|
175 {
|
|
176 if (gpr_op >= OP_rAXr8 && gpr_op <= OP_rDIr15)
|
|
177 gpr_op = (gpr_op - OP_rAXr8) | (P_REX_B(u->pfx_rex) << 3);
|
|
178 else gpr_op = (gpr_op - OP_rAX);
|
|
179
|
|
180 if (u->opr_mode == 16)
|
|
181 return gpr_op + UD_R_AX;
|
|
182 if (u->dis_mode == 32 ||
|
|
183 (u->opr_mode == 32 && ! (P_REX_W(u->pfx_rex) || u->default64))) {
|
|
184 return gpr_op + UD_R_EAX;
|
|
185 }
|
|
186
|
|
187 return gpr_op + UD_R_RAX;
|
|
188 }
|
|
189
|
|
190 /* -----------------------------------------------------------------------------
|
|
191 * resolve_gpr32 () - 32bit General Purpose Register-Selection.
|
|
192 * -----------------------------------------------------------------------------
|
|
193 */
|
|
194 static enum ud_type
|
|
195 resolve_gpr32(struct ud* u, enum map_operand_type gpr_op)
|
|
196 {
|
|
197 gpr_op = gpr_op - OP_eAX;
|
|
198
|
|
199 if (u->opr_mode == 16)
|
|
200 return gpr_op + UD_R_AX;
|
|
201
|
|
202 return gpr_op + UD_R_EAX;
|
|
203 }
|
|
204
|
|
205 /* -----------------------------------------------------------------------------
|
|
206 * resolve_reg() - Resolves the register type
|
|
207 * -----------------------------------------------------------------------------
|
|
208 */
|
|
209 static enum ud_type
|
|
210 resolve_reg(struct ud* u, unsigned int type, unsigned char i)
|
|
211 {
|
|
212 switch (type) {
|
|
213 case T_MMX : return UD_R_MM0 + (i & 7);
|
|
214 case T_XMM : return UD_R_XMM0 + i;
|
|
215 case T_CRG : return UD_R_CR0 + i;
|
|
216 case T_DBG : return UD_R_DR0 + i;
|
|
217 case T_SEG : return UD_R_ES + (i & 7);
|
|
218 case T_NONE:
|
|
219 default: return UD_NONE;
|
|
220 }
|
|
221 }
|
|
222
|
|
223 /* -----------------------------------------------------------------------------
|
|
224 * decode_imm() - Decodes Immediate values.
|
|
225 * -----------------------------------------------------------------------------
|
|
226 */
|
|
227 static void
|
|
228 decode_imm(struct ud* u, unsigned int s, struct ud_operand *op)
|
|
229 {
|
|
230 op->size = resolve_oprsize(u, s);
|
|
231 op->type = UD_OP_IMM;
|
|
232
|
|
233 switch (op->size) {
|
|
234 case 8: op->lval.sbyte = inp_uint8(u); break;
|
|
235 case 16: op->lval.uword = inp_uint16(u); break;
|
|
236 case 32: op->lval.udword = inp_uint32(u); break;
|
|
237 case 64: op->lval.uqword = inp_uint64(u); break;
|
|
238 default: return;
|
|
239 }
|
|
240 }
|
|
241
|
|
242 /* -----------------------------------------------------------------------------
|
|
243 * decode_modrm() - Decodes ModRM Byte
|
|
244 * -----------------------------------------------------------------------------
|
|
245 */
|
|
246 static void
|
|
247 decode_modrm(struct ud* u, struct ud_operand *op, unsigned int s,
|
|
248 unsigned char rm_type, struct ud_operand *opreg,
|
|
249 unsigned char reg_size, unsigned char reg_type)
|
|
250 {
|
|
251 unsigned char mod, rm, reg;
|
|
252
|
|
253 inp_next(u);
|
|
254
|
|
255 /* get mod, r/m and reg fields */
|
|
256 mod = MODRM_MOD(inp_curr(u));
|
|
257 rm = (P_REX_B(u->pfx_rex) << 3) | MODRM_RM(inp_curr(u));
|
|
258 reg = (P_REX_R(u->pfx_rex) << 3) | MODRM_REG(inp_curr(u));
|
|
259
|
|
260 op->size = resolve_oprsize(u, s);
|
|
261
|
|
262 /* if mod is 11b, then the UD_R_m specifies a gpr/mmx/sse/control/debug */
|
|
263 if (mod == 3) {
|
|
264 op->type = UD_OP_REG;
|
|
265 if (rm_type == T_GPR)
|
|
266 op->base = decode_gpr(u, op->size, rm);
|
|
267 else op->base = resolve_reg(u, rm_type, (P_REX_R(u->pfx_rex) << 3) | (rm&7));
|
|
268 }
|
|
269 /* else its memory addressing */
|
|
270 else {
|
|
271 op->type = UD_OP_MEM;
|
|
272
|
|
273 /* 64bit addressing */
|
|
274 if (u->adr_mode == 64) {
|
|
275
|
|
276 op->base = UD_R_RAX + rm;
|
|
277
|
|
278 /* get offset type */
|
|
279 if (mod == 1)
|
|
280 op->offset = 8;
|
|
281 else if (mod == 2)
|
|
282 op->offset = 32;
|
|
283 else if (mod == 0 && (rm & 7) == 5) {
|
|
284 op->base = UD_R_RIP;
|
|
285 op->offset = 32;
|
|
286 } else op->offset = 0;
|
|
287
|
|
288 /* Scale-Index-Base (SIB) */
|
|
289 if ((rm & 7) == 4) {
|
|
290 inp_next(u);
|
|
291
|
|
292 op->scale = (1 << SIB_S(inp_curr(u))) & ~1;
|
|
293 op->index = UD_R_RAX + (SIB_I(inp_curr(u)) | (P_REX_X(u->pfx_rex) << 3));
|
|
294 op->base = UD_R_RAX + (SIB_B(inp_curr(u)) | (P_REX_B(u->pfx_rex) << 3));
|
|
295
|
|
296 /* special conditions for base reference */
|
|
297 if (op->index == UD_R_RSP) {
|
|
298 op->index = UD_NONE;
|
|
299 op->scale = UD_NONE;
|
|
300 }
|
|
301
|
|
302 if (op->base == UD_R_RBP || op->base == UD_R_R13) {
|
|
303 if (mod == 0)
|
|
304 op->base = UD_NONE;
|
|
305 if (mod == 1)
|
|
306 op->offset = 8;
|
|
307 else op->offset = 32;
|
|
308 }
|
|
309 }
|
|
310 }
|
|
311
|
|
312 /* 32-Bit addressing mode */
|
|
313 else if (u->adr_mode == 32) {
|
|
314
|
|
315 /* get base */
|
|
316 op->base = UD_R_EAX + rm;
|
|
317
|
|
318 /* get offset type */
|
|
319 if (mod == 1)
|
|
320 op->offset = 8;
|
|
321 else if (mod == 2)
|
|
322 op->offset = 32;
|
|
323 else if (mod == 0 && rm == 5) {
|
|
324 op->base = UD_NONE;
|
|
325 op->offset = 32;
|
|
326 } else op->offset = 0;
|
|
327
|
|
328 /* Scale-Index-Base (SIB) */
|
|
329 if ((rm & 7) == 4) {
|
|
330 inp_next(u);
|
|
331
|
|
332 op->scale = (1 << SIB_S(inp_curr(u))) & ~1;
|
|
333 op->index = UD_R_EAX + (SIB_I(inp_curr(u)) | (P_REX_X(u->pfx_rex) << 3));
|
|
334 op->base = UD_R_EAX + (SIB_B(inp_curr(u)) | (P_REX_B(u->pfx_rex) << 3));
|
|
335
|
|
336 if (op->index == UD_R_ESP) {
|
|
337 op->index = UD_NONE;
|
|
338 op->scale = UD_NONE;
|
|
339 }
|
|
340
|
|
341 /* special condition for base reference */
|
|
342 if (op->base == UD_R_EBP) {
|
|
343 if (mod == 0)
|
|
344 op->base = UD_NONE;
|
|
345 if (mod == 1)
|
|
346 op->offset = 8;
|
|
347 else op->offset = 32;
|
|
348 }
|
|
349 }
|
|
350 }
|
|
351
|
|
352 /* 16bit addressing mode */
|
|
353 else {
|
|
354 switch (rm) {
|
|
355 case 0: op->base = UD_R_BX; op->index = UD_R_SI; break;
|
|
356 case 1: op->base = UD_R_BX; op->index = UD_R_DI; break;
|
|
357 case 2: op->base = UD_R_BP; op->index = UD_R_SI; break;
|
|
358 case 3: op->base = UD_R_BP; op->index = UD_R_DI; break;
|
|
359 case 4: op->base = UD_R_SI; break;
|
|
360 case 5: op->base = UD_R_DI; break;
|
|
361 case 6: op->base = UD_R_BP; break;
|
|
362 case 7: op->base = UD_R_BX; break;
|
|
363 }
|
|
364
|
|
365 if (mod == 0 && rm == 6) {
|
|
366 op->offset= 16;
|
|
367 op->base = UD_NONE;
|
|
368 }
|
|
369 else if (mod == 1)
|
|
370 op->offset = 8;
|
|
371 else if (mod == 2)
|
|
372 op->offset = 16;
|
|
373 }
|
|
374 }
|
|
375
|
|
376 /* extract offset, if any */
|
|
377 switch(op->offset) {
|
|
378 case 8 : op->lval.ubyte = inp_uint8(u); break;
|
|
379 case 16: op->lval.uword = inp_uint16(u); break;
|
|
380 case 32: op->lval.udword = inp_uint32(u); break;
|
|
381 case 64: op->lval.uqword = inp_uint64(u); break;
|
|
382 default: break;
|
|
383 }
|
|
384
|
|
385 /* resolve register encoded in reg field */
|
|
386 if (opreg) {
|
|
387 opreg->type = UD_OP_REG;
|
|
388 opreg->size = resolve_oprsize(u, reg_size);
|
|
389 if (reg_type == T_GPR)
|
|
390 opreg->base = decode_gpr(u, opreg->size, reg);
|
|
391 else opreg->base = resolve_reg(u, reg_type, reg);
|
|
392 }
|
|
393 }
|
|
394
|
|
395 /* -----------------------------------------------------------------------------
|
|
396 * decode_o() - Decodes offset
|
|
397 * -----------------------------------------------------------------------------
|
|
398 */
|
|
399 static void
|
|
400 decode_o(struct ud* u, unsigned int s, struct ud_operand *op)
|
|
401 {
|
|
402 switch (u->adr_mode) {
|
|
403 case 64:
|
|
404 op->offset = 64;
|
|
405 op->lval.uqword = inp_uint64(u);
|
|
406 break;
|
|
407 case 32:
|
|
408 op->offset = 32;
|
|
409 op->lval.udword = inp_uint32(u);
|
|
410 break;
|
|
411 case 16:
|
|
412 op->offset = 16;
|
|
413 op->lval.uword = inp_uint16(u);
|
|
414 break;
|
|
415 default:
|
|
416 return;
|
|
417 }
|
|
418 op->type = UD_OP_MEM;
|
|
419 op->size = resolve_oprsize(u, s);
|
|
420 }
|
|
421
|
|
422 /* -----------------------------------------------------------------------------
|
|
423 * disasm_operands() - Disassembles Operands.
|
|
424 * -----------------------------------------------------------------------------
|
|
425 */
|
|
426 static void
|
|
427 disasm_operands(register struct ud* u)
|
|
428 {
|
|
429
|
|
430
|
|
431 /* mopXt = map entry, operand X, type; */
|
|
432 enum map_operand_type mop1t = u->mapen->operand1.type;
|
|
433 enum map_operand_type mop2t = u->mapen->operand2.type;
|
|
434 enum map_operand_type mop3t = u->mapen->operand3.type;
|
|
435
|
|
436 /* mopXs = map entry, operand X, size */
|
|
437 unsigned int mop1s = u->mapen->operand1.size;
|
|
438 unsigned int mop2s = u->mapen->operand2.size;
|
|
439 unsigned int mop3s = u->mapen->operand3.size;
|
|
440
|
|
441 /* iop = instruction operand */
|
|
442 register struct ud_operand* iop = u->operand;
|
|
443
|
|
444 switch(mop1t) {
|
|
445
|
|
446 case OP_A :
|
|
447 decode_a(u, &(iop[0]));
|
|
448 break;
|
|
449
|
|
450 /* M[b] ... */
|
|
451 case OP_M :
|
|
452 if (MODRM_MOD(inp_peek(u)) == 3)
|
|
453 u->error= 1;
|
|
454 /* E, G/P/V/I/CL/1/S */
|
|
455 case OP_E :
|
|
456 if (mop2t == OP_G) {
|
|
457 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_GPR);
|
|
458 if (mop3t == OP_I)
|
|
459 decode_imm(u, mop3s, &(iop[2]));
|
|
460 else if (mop3t == OP_CL) {
|
|
461 iop[2].type = UD_OP_REG;
|
|
462 iop[2].base = UD_R_CL;
|
|
463 iop[2].size = 8;
|
|
464 }
|
|
465 }
|
|
466 else if (mop2t == OP_P)
|
|
467 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_MMX);
|
|
468 else if (mop2t == OP_V)
|
|
469 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_XMM);
|
|
470 else if (mop2t == OP_S)
|
|
471 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_SEG);
|
|
472 else {
|
|
473 decode_modrm(u, &(iop[0]), mop1s, T_GPR, NULL, 0, T_NONE);
|
|
474 if (mop2t == OP_CL) {
|
|
475 iop[1].type = UD_OP_REG;
|
|
476 iop[1].base = UD_R_CL;
|
|
477 iop[1].size = 8;
|
|
478 } else if (mop2t == OP_I1) {
|
|
479 iop[1].type = UD_OP_CONST;
|
|
480 u->operand[1].lval.udword = 1;
|
|
481 } else if (mop2t == OP_I)
|
|
482 decode_imm(u, mop2s, &(iop[1]));
|
|
483 }
|
|
484 break;
|
|
485
|
|
486 /* G, E/PR[,I]/VR */
|
|
487 case OP_G :
|
|
488
|
|
489 if (mop2t == OP_M) {
|
|
490 if (MODRM_MOD(inp_peek(u)) == 3)
|
|
491 u->error= 1;
|
|
492 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_GPR);
|
|
493 } else if (mop2t == OP_E) {
|
|
494 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_GPR);
|
|
495 if (mop3t == OP_I)
|
|
496 decode_imm(u, mop3s, &(iop[2]));
|
|
497 } else if (mop2t == OP_PR) {
|
|
498 decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_GPR);
|
|
499 if (mop3t == OP_I)
|
|
500 decode_imm(u, mop3s, &(iop[2]));
|
|
501 } else if (mop2t == OP_VR) {
|
|
502 if (MODRM_MOD(inp_peek(u)) != 3)
|
|
503 u->error = 1;
|
|
504 decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_GPR);
|
|
505 } else if (mop2t == OP_W)
|
|
506 decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_GPR);
|
|
507 break;
|
|
508
|
|
509 /* AL..BH, I/O/DX */
|
|
510 case OP_AL : case OP_CL : case OP_DL : case OP_BL :
|
|
511 case OP_AH : case OP_CH : case OP_DH : case OP_BH :
|
|
512
|
|
513 iop[0].type = UD_OP_REG;
|
|
514 iop[0].base = UD_R_AL + (mop1t - OP_AL);
|
|
515 iop[0].size = 8;
|
|
516
|
|
517 if (mop2t == OP_I)
|
|
518 decode_imm(u, mop2s, &(iop[1]));
|
|
519 else if (mop2t == OP_DX) {
|
|
520 iop[1].type = UD_OP_REG;
|
|
521 iop[1].base = UD_R_DX;
|
|
522 iop[1].size = 16;
|
|
523 }
|
|
524 else if (mop2t == OP_O)
|
|
525 decode_o(u, mop2s, &(iop[1]));
|
|
526 break;
|
|
527
|
|
528 /* rAX[r8]..rDI[r15], I/rAX..rDI/O */
|
|
529 case OP_rAXr8 : case OP_rCXr9 : case OP_rDXr10 : case OP_rBXr11 :
|
|
530 case OP_rSPr12: case OP_rBPr13: case OP_rSIr14 : case OP_rDIr15 :
|
|
531 case OP_rAX : case OP_rCX : case OP_rDX : case OP_rBX :
|
|
532 case OP_rSP : case OP_rBP : case OP_rSI : case OP_rDI :
|
|
533
|
|
534 iop[0].type = UD_OP_REG;
|
|
535 iop[0].base = resolve_gpr64(u, mop1t);
|
|
536
|
|
537 if (mop2t == OP_I)
|
|
538 decode_imm(u, mop2s, &(iop[1]));
|
|
539 else if (mop2t >= OP_rAX && mop2t <= OP_rDI) {
|
|
540 iop[1].type = UD_OP_REG;
|
|
541 iop[1].base = resolve_gpr64(u, mop2t);
|
|
542 }
|
|
543 else if (mop2t == OP_O) {
|
|
544 decode_o(u, mop2s, &(iop[1]));
|
|
545 iop[0].size = resolve_oprsize(u, mop2s);
|
|
546 }
|
|
547 break;
|
|
548
|
|
549 /* AL[r8b]..BH[r15b], I */
|
|
550 case OP_ALr8b : case OP_CLr9b : case OP_DLr10b : case OP_BLr11b :
|
|
551 case OP_AHr12b: case OP_CHr13b: case OP_DHr14b : case OP_BHr15b :
|
|
552 {
|
|
553 ud_type_t gpr = (mop1t - OP_ALr8b) + UD_R_AL +
|
|
554 (P_REX_B(u->pfx_rex) << 3);
|
|
555 if (UD_R_AH <= gpr && u->pfx_rex)
|
|
556 gpr = gpr + 4;
|
|
557 iop[0].type = UD_OP_REG;
|
|
558 iop[0].base = gpr;
|
|
559 if (mop2t == OP_I)
|
|
560 decode_imm(u, mop2s, &(iop[1]));
|
|
561 break;
|
|
562 }
|
|
563
|
|
564 /* eAX..eDX, DX/I */
|
|
565 case OP_eAX : case OP_eCX : case OP_eDX : case OP_eBX :
|
|
566 case OP_eSP : case OP_eBP : case OP_eSI : case OP_eDI :
|
|
567
|
|
568 iop[0].type = UD_OP_REG;
|
|
569 iop[0].base = resolve_gpr32(u, mop1t);
|
|
570 if (mop2t == OP_DX) {
|
|
571 iop[1].type = UD_OP_REG;
|
|
572 iop[1].base = UD_R_DX;
|
|
573 iop[1].size = 16;
|
|
574 } else if (mop2t == OP_I)
|
|
575 decode_imm(u, mop2s, &(iop[1]));
|
|
576 break;
|
|
577
|
|
578 /* ES..GS */
|
|
579 case OP_ES : case OP_CS : case OP_DS :
|
|
580 case OP_SS : case OP_FS : case OP_GS :
|
|
581
|
|
582 /* in 64bits mode, only fs and gs are allowed */
|
|
583 if (u->dis_mode == 64)
|
|
584 if (mop1t != OP_FS && mop1t != OP_GS)
|
|
585 u->error= 1;
|
|
586 iop[0].type = UD_OP_REG;
|
|
587 iop[0].base = (mop1t - OP_ES) + UD_R_ES;
|
|
588 iop[0].size = 16;
|
|
589
|
|
590 break;
|
|
591
|
|
592 /* J */
|
|
593 case OP_J :
|
|
594 decode_imm(u, mop1s, &(iop[0]));
|
|
595 iop[0].type = UD_OP_JIMM;
|
|
596 break ;
|
|
597
|
|
598 /* PR, I */
|
|
599 case OP_PR:
|
|
600 if (MODRM_MOD(inp_peek(u)) != 3)
|
|
601 u->error = 1;
|
|
602 decode_modrm(u, &(iop[0]), mop1s, T_MMX, NULL, 0, T_NONE);
|
|
603 if (mop2t == OP_I)
|
|
604 decode_imm(u, mop2s, &(iop[1]));
|
|
605 break;
|
|
606
|
|
607 /* VR, I */
|
|
608 case OP_VR:
|
|
609 if (MODRM_MOD(inp_peek(u)) != 3)
|
|
610 u->error = 1;
|
|
611 decode_modrm(u, &(iop[0]), mop1s, T_XMM, NULL, 0, T_NONE);
|
|
612 if (mop2t == OP_I)
|
|
613 decode_imm(u, mop2s, &(iop[1]));
|
|
614 break;
|
|
615
|
|
616 /* P, Q[,I]/W/E[,I] */
|
|
617 case OP_P :
|
|
618 if (mop2t == OP_Q) {
|
|
619 decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_MMX);
|
|
620 if (mop3t == OP_I)
|
|
621 decode_imm(u, mop3s, &(iop[2]));
|
|
622 } else if (mop2t == OP_W)
|
|
623 decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_MMX);
|
|
624 else if (mop2t == OP_E) {
|
|
625 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_MMX);
|
|
626 if (mop3t == OP_I)
|
|
627 decode_imm(u, mop3s, &(iop[2]));
|
|
628 }
|
|
629 break;
|
|
630
|
|
631 /* R, C/D */
|
|
632 case OP_R :
|
|
633 if (mop2t == OP_C)
|
|
634 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_CRG);
|
|
635 else if (mop2t == OP_D)
|
|
636 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_DBG);
|
|
637 break;
|
|
638
|
|
639 /* C, R */
|
|
640 case OP_C :
|
|
641 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_CRG);
|
|
642 break;
|
|
643
|
|
644 /* D, R */
|
|
645 case OP_D :
|
|
646 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_DBG);
|
|
647 break;
|
|
648
|
|
649 /* Q, P */
|
|
650 case OP_Q :
|
|
651 decode_modrm(u, &(iop[0]), mop1s, T_MMX, &(iop[1]), mop2s, T_MMX);
|
|
652 break;
|
|
653
|
|
654 /* S, E */
|
|
655 case OP_S :
|
|
656 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_SEG);
|
|
657 break;
|
|
658
|
|
659 /* W, V */
|
|
660 case OP_W :
|
|
661 decode_modrm(u, &(iop[0]), mop1s, T_XMM, &(iop[1]), mop2s, T_XMM);
|
|
662 break;
|
|
663
|
|
664 /* V, W[,I]/Q/M/E */
|
|
665 case OP_V :
|
|
666 if (mop2t == OP_W) {
|
|
667 /* special cases for movlps and movhps */
|
|
668 if (MODRM_MOD(inp_peek(u)) == 3) {
|
|
669 if (u->mnemonic == UD_Imovlps)
|
|
670 u->mnemonic = UD_Imovhlps;
|
|
671 else
|
|
672 if (u->mnemonic == UD_Imovhps)
|
|
673 u->mnemonic = UD_Imovlhps;
|
|
674 }
|
|
675 decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_XMM);
|
|
676 if (mop3t == OP_I)
|
|
677 decode_imm(u, mop3s, &(iop[2]));
|
|
678 } else if (mop2t == OP_Q)
|
|
679 decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_XMM);
|
|
680 else if (mop2t == OP_M) {
|
|
681 if (MODRM_MOD(inp_peek(u)) == 3)
|
|
682 u->error= 1;
|
|
683 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM);
|
|
684 } else if (mop2t == OP_E) {
|
|
685 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM);
|
|
686 }
|
|
687 break;
|
|
688
|
|
689 /* DX, eAX/AL */
|
|
690 case OP_DX :
|
|
691 iop[0].type = UD_OP_REG;
|
|
692 iop[0].base = UD_R_DX;
|
|
693 iop[0].size = 16;
|
|
694
|
|
695 if (mop2t == OP_eAX) {
|
|
696 iop[1].type = UD_OP_REG;
|
|
697 iop[1].base = resolve_gpr32(u, mop2t);
|
|
698 } else if (mop2t == OP_AL) {
|
|
699 iop[1].type = UD_OP_REG;
|
|
700 iop[1].base = UD_R_AL;
|
|
701 iop[1].size = 8;
|
|
702 }
|
|
703
|
|
704 break;
|
|
705
|
|
706 /* I, I/AL/eAX */
|
|
707 case OP_I :
|
|
708 decode_imm(u, mop1s, &(iop[0]));
|
|
709 if (mop2t == OP_I)
|
|
710 decode_imm(u, mop2s, &(iop[1]));
|
|
711 else if (mop2t == OP_AL) {
|
|
712 iop[1].type = UD_OP_REG;
|
|
713 iop[1].base = UD_R_AL;
|
|
714 iop[1].size = 16;
|
|
715 } else if (mop2t == OP_eAX) {
|
|
716 iop[1].type = UD_OP_REG;
|
|
717 iop[1].base = resolve_gpr32(u, mop2t);
|
|
718 }
|
|
719 break;
|
|
720
|
|
721 /* O, AL/eAX */
|
|
722 case OP_O :
|
|
723 decode_o(u, mop1s, &(iop[0]));
|
|
724 iop[1].type = UD_OP_REG;
|
|
725 iop[1].size = resolve_oprsize(u, mop1s);
|
|
726 if (mop2t == OP_AL)
|
|
727 iop[1].base = UD_R_AL;
|
|
728 else if (mop2t == OP_eAX)
|
|
729 iop[1].base = resolve_gpr32(u, mop2t);
|
|
730 else if (mop2t == OP_rAX)
|
|
731 iop[1].base = resolve_gpr64(u, mop2t);
|
|
732 break;
|
|
733
|
|
734 /* 3 */
|
|
735 case OP_I3 :
|
|
736 iop[0].type = UD_OP_CONST;
|
|
737 iop[0].lval.sbyte = 3;
|
|
738 break;
|
|
739
|
|
740 /* ST(n), ST(n) */
|
|
741 case OP_ST0 : case OP_ST1 : case OP_ST2 : case OP_ST3 :
|
|
742 case OP_ST4 : case OP_ST5 : case OP_ST6 : case OP_ST7 :
|
|
743
|
|
744 iop[0].type = UD_OP_REG;
|
|
745 iop[0].base = (mop1t-OP_ST0) + UD_R_ST0;
|
|
746 iop[0].size = 0;
|
|
747
|
|
748 if (mop2t >= OP_ST0 && mop2t <= OP_ST7) {
|
|
749 iop[1].type = UD_OP_REG;
|
|
750 iop[1].base = (mop2t-OP_ST0) + UD_R_ST0;
|
|
751 iop[1].size = 0;
|
|
752 }
|
|
753 break;
|
|
754
|
|
755 /* AX */
|
|
756 case OP_AX:
|
|
757 iop[0].type = UD_OP_REG;
|
|
758 iop[0].base = UD_R_AX;
|
|
759 iop[0].size = 16;
|
|
760 break;
|
|
761
|
|
762 /* none */
|
|
763 default :
|
|
764 iop[0].type = iop[1].type = iop[2].type = UD_NONE;
|
|
765 }
|
|
766 }
|
|
767
|
|
768 /* -----------------------------------------------------------------------------
|
|
769 * clear_insn() - clear instruction pointer
|
|
770 * -----------------------------------------------------------------------------
|
|
771 */
|
|
772 void clear_insn(register struct ud* u)
|
|
773 {
|
|
774 u->error = 0;
|
|
775 u->pfx_seg = 0;
|
|
776 u->pfx_opr = 0;
|
|
777 u->pfx_adr = 0;
|
|
778 u->pfx_lock = 0;
|
|
779 u->pfx_repne = 0;
|
|
780 u->pfx_rep = 0;
|
|
781 u->pfx_seg = 0;
|
|
782 u->pfx_rex = 0;
|
|
783 u->pfx_insn= 0;
|
|
784 u->mnemonic = UD_Inone;
|
|
785 u->mapen = NULL;
|
|
786
|
|
787 memset(&u->operand[0], 0, sizeof(struct ud_operand));
|
|
788 memset(&u->operand[1], 0, sizeof(struct ud_operand));
|
|
789 memset(&u->operand[2], 0, sizeof(struct ud_operand));
|
|
790 }
|
|
791
|
|
792 /* =============================================================================
|
|
793 * ud_decode() - Instruction decoder. Returns the number of bytes decoded.
|
|
794 * =============================================================================
|
|
795 */
|
|
796 extern unsigned int ud_decode(register struct ud* u)
|
|
797 {
|
|
798 unsigned int p; /* (bool) denotes end of prefixes */
|
|
799 unsigned int i; /* prefix counter */
|
|
800 char* src_hex;
|
|
801 unsigned char *src_ptr;
|
|
802
|
|
803 inp_start(u);
|
|
804
|
|
805 /* [1] Clear the decode/output fields */
|
|
806
|
|
807 clear_insn(u);
|
|
808
|
|
809 /* [2] Extract Prefixes */
|
|
810
|
|
811 inp_next(u);
|
|
812
|
|
813 for (i = 0, p = 0; p == 0; ++i) {
|
|
814 if ((inp_curr(u) & 0xF0) == 0x40) { /* REX */
|
|
815 if (u->dis_mode == 64) {
|
|
816 u->pfx_rex = inp_curr(u);
|
|
817 inp_next(u);
|
|
818 } else p = 1; /* Bail out, its an inc/dec */
|
|
819 }
|
|
820 else switch(inp_curr(u)) {
|
|
821 case 0x2E : u->pfx_seg = UD_R_CS; inp_next(u); break;
|
|
822 case 0x36 : u->pfx_seg = UD_R_SS; inp_next(u); break;
|
|
823 case 0x3E : u->pfx_seg = UD_R_DS; inp_next(u); break;
|
|
824 case 0x26 : u->pfx_seg = UD_R_ES; inp_next(u); break;
|
|
825 case 0x64 : u->pfx_seg = UD_R_FS; inp_next(u); break;
|
|
826 case 0x65 : u->pfx_seg = UD_R_GS; inp_next(u); break;
|
|
827 case 0x66 : u->pfx_insn = u->pfx_opr = 0x66; inp_next(u); break;
|
|
828 case 0x67 : u->pfx_adr = 0x67; inp_next(u); break;
|
|
829 case 0xF0 : u->pfx_lock= 0xF0; inp_next(u); break;
|
|
830 case 0xF2 : u->pfx_insn = u->pfx_repne=0xF2; inp_next(u); break;
|
|
831 case 0xF3 : u->pfx_insn = u->pfx_rep = 0xF3; inp_next(u); break;
|
|
832 default : p = 1;
|
|
833 }
|
|
834
|
|
835 /* if >= MAX_PREFIXES, disintegrate */
|
|
836 if (i >= MAX_PREFIXES) {
|
|
837 u->error= 1;
|
|
838 break;
|
|
839 }
|
|
840 }
|
|
841
|
|
842 /* rewind back one byte in stream */
|
|
843 inp_back(u);
|
|
844
|
|
845 /* [3] Search opcode map */
|
|
846
|
|
847 ud_search_map(u);
|
|
848
|
|
849 /* [4] Set mode flags */
|
|
850
|
|
851 if (u->dis_mode == 64) { /* set 64bit-mode flags */
|
|
852 u->pfx_rex = u->pfx_rex & P_REX_MASK(u->mapen->prefix);
|
|
853 u->default64 = P_DEF64(u->mapen->prefix);
|
|
854 u->error = P_INV64(u->mapen->prefix);
|
|
855
|
|
856 if (P_REX(u->mapen->prefix) && P_REX_W(u->pfx_rex))
|
|
857 u->opr_mode = 64;
|
|
858 else if (u->pfx_opr)
|
|
859 u->opr_mode = 16;
|
|
860 else u->opr_mode = (u->default64) ? 64 : 32;
|
|
861
|
|
862 u->adr_mode = (u->pfx_adr) ? 32 : 64;
|
|
863 }
|
|
864 else if (u->dis_mode == 32) { /* set 32bit-mode flags */
|
|
865 u->opr_mode = (u->pfx_opr) ? 16 : 32;
|
|
866 u->adr_mode = (u->pfx_adr) ? 16 : 32;
|
|
867 }
|
|
868 else if (u->dis_mode == 16) { /* set 16bit-mode flags */
|
|
869 u->opr_mode = (u->pfx_opr) ? 32 : 16;
|
|
870 u->adr_mode = (u->pfx_adr) ? 32 : 16;
|
|
871 }
|
|
872
|
|
873 u->c1 = (P_C1(u->mapen->prefix)) ? 1 : 0;
|
|
874 u->c2 = (P_C2(u->mapen->prefix)) ? 1 : 0;
|
|
875 u->c3 = (P_C3(u->mapen->prefix)) ? 1 : 0;
|
|
876
|
|
877 /* [5] Disassembled operands */
|
|
878
|
|
879 disasm_operands(u);
|
|
880
|
|
881 /* [6] Resolve mode related and other mnemonic issues */
|
|
882
|
|
883 if (P_DEPM(u->mapen->prefix))
|
|
884 u->mnemonic = resolve_mnemonic(u);
|
|
885
|
|
886 u->br_far = 0;
|
|
887 u->br_near = 0;
|
|
888
|
|
889 if (u->mnemonic == UD_Icall || u->mnemonic == UD_Ijmp) {
|
|
890 if (u->operand[0].size == SZ_WP) {
|
|
891 u->operand[0].size = 16;
|
|
892 u->br_far = 1;
|
|
893 u->br_near= 0;
|
|
894 } else if (u->operand[0].size == SZ_DP) {
|
|
895 u->operand[0].size = 32;
|
|
896 u->br_far = 1;
|
|
897 u->br_near= 0;
|
|
898 } else {
|
|
899 u->br_far = 0;
|
|
900 u->br_near= 1;
|
|
901 }
|
|
902 } else if (u->mnemonic == UD_I3dnow)
|
|
903 u->mnemonic = ud_map_get_3dnow(inp_curr(u));
|
|
904
|
|
905 /* [7] Check for errors */
|
|
906
|
|
907 if (u->error) {
|
|
908 clear_insn(u);
|
|
909 u->mapen = ud_me_invalid();
|
|
910 u->mnemonic = u->mapen->mnemonic;
|
|
911 }
|
|
912
|
|
913 /* [8] Generate hexadecimal code */
|
|
914
|
|
915 u->insn_offset = u->pc;
|
|
916 u->insn_fill = 0;
|
|
917 src_ptr = inp_sess(u);
|
|
918
|
|
919 src_hex = (char*) u->insn_hexcode;
|
|
920
|
|
921 for (i = 0; i < u->inp_ctr; ++i, ++src_ptr) {
|
|
922 sprintf(src_hex, "%02x", *src_ptr & 0xFF);
|
|
923 src_hex += 2;
|
|
924 }
|
|
925
|
|
926 /* [9] Update program counter */
|
|
927
|
|
928 u->pc += u->inp_ctr;
|
|
929
|
|
930 /* [10] Return the number of bytes disassemled */
|
|
931
|
|
932 return u->inp_ctr;
|
|
933 }
|