§ Как использовать

Ниже представлен код 2х файлов:
  • disasm.cc
  • disasm.h
Для того, чтобы начать ими пользоваться, надо добавить в проект такое объявление:
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];        // Rm-часть Modrm
12    char    dis_rm[32];        // Rm-часть Modrm
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    // Дизассемблирование modrm
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        /* Печать регистра 8/16/32 */
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        // 16 бит
63        if (mem32 == 0) {
64
65            /* Rm-часть */
66            switch (mod) {
67
68                /* Индекс без disp или disp16 */
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                /* + disp8 */
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                /* + disp16 */
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        // 32 бит
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) { /* SIB */
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                /* + disp8 */
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                /* + disp32 */
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            // Имеется байт SIB
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                /* Декодирование Displacement */
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                /* Декодирование Index */
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        /* Декодирование префиксов (до 6 штук) */
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        // Байт имеет modrm
337        if (hasmodrm) {
338
339            // Размер по умолчанию 8 бит, если opcode[0] = 1, то либо 16, либо 32
340            int regsize = opcode & 1 ? (ereg ? 32 : 16) : 8;
341            int swmod   = opcode & 2; // Обмен местами dis_rm и dis_rg
342
343            if (opcode == /* BOUND */ 0x62) regsize = (ereg ? 32 : 16);
344
345            // SWmod
346            if (opcode == /* ARPL */ 0x63) swmod = 0;
347            if (opcode == /* LEA */ 0x8D || opcode == 0xC4 /* LES */ || opcode == 0xC5) swmod = 1;
348
349            // Regsize
350            if (opcode == /* SREG */ 0x8C || opcode == 0x8E ||
351                opcode == /* LES */ 0xC4) regsize = (ereg ? 32 : 16);
352
353            // Получить данные из modrm
354            n += disas_modrm(regsize, emem ? 0x20 : 0x00);
355
356            // GRP-1 8
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            // GRP-1 16/32
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            // GRP-1 16/32: Расширение 8 бит до 16/32
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            // IMUL imm16
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            // Групповые инструкции #2: Byte
398            else if (opcode == 0xF6) {
399
400                sprintf(dis_cmd, "%s", grp2[ reg ]  );
401                if (reg < 2) { /* TEST */
402                    sprintf(dis_ops, "%s, %02X", dis_rm, fetchb() ); n++;
403                } else {
404                    sprintf(dis_ops, "%s", dis_rm);
405                }
406            }
407
408            // Групповые инструкции #2: Word/Dword
409            else if (opcode == 0xF7) {
410
411                sprintf(dis_cmd, "%s", grp2[ reg ]  );
412
413                if (reg < 2) { /* TEST */
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            // Групповые инструкции #3: Byte
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            // Групповые инструкции #3: Word / Dword
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            // Сегментные и POP r/m
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            // GRP-2: imm
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            // 1
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            // cl
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            // mov r/m, i8/16/32
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            // [00xx_x10x] АЛУ AL/AX/EAX, i8/16/32
481            if ((opcode & 0b11000110) == 0b00000100) {
482
483                if ((opcode & 1) == 0) { // 8 bit
484                    sprintf(dis_ops, "al, %02X", fetchb()); n++;
485                } else if (ereg == 0) { // 16 bit
486                    sprintf(dis_ops, "ax, %04X", fetchw()); n += 2;
487                } else {
488                    sprintf(dis_ops, "eax, %08X", fetchd()); n += 4;
489                }
490            }
491
492            // [000x x11x] PUSH/POP
493            else if ((opcode & 0b11100110) == 0b00000110) {
494                sprintf(dis_ops, "%s", regnames[0x18 + ((opcode >> 3) & 3)] );
495            }
496
497            // [0100_xxxx] INC/DEC/PUSH/POP
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            // PUSH imm16/32
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            // PUSH imm8
514            else if (opcode == 0x6A) { int t = fetchb(); sprintf(dis_ops, "%04X", t | ((t & 0x80) ? 0xFF00 : 0)); n++; }
515            // Jccc rel8
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            // XCHG ax, r16/32
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            // CALLF/JMPF
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            // MOV
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            // TEST
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            // RET / RETF
575            else if (opcode == 0xc2 || opcode == 0xca) {
576                sprintf(dis_ops, "%04X", fetchw()); n += 2;
577            }
578            // ENTER
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            // INT
586            else if (opcode == 0xCD) { sprintf(dis_ops, "%02X", fetchb()); n++; }
587            // IO/OUT
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            // CALL / JMP rel16
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        // Максимальное кол-во байт должно быть не более 6
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// Список мнемоник, используютcя в ops
3const char* mnemonics[] = {
4
5    /* 00 */ "add",     /* 01 */ "or",      /* 02 */ "adc",     /* 03 */ "sbb",
6    /* 04 */ "and",     /* 05 */ "sub",     /* 06 */ "xor",     /* 07 */ "cmp",
7    /* 08 */ "es:",     /* 09 */ "cs:",     /* 0A */ "ss:",     /* 0B */ "ds:",
8    /* 0C */ "fs:",     /* 0D */ "gs:",     /* 0E */ "push",    /* 0F */ "pop",
9
10    /* 10 */ "daa",     /* 11 */ "das",     /* 12 */ "aaa",     /* 13 */ "aas",
11    /* 14 */ "inc",     /* 15 */ "dec",     /* 16 */ "pusha",   /* 17 */ "popa",
12    /* 18 */ "bound",   /* 19 */ "arpl",    /* 1A */ "imul",    /* 1B */ "ins",
13    /* 1C */ "outs",    /* 1D */ "test",    /* 1E */ "xchg",    /* 1F */ "lea",
14
15    /* 20 */ "jo",      /* 21 */ "jno",     /* 22 */ "jb",      /* 23 */ "jnb",
16    /* 24 */ "jz",      /* 25 */ "jnz",     /* 26 */ "jbe",     /* 27 */ "jnbe",
17    /* 28 */ "js",      /* 29 */ "jns",     /* 2A */ "jp",      /* 2B */ "jnp",
18    /* 2C */ "jl",      /* 2D */ "jnl",     /* 2E */ "jle",     /* 2F */ "jnle",
19
20    /* 30 */ "mov",     /* 31 */ "nop",     /* 32 */ "cbw",     /* 33 */ "cwd",
21    /* 34 */ "cwde",    /* 35 */ "cdq",     /* 36 */ "callf",   /* 37 */ "fwait",
22    /* 38 */ "pushf",   /* 39 */ "popf",    /* 3A */ "sahf",    /* 3B */ "lahf",
23    /* 3C */ "movs",    /* 3D */ "cmps",    /* 3E */ "stos",    /* 3F */ "lods",
24
25    /* 40 */ "scas",    /* 41 */ "ret",     /* 42 */ "retf",    /* 43 */ "les",
26    /* 44 */ "lds",     /* 45 */ "lfs",     /* 46 */ "lgs",     /* 47 */ "enter",
27    /* 48 */ "leave",   /* 49 */ "int",     /* 4A */ "int1",    /* 4B */ "int3",
28    /* 4C */ "into",    /* 4D */ "iret",    /* 4E */ "aam",     /* 4F */ "aad",
29
30    /* 50 */ "salc",    /* 51 */ "xlatb",   /* 52 */ "loopnz",  /* 53 */ "loopz",
31    /* 54 */ "loop",    /* 55 */ "jcxz",    /* 56 */ "in",      /* 57 */ "out",
32    /* 58 */ "call",    /* 59 */ "jmp",     /* 5A */ "jmpf",    /* 5B */ "lock:",
33    /* 5C */ "repnz:",  /* 5D */ "repz:",   /* 5E */ "hlt",     /* 5F */ "cmc",
34
35    /* 60 */ "clc",     /* 61 */ "stc",     /* 62 */ "cli",     /* 63 */ "sti",
36    /* 64 */ "cld",     /* 65 */ "std",     /* 66 */ "rol",     /* 67 */ "ror",
37    /* 68 */ "rcl",     /* 69 */ "rcr",     /* 6A */ "shl",     /* 6B */ "shr",
38    /* 6C */ "sal",     /* 6D */ "sar",     /* 6E */ "not",     /* 6F */ "neg",
39
40    /* 70 */ "mul",     /* 71 */ "div",     /* 72 */ "idiv",    /* 73 */ "rep:",
41    /* 74 */ "",        /* 75 */ "",        /* 76 */ "",        /* 77 */ "",
42    /* 78 */ "",        /* 79 */ "",        /* 7A */ "",        /* 7B */ "",
43    /* 7C */ "",        /* 7D */ "",        /* 7E */ "",        /* 7F */ "",
44};
45
46const int ops[256] = {
47
48    /* Основной набор */
49    /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0F,
50    /* 08 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0E, 0xFF,
51    /* 10 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E, 0x0F,
52    /* 18 */ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x0E, 0x0F,
53    /* 20 */ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x10,
54    /* 28 */ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x11,
55    /* 30 */ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0A, 0x12,
56    /* 38 */ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0B, 0x13,
57    /* 40 */ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
58    /* 48 */ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
59    /* 50 */ 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E,
60    /* 58 */ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
61    /* 60 */ 0x16, 0x17, 0x18, 0x19, 0x0C, 0x0D, 0xFF, 0xFF,
62    /* 68 */ 0x0E, 0x1A, 0x0E, 0x1A, 0x1B, 0x1B, 0x1C, 0x1C,
63    /* 70 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
64    /* 78 */ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
65    /* 80 */ 0xFF, 0xFF, 0xFF, 0xFF, 0x1D, 0x1D, 0x1E, 0x1E,
66    /* 88 */ 0x30, 0x30, 0x30, 0x30, 0x30, 0x1F, 0x30, 0x0F,
67    /* 90 */ 0x31, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
68    /* 98 */ 0x32, 0x33, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
69    /* A0 */ 0x30, 0x30, 0x30, 0x30, 0x3C, 0x3C, 0x3D, 0x3D,
70    /* A8 */ 0x1D, 0x1D, 0x3E, 0x3E, 0x3F, 0x3F, 0x40, 0x40,
71    /* B0 */ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
72    /* B8 */ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
73    /* C0 */ 0xFF, 0xFF, 0x41, 0x41, 0x43, 0x44, 0x30, 0x30,
74    /* C8 */ 0x47, 0x48, 0x42, 0x42, 0x4B, 0x49, 0x4C, 0x4D,
75    /* D0 */ 0xFF, 0xFF, 0xFF, 0xFF, 0x4E, 0x4F, 0x50, 0x51,
76    /* D8 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
77    /* E0 */ 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x57, 0x57,
78    /* E8 */ 0x58, 0x59, 0x5A, 0x59, 0x56, 0x56, 0x57, 0x57,
79    /* F0 */ 0x5B, 0x4A, 0x5C, 0x5D, 0x5E, 0x5F, 0xFF, 0xFF,
80    /* F8 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0xFF, 0xFF
81};
82
83const int modrm_lookup[512] = {
84
85    /*       0 1 2 3 4 5 6 7 8 9 A B C D E F */
86    /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
87    /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
88    /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
89    /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
90    /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
91    /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
92    /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
93    /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
94    /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
95    /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
96    /* A0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
97    /* B0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
98    /* C0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
99    /* D0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
100    /* E0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
101    /* F0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
102};
103
104const char* regnames[] = {
105
106    /* 00 */ "al",  "cl",  "dl",  "bl",  "ah",  "ch",  "dh",  "bh",
107    /* 08 */ "ax",  "cx",  "dx",  "bx",  "sp",  "bp",  "si",  "di",
108    /* 10 */ "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
109    /* 18 */ "es",  "cs",  "ss",  "ds",  "fs",  "gs",  "",    ""
110
111};
112
113const char* rm16names[] = {
114
115    /* 0 */ "bx+si",
116    /* 1 */ "bx+di",
117    /* 2 */ "bp+si",
118    /* 3 */ "bp+di",
119    /* 4 */ "si",
120    /* 5 */ "di",
121    /* 6 */ "bp",
122    /* 7 */ "bx"
123
124};
125
126// FE
127const char* grp2[] = {
128
129    /* 0 */ "test",
130    /* 1 */ "test",
131    /* 2 */ "not",
132    /* 3 */ "neg",
133    /* 4 */ "mul",
134    /* 5 */ "imul",
135    /* 6 */ "div",
136    /* 7 */ "idiv"
137};
138
139// FF
140const char* grp3[] = {
141
142    /* 0 */ "inc",
143    /* 1 */ "dec",
144    /* 2 */ "call",
145    /* 3 */ "callf",
146    /* 4 */ "jmp",
147    /* 5 */ "jmpf",
148    /* 6 */ "push",
149    /* 7 */ "(unk)"
150};