Mercurial > projects > ddbg_continued
comparison udis86-1.4/libudis86/decode.c @ 1:4a9dcbd9e54f
-files of 0.13 beta
-fixes so that it now compiles with the current dmd version
author | marton@basel.hu |
---|---|
date | Tue, 05 Apr 2011 20:44:01 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:586e4a649642 | 1:4a9dcbd9e54f |
---|---|
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 } |