§ Как использовать
Ниже представлен код 2х файлов:
Для того, чтобы начать ими пользоваться, надо добавить в проект такое объявление:
1unsigned char* memory = (unsigned char*)malloc(1024*1024);
2Disassemble* dasm = new Disassemble(memory);
Это минимально, что надо сделать.
§ Основной код
Ниже представлен код disasm.cc:
1#include "disasm.h"
2
3class Disassemble {
4
5protected:
6
7 int eip;
8 int reg, mod, rm;
9 char tmps[256];
10 char dis_row[256];
11 char dis_rg[32];
12 char dis_rm[32];
13 char dis_px[32];
14 int max_memory;
15 unsigned char* memory;
16
17public:
18
19 Disassemble(unsigned char* _mem) {
20
21 memory = _mem;
22 max_memory = 0xfffff;
23 }
24
25 int readb(int address) {
26 return memory[address & max_memory];
27 }
28
29 int fetchb() {
30
31 int a = readb(eip);
32 eip = (eip + 1) & 0xfffff;
33 return a;
34 }
35
36 int fetchw() { int a = fetchb(); int b = fetchb(); return b*256 + a; }
37 int fetchd() { int a = fetchw(); int b = fetchw(); return b*65536 + a; }
38
39
40 int disas_modrm(int reg32, int mem32) {
41
42 int n = 0, b, w;
43
44
45 dis_rg[0] = 0;
46 dis_rm[0] = 0;
47
48 b = fetchb(); n++;
49
50 rm = (b & 0x07);
51 reg = (b & 0x38) >> 3;
52 mod = (b & 0xc0);
53
54
55 switch (reg32) {
56 case 0x08: sprintf(dis_rg, "%s", regnames[ reg ]); break;
57 case 0x10: sprintf(dis_rg, "%s", regnames[ reg + 0x08 ]); break;
58 case 0x20: sprintf(dis_rg, "%s", regnames[ reg + 0x10 ]); break;
59 default: sprintf(dis_rg, "<unknown>"); break;
60 }
61
62
63 if (mem32 == 0) {
64
65
66 switch (mod) {
67
68
69 case 0x00:
70
71 if (rm == 6) {
72 w = fetchw(); n += 2;
73 sprintf(dis_rm, "[%s%04x]", dis_px, w);
74 } else {
75 sprintf(dis_rm, "[%s%s]", dis_px, rm16names[ rm ]);
76 }
77
78 break;
79
80
81 case 0x40:
82
83 b = fetchb(); n++;
84 if (b & 0x80) {
85 sprintf(dis_rm, "[%s%s-%02x]", dis_px, rm16names[ rm ], (0xff ^ b) + 1);
86 } else if (b == 0) {
87 sprintf(dis_rm, "[%s%s]", dis_px, rm16names[ rm ]);
88 } else {
89 sprintf(dis_rm, "[%s%s+%02x]", dis_px, rm16names[ rm ], b);
90 }
91
92 break;
93
94
95 case 0x80:
96
97 w = fetchw(); n += 2;
98 if (w & 0x8000) {
99 sprintf(dis_rm, "[%s%s-%04x]", dis_px, rm16names[ rm ], (0xFFFF ^ w) + 1);
100 } else if (w == 0) {
101 sprintf(dis_rm, "[%s%s]", dis_px, rm16names[ rm ]);
102 } else {
103 sprintf(dis_rm, "[%s%s+%04x]", dis_px, rm16names[ rm ], w);
104 }
105
106 break;
107
108
109 case 0xc0:
110
111 switch (reg32) {
112 case 0x08: sprintf(dis_rm, "%s", regnames[ rm ]); break;
113 case 0x10: sprintf(dis_rm, "%s", regnames[ rm + 0x08 ]); break;
114 case 0x20: sprintf(dis_rm, "%s", regnames[ rm + 0x10 ]); break;
115 }
116
117 break;
118 }
119 }
120
121 else {
122
123 int sib = 0, sibhas = 0;
124
125 switch (mod) {
126
127 case 0x00:
128
129 if (rm == 5) {
130
131 w = fetchd(); n += 4;
132 sprintf(dis_rm, "[%s%08x]", dis_px, w);
133
134 } else if (rm == 4) {
135
136 sib = fetchb(); n++;
137 sibhas = 1;
138
139 } else {
140 sprintf(dis_rm, "[%s%s]", dis_px, regnames[0x10 + rm]);
141 }
142
143 break;
144
145
146 case 0x40:
147
148
149 if (rm == 4) {
150
151 sib = fetchb(); n++;
152 sibhas = 1;
153
154 } else {
155
156 b = fetchb(); n++;
157
158 if (b & 0x80) {
159 sprintf(dis_rm, "[%s%s-%02x]", dis_px, regnames[ 0x10 + rm ], (0xff ^ b) + 1);
160 } else if (b == 0) {
161 sprintf(dis_rm, "[%s%s]", dis_px, regnames[ 0x10 + rm ]);
162 } else {
163 sprintf(dis_rm, "[%s%s+%02x]", dis_px, regnames[ 0x10 + rm ], b);
164 }
165 }
166
167 break;
168
169
170 case 0x80:
171
172
173 if (rm == 4) {
174
175 sib = fetchb(); n++;
176 sibhas = 1;
177
178 } else {
179
180 w = fetchd(); n += 4;
181
182 if (w & 0x80000000) {
183 sprintf(dis_rm, "[%s%s-%04x]", dis_px, regnames[ 0x10 + rm ], (0xFFFFFFFF ^ w) + 1);
184 } else if (w == 0) {
185 sprintf(dis_rm, "[%s%s]", dis_px, regnames[ 0x10 + rm ]);
186 } else {
187 sprintf(dis_rm, "[%s%s+%04x]", dis_px, regnames[ 0x10 + rm ], w);
188 }
189 }
190
191 break;
192
193
194 case 0xc0:
195
196 switch (reg32) {
197 case 0x08: sprintf(dis_rm, "%s", regnames[ rm ]); break;
198 case 0x10: sprintf(dis_rm, "%s", regnames[ rm + 0x08 ]); break;
199 case 0x20: sprintf(dis_rm, "%s", regnames[ rm + 0x10 ]); break;
200 }
201
202 break;
203 }
204
205
206 if (sibhas) {
207
208 char cdisp32[16]; cdisp32[0] = 0;
209
210 int disp = 0;
211 int sib_ss = (sib & 0xc0);
212 int sib_ix = (sib & 0x38) >> 3;
213 int sib_bs = (sib & 0x07);
214
215
216 switch (mod) {
217
218 case 0x40:
219
220 disp = fetchb(); n += 1;
221
222 if (disp & 0x80) {
223 sprintf(cdisp32, "-%02X", (disp ^ 0xff) + 1);
224 } else {
225 sprintf(cdisp32, "+%02X", disp);
226 }
227
228 break;
229
230 case 0x80:
231 case 0xc0:
232
233 disp = fetchd(); n += 4;
234 if (disp & 0x80000000) {
235 sprintf(cdisp32, "-%08X", (disp ^ 0xffffffff) + 1);
236 } else {
237 sprintf(cdisp32, "+%08X", disp);
238 }
239 break;
240 }
241
242
243 if (sib_ix == 4) {
244
245 sprintf(dis_rm, "[%s%s]", dis_px, regnames[ 0x10 + sib_bs ]);
246
247 } else {
248
249 switch (sib_ss) {
250
251 case 0x00:
252
253 sprintf(dis_rm, "[%s%s+%s]", dis_px, regnames[ 0x10 + sib_bs ], regnames[ 0x10 + sib_ix ]);
254 break;
255
256 case 0x40:
257
258 sprintf(dis_rm, "[%s%s+2*%s%s]", dis_px, regnames[ 0x10 + sib_bs ], regnames[ 0x10 + sib_ix ], cdisp32);
259 break;
260
261 case 0x80:
262
263 sprintf(dis_rm, "[%s%s+4*%s%s]", dis_px, regnames[ 0x10 + sib_bs ], regnames[ 0x10 + sib_ix ], cdisp32);
264 break;
265
266 case 0xc0:
267
268 sprintf(dis_rm, "[%s%s+8*%s%s]", dis_px, regnames[ 0x10 + sib_bs ], regnames[ 0x10 + sib_ix ], cdisp32);
269 break;
270 }
271 }
272 }
273 }
274
275 return n;
276 }
277
278
279 int disassemble(int address) {
280
281 eip = address & max_memory;
282
283 int ereg = 0;
284 int emem = 0;
285 int stop = 0;
286 char dis_pf[8];
287 char dis_cmd [32];
288 char dis_cmd2[64];
289 char dis_ops[128];
290 char dis_dmp[128];
291 char dis_sfx[8];
292
293 int n = 0, i, j, d, opcode = 0;
294 int elock = 0;
295
296
297 dis_px[0] = 0;
298 dis_pf[0] = 0;
299 dis_ops[0] = 0;
300 dis_dmp[0] = 0;
301 dis_sfx[0] = 0;
302
303
304 for (i = 0; i < 6; i++) {
305
306 d = fetchb();
307 n++;
308
309 switch (d) {
310 case 0x0F: opcode |= 0x100; break;
311 case 0x26: sprintf(dis_px, "%s", "es:"); break;
312 case 0x2E: sprintf(dis_px, "%s", "cs:"); break;
313 case 0x36: sprintf(dis_px, "%s", "ss:"); break;
314 case 0x3E: sprintf(dis_px, "%s", "ss:"); break;
315 case 0x64: sprintf(dis_px, "%s", "fs:"); break;
316 case 0x65: sprintf(dis_px, "%s", "gs:"); break;
317 case 0x66: ereg = ereg ^ 1; break;
318 case 0x67: emem = emem ^ 1; break;
319 case 0xf0: elock = 1; break;
320 case 0xf2: sprintf(dis_pf, "%s", "repnz "); break;
321 case 0xf3: sprintf(dis_pf, "%s", "rep "); break;
322 default: opcode |= d; stop = 1; break;
323 }
324
325 if (stop) break;
326 }
327
328 int opdec = ops[ opcode & 255 ];
329 int hasmodrm = modrm_lookup[ opcode ];
330
331
332 if (opdec != 0xff) {
333 sprintf(dis_cmd, "%s", mnemonics[ opdec ] );
334 }
335
336
337 if (hasmodrm) {
338
339
340 int regsize = opcode & 1 ? (ereg ? 32 : 16) : 8;
341 int swmod = opcode & 2;
342
343 if (opcode == 0x62) regsize = (ereg ? 32 : 16);
344
345
346 if (opcode == 0x63) swmod = 0;
347 if (opcode == 0x8D || opcode == 0xC4 || opcode == 0xC5) swmod = 1;
348
349
350 if (opcode == 0x8C || opcode == 0x8E ||
351 opcode == 0xC4) regsize = (ereg ? 32 : 16);
352
353
354 n += disas_modrm(regsize, emem ? 0x20 : 0x00);
355
356
357 if (opcode == 0x80 || opcode == 0x82) {
358
359 sprintf(dis_cmd, "%s", mnemonics[ reg ] );
360 sprintf(dis_ops, "%s, %02X", dis_rm, fetchb()); n++;
361 }
362
363
364 else if (opcode == 0x81) {
365
366 sprintf(dis_cmd, "%s", mnemonics[ reg ] );
367
368 if (ereg) {
369 sprintf(dis_ops, "%s, %08X", dis_rm, fetchd()); n += 4;
370 } else {
371 sprintf(dis_ops, "%s, %04X", dis_rm, fetchw()); n += 2;
372 }
373 }
374
375
376 else if (opcode == 0x83) {
377
378 int b8 = fetchb(); n++;
379 sprintf(dis_cmd, "%s", mnemonics[ reg ] );
380
381 if (ereg) {
382 sprintf(dis_ops, "%s, %08X", dis_rm, b8 | (b8 & 0x80 ? 0xFFFFFF00 : 0));
383 } else {
384 sprintf(dis_ops, "%s, %04X", dis_rm, b8 | (b8 & 0x80 ? 0xFF00 : 0));
385 }
386 }
387
388
389 else if (opcode == 0x69) {
390
391 if (ereg) {
392 sprintf(dis_ops, "%s, %s, %08X", dis_rg, dis_rm, fetchd() ); n += 4;
393 } else {
394 sprintf(dis_ops, "%s, %s, %04X", dis_rg, dis_rm, fetchw() ); n += 2;
395 }
396 }
397
398 else if (opcode == 0xF6) {
399
400 sprintf(dis_cmd, "%s", grp2[ reg ] );
401 if (reg < 2) {
402 sprintf(dis_ops, "%s, %02X", dis_rm, fetchb() ); n++;
403 } else {
404 sprintf(dis_ops, "%s", dis_rm);
405 }
406 }
407
408
409 else if (opcode == 0xF7) {
410
411 sprintf(dis_cmd, "%s", grp2[ reg ] );
412
413 if (reg < 2) {
414 if (ereg) {
415 sprintf(dis_ops, "%s, %08X", dis_rm, fetchd() ); n += 4;
416 } else {
417 sprintf(dis_ops, "%s, %04X", dis_rm, fetchw() ); n += 2;
418 }
419 } else {
420 sprintf(dis_ops, "%s", dis_rm);
421 }
422 }
423
424
425 else if (opcode == 0xFE) {
426
427 if (reg < 2) {
428 sprintf(dis_cmd, "%s", grp3[ reg ] );
429 sprintf(dis_ops, "byte %s", dis_rm );
430 } else {
431 sprintf(dis_cmd, "(unk)");
432 }
433 }
434
435 else if (opcode == 0xFF) {
436
437 sprintf(dis_cmd, "%s", grp3[ reg ] );
438 sprintf(dis_ops, "%s %s", ereg ? "dword" : "word", dis_rm );
439
440 }
441
442
443 else if (opcode == 0x8C) { sprintf(dis_ops, "%s, %s", dis_rm, regnames[ 0x18 + reg ] ); }
444 else if (opcode == 0x8E) { sprintf(dis_ops, "%s, %s", regnames[ 0x18 + reg ], dis_rm ); }
445 else if (opcode == 0x8F) { sprintf(dis_ops, "%s %s", ereg ? "dword" : "word", dis_rm ); }
446
447
448 else if (opcode == 0xC0 || opcode == 0xC1) {
449 sprintf(dis_cmd, "%s", mnemonics[ 0x66 + reg ]);
450 sprintf(dis_ops, "%s, %02X", dis_rm, fetchb()); n++;
451 }
452
453 else if (opcode == 0xD0 || opcode == 0xD1) {
454 sprintf(dis_cmd, "%s", mnemonics[ 0x66 + reg ]);
455 sprintf(dis_ops, "%s, 1", dis_rm);
456 }
457
458 else if (opcode == 0xD2 || opcode == 0xD3) {
459 sprintf(dis_cmd, "%s", mnemonics[ 0x66 + reg ]);
460 sprintf(dis_ops, "%s, cl", dis_rm);
461 }
462
463 else if (opcode == 0xC6) {
464 sprintf(dis_ops, "%s, %02X", dis_rm, fetchb()); n++;
465 }
466 else if (opcode == 0xC7) {
467 if (ereg) {
468 sprintf(dis_ops, "%s, %08X", dis_rm, fetchd()); n += 4;
469 } else {
470 sprintf(dis_ops, "%s, %04X", dis_rm, fetchw()); n += 2;
471 }
472 }
473
474 else {
475 sprintf(dis_ops, "%s, %s", swmod ? dis_rg : dis_rm, swmod ? dis_rm : dis_rg);
476 }
477
478 } else {
479
480
481 if ((opcode & 0b11000110) == 0b00000100) {
482
483 if ((opcode & 1) == 0) {
484 sprintf(dis_ops, "al, %02X", fetchb()); n++;
485 } else if (ereg == 0) {
486 sprintf(dis_ops, "ax, %04X", fetchw()); n += 2;
487 } else {
488 sprintf(dis_ops, "eax, %08X", fetchd()); n += 4;
489 }
490 }
491
492
493 else if ((opcode & 0b11100110) == 0b00000110) {
494 sprintf(dis_ops, "%s", regnames[0x18 + ((opcode >> 3) & 3)] );
495 }
496
497
498 else if ((opcode & 0b11100000) == 0b01000000) {
499 sprintf(dis_ops, "%s", regnames[ (ereg ? 0x10 : 0x08) + (opcode & 7)] );
500 }
501 else if (opcode == 0x60 && ereg) { sprintf(dis_cmd, "pushad"); }
502 else if (opcode == 0x61 && ereg) { sprintf(dis_cmd, "popad"); }
503
504
505 else if (opcode == 0x68) {
506
507 if (ereg) {
508 sprintf(dis_ops, "%08X", fetchd()); n += 4;
509 } else {
510 sprintf(dis_ops, "%04X", fetchw()); n += 2;
511 }
512 }
513
514 else if (opcode == 0x6A) { int t = fetchb(); sprintf(dis_ops, "%04X", t | ((t & 0x80) ? 0xFF00 : 0)); n++; }
515
516 else if (((opcode & 0b11110000) == 0b01110000) || (opcode >= 0xE0 && opcode <= 0xE3) || (opcode == 0xEB)) {
517 int br = fetchb(); n++;
518 sprintf(dis_ops, "%08X", (br & 0x80 ? (eip + br - 256) : eip + br ));
519 }
520 else if (opcode == 0x6c) sprintf(dis_cmd, "insb");
521 else if (opcode == 0x6d) sprintf(dis_cmd, ereg ? "insd" : "insw");
522 else if (opcode == 0x6e) sprintf(dis_cmd, "outsb");
523 else if (opcode == 0x6f) sprintf(dis_cmd, ereg ? "outsd" : "outsw");
524
525 else if (opcode > 0x90 && opcode <= 0x97) {
526 if (ereg) {
527 sprintf(dis_ops, "eax, %s", regnames[ 0x10 + (opcode & 7) ] );
528 } else {
529 sprintf(dis_ops, "ax, %s", regnames[ 0x8 + (opcode & 7) ] );
530 }
531 }
532 else if (opcode == 0x98 && ereg) sprintf(dis_cmd, "cwde");
533 else if (opcode == 0x99 && ereg) sprintf(dis_cmd, "cdq");
534
535
536 else if (opcode == 0x9A || opcode == 0xEA) {
537
538 int dw = ereg ? fetchd() : fetchw();
539 n += (ereg ? 4 : 2);
540
541 int sg = fetchw();
542 n += 2;
543
544 if (ereg) sprintf(dis_ops, "%04X:%08X", sg, dw);
545 else sprintf(dis_ops, "%04X:%04X", sg, dw);
546 }
547
548 else if (opcode == 0xA0) { sprintf(dis_ops, "al, [%04X]", fetchw()); n += 2; }
549 else if (opcode == 0xA1) { sprintf(dis_ops, "ax, [%04X]", fetchw()); n += 2; }
550 else if (opcode == 0xA2) { sprintf(dis_ops, "[%04X], al", fetchw()); n += 2; }
551 else if (opcode == 0xA3) { sprintf(dis_ops, "[%04X], ax", fetchw()); n += 2; }
552 else if (opcode == 0xA8) { sprintf(dis_ops, "al, %02X", fetchb()); n++; }
553
554 else if (opcode == 0xA9) {
555 if (ereg) {
556 sprintf(dis_ops, "eax, %08X", fetchd()); n += 4;
557 } else {
558 sprintf(dis_ops, "ax, %04X", fetchw()); n += 2;
559 }
560 }
561 else if ((opcode >= 0xA4 && opcode <= 0xA7) || (opcode >= 0xAA && opcode <= 0xAF)) {
562 sprintf(dis_sfx, opcode&1 ? (ereg ? "d" : "w") : "b");
563 }
564 else if (opcode >= 0xB0 && opcode <= 0xB7) {
565 sprintf(dis_ops, "%s, %02x", regnames[ opcode & 7 ], fetchb()); n++;
566 }
567 else if (opcode >= 0xB8 && opcode <= 0xBF) {
568 if (ereg) {
569 sprintf(dis_ops, "%s, %08x", regnames[ 0x10 + (opcode & 7) ], fetchd()); n += 4;
570 } else {
571 sprintf(dis_ops, "%s, %04x", regnames[ 0x08 + (opcode & 7) ], fetchw()); n += 2;
572 }
573 }
574
575 else if (opcode == 0xc2 || opcode == 0xca) {
576 sprintf(dis_ops, "%04X", fetchw()); n += 2;
577 }
578
579 else if (opcode == 0xC8) {
580
581 int aa = fetchw();
582 int ab = fetchb();
583 sprintf(dis_ops, "%04x, %02X", aa, ab); n += 3;
584 }
585
586 else if (opcode == 0xCD) { sprintf(dis_ops, "%02X", fetchb()); n++; }
587
588 else if (opcode == 0xE4) { sprintf(dis_ops, "al, %02X", fetchb()); n++; }
589 else if (opcode == 0xE5) { sprintf(dis_ops, "%s, %02X", ereg ? "eax" : "ax", fetchb()); n++; }
590 else if (opcode == 0xE6) { sprintf(dis_ops, "%02X, al", fetchb()); n++; }
591 else if (opcode == 0xE7) { sprintf(dis_ops, "%02X, %s", fetchb(), ereg ? "eax" : "ax"); n++; }
592 else if (opcode == 0xEC) { sprintf(dis_ops, "al, dx"); }
593 else if (opcode == 0xED) { sprintf(dis_ops, "%s, dx", ereg ? "eax" : "ax"); }
594 else if (opcode == 0xEE) { sprintf(dis_ops, "dx, al"); }
595 else if (opcode == 0xEF) { sprintf(dis_ops, "dx, %s", ereg ? "eax" : "ax"); }
596
597 else if (opcode == 0xE8 || opcode == 0xE9) {
598 if (ereg) {
599
600 int m = fetchd(); n += 4;
601 m = (m & 0x80000000) ? m - 0x100000000 : m;
602 sprintf(dis_ops, "%08X", m);
603
604 } else {
605 int m = fetchw(); n += 2;
606 m = (m & 0x8000) ? m - 0x10000 : m;
607 sprintf(dis_ops, "%04X", m + (eip & 0xffff));
608 }
609 }
610 }
611
612
613 for (i = 0; i < 6; i++) {
614 if (i == 5 && n > 5) {
615 sprintf(dis_dmp + 2*i, "..");
616 } else if (i < n) {
617 sprintf(dis_dmp + 2*i, "%02X", readb(address + i));
618 } else {
619 sprintf(dis_dmp + 2*i, " ");
620 }
621 }
622
623
624 sprintf(dis_cmd2, "%s%s", dis_cmd, dis_sfx);
625
626
627 for (i = 0; i < 8; i++) {
628 if (dis_cmd2[i] == 0) {
629 for (j = i; j < 8; j++) {
630 dis_cmd2[j] = ' ';
631 }
632 dis_cmd2[8 - 1] = 0;
633 break;
634 }
635 }
636
637
638
639 sprintf(dis_row, "%s %s%s%s %s", dis_dmp, elock ? "lock " : "", dis_pf, dis_cmd2, dis_ops);
640 return n;
641 }
642};
§ Заголовочные файлы
Код disasm.h:
1
2
3const char* mnemonics[] = {
4
5 "add", "or", "adc", "sbb",
6 "and", "sub", "xor", "cmp",
7 "es:", "cs:", "ss:", "ds:",
8 "fs:", "gs:", "push", "pop",
9
10 "daa", "das", "aaa", "aas",
11 "inc", "dec", "pusha", "popa",
12 "bound", "arpl", "imul", "ins",
13 "outs", "test", "xchg", "lea",
14
15 "jo", "jno", "jb", "jnb",
16 "jz", "jnz", "jbe", "jnbe",
17 "js", "jns", "jp", "jnp",
18 "jl", "jnl", "jle", "jnle",
19
20 "mov", "nop", "cbw", "cwd",
21 "cwde", "cdq", "callf", "fwait",
22 "pushf", "popf", "sahf", "lahf",
23 "movs", "cmps", "stos", "lods",
24
25 "scas", "ret", "retf", "les",
26 "lds", "lfs", "lgs", "enter",
27 "leave", "int", "int1", "int3",
28 "into", "iret", "aam", "aad",
29
30 "salc", "xlatb", "loopnz", "loopz",
31 "loop", "jcxz", "in", "out",
32 "call", "jmp", "jmpf", "lock:",
33 "repnz:", "repz:", "hlt", "cmc",
34
35 "clc", "stc", "cli", "sti",
36 "cld", "std", "rol", "ror",
37 "rcl", "rcr", "shl", "shr",
38 "sal", "sar", "not", "neg",
39
40 "mul", "div", "idiv", "rep:",
41 "", "", "", "",
42 "", "", "", "",
43 "", "", "", "",
44};
45
46const int ops[256] = {
47
48
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0F,
50 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0E, 0xFF,
51 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E, 0x0F,
52 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x0E, 0x0F,
53 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x10,
54 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x11,
55 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0A, 0x12,
56 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0B, 0x13,
57 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
58 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
59 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
60 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
61 0x16, 0x17, 0x18, 0x19, 0x0C, 0x0D, 0xFF, 0xFF,
62 0x0E, 0x1A, 0x0E, 0x1A, 0x1B, 0x1B, 0x1C, 0x1C,
63 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
64 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
65 0xFF, 0xFF, 0xFF, 0xFF, 0x1D, 0x1D, 0x1E, 0x1E,
66 0x30, 0x30, 0x30, 0x30, 0x30, 0x1F, 0x30, 0x0F,
67 0x31, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
68 0x32, 0x33, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
69 0x30, 0x30, 0x30, 0x30, 0x3C, 0x3C, 0x3D, 0x3D,
70 0x1D, 0x1D, 0x3E, 0x3E, 0x3F, 0x3F, 0x40, 0x40,
71 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
72 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
73 0xFF, 0xFF, 0x41, 0x41, 0x43, 0x44, 0x30, 0x30,
74 0x47, 0x48, 0x42, 0x42, 0x4B, 0x49, 0x4C, 0x4D,
75 0xFF, 0xFF, 0xFF, 0xFF, 0x4E, 0x4F, 0x50, 0x51,
76 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
77 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x57, 0x57,
78 0x58, 0x59, 0x5A, 0x59, 0x56, 0x56, 0x57, 0x57,
79 0x5B, 0x4A, 0x5C, 0x5D, 0x5E, 0x5F, 0xFF, 0xFF,
80 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0xFF, 0xFF
81};
82
83const int modrm_lookup[512] = {
84
85
86 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
87 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
88 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
89 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
90 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
91 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
92 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
93 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
94 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
95 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
96 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
97 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
98 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
99 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
100 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
101 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
102};
103
104const char* regnames[] = {
105
106 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
107 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
108 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
109 "es", "cs", "ss", "ds", "fs", "gs", "", ""
110
111};
112
113const char* rm16names[] = {
114
115 "bx+si",
116 "bx+di",
117 "bp+si",
118 "bp+di",
119 "si",
120 "di",
121 "bp",
122 "bx"
123
124};
125
126
127const char* grp2[] = {
128
129 "test",
130 "test",
131 "not",
132 "neg",
133 "mul",
134 "imul",
135 "div",
136 "idiv"
137};
138
139
140const char* grp3[] = {
141
142 "inc",
143 "dec",
144 "call",
145 "callf",
146 "jmp",
147 "jmpf",
148 "push",
149 "(unk)"
150};