§ Как использовать
Ниже представлен код 2х файлов:- disasm.cc
- disasm.h
unsigned char* memory = (unsigned char*)malloc(1024*1024); Disassemble* dasm = new Disassemble(memory);Это минимально, что надо сделать.
§ Основной код
Ниже представлен код disasm.cc:#include "disasm.h" class Disassemble { protected: int eip; int reg, mod, rm; char tmps[256]; char dis_row[256]; char dis_rg[32]; // Rm-часть Modrm char dis_rm[32]; // Rm-часть Modrm char dis_px[32]; // Префикс int max_memory; unsigned char* memory; public: Disassemble(unsigned char* _mem) { memory = _mem; max_memory = 0xfffff; } int readb(int address) { return memory[address & max_memory]; } int fetchb() { int a = readb(eip); eip = (eip + 1) & 0xfffff; return a; } int fetchw() { int a = fetchb(); int b = fetchb(); return b*256 + a; } int fetchd() { int a = fetchw(); int b = fetchw(); return b*65536 + a; } // Дизассемблирование modrm int disas_modrm(int reg32, int mem32) { int n = 0, b, w; /* Очистка */ dis_rg[0] = 0; dis_rm[0] = 0; b = fetchb(); n++; rm = (b & 0x07); reg = (b & 0x38) >> 3; mod = (b & 0xc0); /* Печать регистра 8/16/32 */ switch (reg32) { case 0x08: sprintf(dis_rg, "%s", regnames[ reg ]); break; case 0x10: sprintf(dis_rg, "%s", regnames[ reg + 0x08 ]); break; case 0x20: sprintf(dis_rg, "%s", regnames[ reg + 0x10 ]); break; default: sprintf(dis_rg, "<unknown>"); break; } // 16 бит if (mem32 == 0) { /* Rm-часть */ switch (mod) { /* Индекс без disp или disp16 */ case 0x00: if (rm == 6) { w = fetchw(); n += 2; sprintf(dis_rm, "[%s%04x]", dis_px, w); } else { sprintf(dis_rm, "[%s%s]", dis_px, rm16names[ rm ]); } break; /* + disp8 */ case 0x40: b = fetchb(); n++; if (b & 0x80) { sprintf(dis_rm, "[%s%s-%02x]", dis_px, rm16names[ rm ], (0xff ^ b) + 1); } else if (b == 0) { sprintf(dis_rm, "[%s%s]", dis_px, rm16names[ rm ]); } else { sprintf(dis_rm, "[%s%s+%02x]", dis_px, rm16names[ rm ], b); } break; /* + disp16 */ case 0x80: w = fetchw(); n += 2; if (w & 0x8000) { sprintf(dis_rm, "[%s%s-%04x]", dis_px, rm16names[ rm ], (0xFFFF ^ w) + 1); } else if (w == 0) { sprintf(dis_rm, "[%s%s]", dis_px, rm16names[ rm ]); } else { sprintf(dis_rm, "[%s%s+%04x]", dis_px, rm16names[ rm ], w); } break; /* Регистровая часть */ case 0xc0: switch (reg32) { case 0x08: sprintf(dis_rm, "%s", regnames[ rm ]); break; case 0x10: sprintf(dis_rm, "%s", regnames[ rm + 0x08 ]); break; case 0x20: sprintf(dis_rm, "%s", regnames[ rm + 0x10 ]); break; } break; } } // 32 бит else { int sib = 0, sibhas = 0; switch (mod) { case 0x00: if (rm == 5) { w = fetchd(); n += 4; sprintf(dis_rm, "[%s%08x]", dis_px, w); } else if (rm == 4) { /* SIB */ sib = fetchb(); n++; sibhas = 1; } else { sprintf(dis_rm, "[%s%s]", dis_px, regnames[0x10 + rm]); } break; /* + disp8 */ case 0x40: if (rm == 4) { sib = fetchb(); n++; sibhas = 1; } else { b = fetchb(); n++; if (b & 0x80) { sprintf(dis_rm, "[%s%s-%02x]", dis_px, regnames[ 0x10 + rm ], (0xff ^ b) + 1); } else if (b == 0) { sprintf(dis_rm, "[%s%s]", dis_px, regnames[ 0x10 + rm ]); } else { sprintf(dis_rm, "[%s%s+%02x]", dis_px, regnames[ 0x10 + rm ], b); } } break; /* + disp32 */ case 0x80: if (rm == 4) { sib = fetchb(); n++; sibhas = 1; } else { w = fetchd(); n += 4; if (w & 0x80000000) { sprintf(dis_rm, "[%s%s-%04x]", dis_px, regnames[ 0x10 + rm ], (0xFFFFFFFF ^ w) + 1); } else if (w == 0) { sprintf(dis_rm, "[%s%s]", dis_px, regnames[ 0x10 + rm ]); } else { sprintf(dis_rm, "[%s%s+%04x]", dis_px, regnames[ 0x10 + rm ], w); } } break; // Регистровая часть case 0xc0: switch (reg32) { case 0x08: sprintf(dis_rm, "%s", regnames[ rm ]); break; case 0x10: sprintf(dis_rm, "%s", regnames[ rm + 0x08 ]); break; case 0x20: sprintf(dis_rm, "%s", regnames[ rm + 0x10 ]); break; } break; } // Имеется байт SIB if (sibhas) { char cdisp32[16]; cdisp32[0] = 0; int disp = 0; int sib_ss = (sib & 0xc0); int sib_ix = (sib & 0x38) >> 3; int sib_bs = (sib & 0x07); /* Декодирование Displacement */ switch (mod) { case 0x40: disp = fetchb(); n += 1; if (disp & 0x80) { sprintf(cdisp32, "-%02X", (disp ^ 0xff) + 1); } else { sprintf(cdisp32, "+%02X", disp); } break; case 0x80: case 0xc0: disp = fetchd(); n += 4; if (disp & 0x80000000) { sprintf(cdisp32, "-%08X", (disp ^ 0xffffffff) + 1); } else { sprintf(cdisp32, "+%08X", disp); } break; } /* Декодирование Index */ if (sib_ix == 4) { sprintf(dis_rm, "[%s%s]", dis_px, regnames[ 0x10 + sib_bs ]); } else { switch (sib_ss) { case 0x00: sprintf(dis_rm, "[%s%s+%s]", dis_px, regnames[ 0x10 + sib_bs ], regnames[ 0x10 + sib_ix ]); break; case 0x40: sprintf(dis_rm, "[%s%s+2*%s%s]", dis_px, regnames[ 0x10 + sib_bs ], regnames[ 0x10 + sib_ix ], cdisp32); break; case 0x80: sprintf(dis_rm, "[%s%s+4*%s%s]", dis_px, regnames[ 0x10 + sib_bs ], regnames[ 0x10 + sib_ix ], cdisp32); break; case 0xc0: sprintf(dis_rm, "[%s%s+8*%s%s]", dis_px, regnames[ 0x10 + sib_bs ], regnames[ 0x10 + sib_ix ], cdisp32); break; } } } } return n; } // Дизассемблировать строку int disassemble(int address) { eip = address & max_memory; int ereg = 0; int emem = 0; int stop = 0; char dis_pf[8]; char dis_cmd [32]; char dis_cmd2[64]; char dis_ops[128]; char dis_dmp[128]; char dis_sfx[8]; int n = 0, i, j, d, opcode = 0; int elock = 0; // Очистить префикс dis_px[0] = 0; // Сегментный префикс dis_pf[0] = 0; // Префикс dis_ops[0] = 0; // Операнды dis_dmp[0] = 0; // Минидамп dis_sfx[0] = 0; // Суффикс /* Декодирование префиксов (до 6 штук) */ for (i = 0; i < 6; i++) { d = fetchb(); n++; switch (d) { case 0x0F: opcode |= 0x100; break; case 0x26: sprintf(dis_px, "%s", "es:"); break; case 0x2E: sprintf(dis_px, "%s", "cs:"); break; case 0x36: sprintf(dis_px, "%s", "ss:"); break; case 0x3E: sprintf(dis_px, "%s", "ss:"); break; case 0x64: sprintf(dis_px, "%s", "fs:"); break; case 0x65: sprintf(dis_px, "%s", "gs:"); break; case 0x66: ereg = ereg ^ 1; break; case 0x67: emem = emem ^ 1; break; case 0xf0: elock = 1; break; case 0xf2: sprintf(dis_pf, "%s", "repnz "); break; case 0xf3: sprintf(dis_pf, "%s", "rep "); break; default: opcode |= d; stop = 1; break; } if (stop) break; } int opdec = ops[ opcode & 255 ]; int hasmodrm = modrm_lookup[ opcode ]; // Типичная мнемоника if (opdec != 0xff) { sprintf(dis_cmd, "%s", mnemonics[ opdec ] ); } // Байт имеет modrm if (hasmodrm) { // Размер по умолчанию 8 бит, если opcode[0] = 1, то либо 16, либо 32 int regsize = opcode & 1 ? (ereg ? 32 : 16) : 8; int swmod = opcode & 2; // Обмен местами dis_rm и dis_rg if (opcode == /* BOUND */ 0x62) regsize = (ereg ? 32 : 16); // SWmod if (opcode == /* ARPL */ 0x63) swmod = 0; if (opcode == /* LEA */ 0x8D || opcode == 0xC4 /* LES */ || opcode == 0xC5) swmod = 1; // Regsize if (opcode == /* SREG */ 0x8C || opcode == 0x8E || opcode == /* LES */ 0xC4) regsize = (ereg ? 32 : 16); // Получить данные из modrm n += disas_modrm(regsize, emem ? 0x20 : 0x00); // GRP-1 8 if (opcode == 0x80 || opcode == 0x82) { sprintf(dis_cmd, "%s", mnemonics[ reg ] ); sprintf(dis_ops, "%s, %02X", dis_rm, fetchb()); n++; } // GRP-1 16/32 else if (opcode == 0x81) { sprintf(dis_cmd, "%s", mnemonics[ reg ] ); if (ereg) { sprintf(dis_ops, "%s, %08X", dis_rm, fetchd()); n += 4; } else { sprintf(dis_ops, "%s, %04X", dis_rm, fetchw()); n += 2; } } // GRP-1 16/32: Расширение 8 бит до 16/32 else if (opcode == 0x83) { int b8 = fetchb(); n++; sprintf(dis_cmd, "%s", mnemonics[ reg ] ); if (ereg) { sprintf(dis_ops, "%s, %08X", dis_rm, b8 | (b8 & 0x80 ? 0xFFFFFF00 : 0)); } else { sprintf(dis_ops, "%s, %04X", dis_rm, b8 | (b8 & 0x80 ? 0xFF00 : 0)); } } // IMUL imm16 else if (opcode == 0x69) { if (ereg) { sprintf(dis_ops, "%s, %s, %08X", dis_rg, dis_rm, fetchd() ); n += 4; } else { sprintf(dis_ops, "%s, %s, %04X", dis_rg, dis_rm, fetchw() ); n += 2; } } // Групповые инструкции #2: Byte else if (opcode == 0xF6) { sprintf(dis_cmd, "%s", grp2[ reg ] ); if (reg < 2) { /* TEST */ sprintf(dis_ops, "%s, %02X", dis_rm, fetchb() ); n++; } else { sprintf(dis_ops, "%s", dis_rm); } } // Групповые инструкции #2: Word/Dword else if (opcode == 0xF7) { sprintf(dis_cmd, "%s", grp2[ reg ] ); if (reg < 2) { /* TEST */ if (ereg) { sprintf(dis_ops, "%s, %08X", dis_rm, fetchd() ); n += 4; } else { sprintf(dis_ops, "%s, %04X", dis_rm, fetchw() ); n += 2; } } else { sprintf(dis_ops, "%s", dis_rm); } } // Групповые инструкции #3: Byte else if (opcode == 0xFE) { if (reg < 2) { sprintf(dis_cmd, "%s", grp3[ reg ] ); sprintf(dis_ops, "byte %s", dis_rm ); } else { sprintf(dis_cmd, "(unk)"); } } // Групповые инструкции #3: Word / Dword else if (opcode == 0xFF) { sprintf(dis_cmd, "%s", grp3[ reg ] ); sprintf(dis_ops, "%s %s", ereg ? "dword" : "word", dis_rm ); } // Сегментные и POP r/m else if (opcode == 0x8C) { sprintf(dis_ops, "%s, %s", dis_rm, regnames[ 0x18 + reg ] ); } else if (opcode == 0x8E) { sprintf(dis_ops, "%s, %s", regnames[ 0x18 + reg ], dis_rm ); } else if (opcode == 0x8F) { sprintf(dis_ops, "%s %s", ereg ? "dword" : "word", dis_rm ); } // GRP-2: imm else if (opcode == 0xC0 || opcode == 0xC1) { sprintf(dis_cmd, "%s", mnemonics[ 0x66 + reg ]); sprintf(dis_ops, "%s, %02X", dis_rm, fetchb()); n++; } // 1 else if (opcode == 0xD0 || opcode == 0xD1) { sprintf(dis_cmd, "%s", mnemonics[ 0x66 + reg ]); sprintf(dis_ops, "%s, 1", dis_rm); } // cl else if (opcode == 0xD2 || opcode == 0xD3) { sprintf(dis_cmd, "%s", mnemonics[ 0x66 + reg ]); sprintf(dis_ops, "%s, cl", dis_rm); } // mov r/m, i8/16/32 else if (opcode == 0xC6) { sprintf(dis_ops, "%s, %02X", dis_rm, fetchb()); n++; } else if (opcode == 0xC7) { if (ereg) { sprintf(dis_ops, "%s, %08X", dis_rm, fetchd()); n += 4; } else { sprintf(dis_ops, "%s, %04X", dis_rm, fetchw()); n += 2; } } // Обычные else { sprintf(dis_ops, "%s, %s", swmod ? dis_rg : dis_rm, swmod ? dis_rm : dis_rg); } } else { // [00xx_x10x] АЛУ AL/AX/EAX, i8/16/32 if ((opcode & 0b11000110) == 0b00000100) { if ((opcode & 1) == 0) { // 8 bit sprintf(dis_ops, "al, %02X", fetchb()); n++; } else if (ereg == 0) { // 16 bit sprintf(dis_ops, "ax, %04X", fetchw()); n += 2; } else { sprintf(dis_ops, "eax, %08X", fetchd()); n += 4; } } // [000x x11x] PUSH/POP else if ((opcode & 0b11100110) == 0b00000110) { sprintf(dis_ops, "%s", regnames[0x18 + ((opcode >> 3) & 3)] ); } // [0100_xxxx] INC/DEC/PUSH/POP else if ((opcode & 0b11100000) == 0b01000000) { sprintf(dis_ops, "%s", regnames[ (ereg ? 0x10 : 0x08) + (opcode & 7)] ); } else if (opcode == 0x60 && ereg) { sprintf(dis_cmd, "pushad"); } else if (opcode == 0x61 && ereg) { sprintf(dis_cmd, "popad"); } // PUSH imm16/32 else if (opcode == 0x68) { if (ereg) { sprintf(dis_ops, "%08X", fetchd()); n += 4; } else { sprintf(dis_ops, "%04X", fetchw()); n += 2; } } // PUSH imm8 else if (opcode == 0x6A) { int t = fetchb(); sprintf(dis_ops, "%04X", t | ((t & 0x80) ? 0xFF00 : 0)); n++; } // Jccc rel8 else if (((opcode & 0b11110000) == 0b01110000) || (opcode >= 0xE0 && opcode <= 0xE3) || (opcode == 0xEB)) { int br = fetchb(); n++; sprintf(dis_ops, "%08X", (br & 0x80 ? (eip + br - 256) : eip + br )); } else if (opcode == 0x6c) sprintf(dis_cmd, "insb"); else if (opcode == 0x6d) sprintf(dis_cmd, ereg ? "insd" : "insw"); else if (opcode == 0x6e) sprintf(dis_cmd, "outsb"); else if (opcode == 0x6f) sprintf(dis_cmd, ereg ? "outsd" : "outsw"); // XCHG ax, r16/32 else if (opcode > 0x90 && opcode <= 0x97) { if (ereg) { sprintf(dis_ops, "eax, %s", regnames[ 0x10 + (opcode & 7) ] ); } else { sprintf(dis_ops, "ax, %s", regnames[ 0x8 + (opcode & 7) ] ); } } else if (opcode == 0x98 && ereg) sprintf(dis_cmd, "cwde"); else if (opcode == 0x99 && ereg) sprintf(dis_cmd, "cdq"); // CALLF/JMPF else if (opcode == 0x9A || opcode == 0xEA) { int dw = ereg ? fetchd() : fetchw(); n += (ereg ? 4 : 2); int sg = fetchw(); n += 2; if (ereg) sprintf(dis_ops, "%04X:%08X", sg, dw); else sprintf(dis_ops, "%04X:%04X", sg, dw); } // MOV else if (opcode == 0xA0) { sprintf(dis_ops, "al, [%04X]", fetchw()); n += 2; } else if (opcode == 0xA1) { sprintf(dis_ops, "ax, [%04X]", fetchw()); n += 2; } else if (opcode == 0xA2) { sprintf(dis_ops, "[%04X], al", fetchw()); n += 2; } else if (opcode == 0xA3) { sprintf(dis_ops, "[%04X], ax", fetchw()); n += 2; } else if (opcode == 0xA8) { sprintf(dis_ops, "al, %02X", fetchb()); n++; } // TEST else if (opcode == 0xA9) { if (ereg) { sprintf(dis_ops, "eax, %08X", fetchd()); n += 4; } else { sprintf(dis_ops, "ax, %04X", fetchw()); n += 2; } } else if ((opcode >= 0xA4 && opcode <= 0xA7) || (opcode >= 0xAA && opcode <= 0xAF)) { sprintf(dis_sfx, opcode&1 ? (ereg ? "d" : "w") : "b"); } else if (opcode >= 0xB0 && opcode <= 0xB7) { sprintf(dis_ops, "%s, %02x", regnames[ opcode & 7 ], fetchb()); n++; } else if (opcode >= 0xB8 && opcode <= 0xBF) { if (ereg) { sprintf(dis_ops, "%s, %08x", regnames[ 0x10 + (opcode & 7) ], fetchd()); n += 4; } else { sprintf(dis_ops, "%s, %04x", regnames[ 0x08 + (opcode & 7) ], fetchw()); n += 2; } } // RET / RETF else if (opcode == 0xc2 || opcode == 0xca) { sprintf(dis_ops, "%04X", fetchw()); n += 2; } // ENTER else if (opcode == 0xC8) { int aa = fetchw(); int ab = fetchb(); sprintf(dis_ops, "%04x, %02X", aa, ab); n += 3; } // INT else if (opcode == 0xCD) { sprintf(dis_ops, "%02X", fetchb()); n++; } // IO/OUT else if (opcode == 0xE4) { sprintf(dis_ops, "al, %02X", fetchb()); n++; } else if (opcode == 0xE5) { sprintf(dis_ops, "%s, %02X", ereg ? "eax" : "ax", fetchb()); n++; } else if (opcode == 0xE6) { sprintf(dis_ops, "%02X, al", fetchb()); n++; } else if (opcode == 0xE7) { sprintf(dis_ops, "%02X, %s", fetchb(), ereg ? "eax" : "ax"); n++; } else if (opcode == 0xEC) { sprintf(dis_ops, "al, dx"); } else if (opcode == 0xED) { sprintf(dis_ops, "%s, dx", ereg ? "eax" : "ax"); } else if (opcode == 0xEE) { sprintf(dis_ops, "dx, al"); } else if (opcode == 0xEF) { sprintf(dis_ops, "dx, %s", ereg ? "eax" : "ax"); } // CALL / JMP rel16 else if (opcode == 0xE8 || opcode == 0xE9) { if (ereg) { int m = fetchd(); n += 4; m = (m & 0x80000000) ? m - 0x100000000 : m; sprintf(dis_ops, "%08X", m); } else { int m = fetchw(); n += 2; m = (m & 0x8000) ? m - 0x10000 : m; sprintf(dis_ops, "%04X", m + (eip & 0xffff)); } } } // Максимальное кол-во байт должно быть не более 6 for (i = 0; i < 6; i++) { if (i == 5 && n > 5) { sprintf(dis_dmp + 2*i, ".."); } else if (i < n) { sprintf(dis_dmp + 2*i, "%02X", readb(address + i)); } else { sprintf(dis_dmp + 2*i, " "); } } // Суффикс команды sprintf(dis_cmd2, "%s%s", dis_cmd, dis_sfx); // Дополнить пробелами мнемонику for (i = 0; i < 8; i++) { if (dis_cmd2[i] == 0) { for (j = i; j < 8; j++) { dis_cmd2[j] = ' '; } dis_cmd2[8 - 1] = 0; break; } } // Формирование строки вывода // Дамп инструкции, команда, операнды sprintf(dis_row, "%s %s%s%s %s", dis_dmp, elock ? "lock " : "", dis_pf, dis_cmd2, dis_ops); return n; } };
§ Заголовочные файлы
Код disasm.h:// Список мнемоник, используютcя в ops const char* mnemonics[] = { /* 00 */ "add", /* 01 */ "or", /* 02 */ "adc", /* 03 */ "sbb", /* 04 */ "and", /* 05 */ "sub", /* 06 */ "xor", /* 07 */ "cmp", /* 08 */ "es:", /* 09 */ "cs:", /* 0A */ "ss:", /* 0B */ "ds:", /* 0C */ "fs:", /* 0D */ "gs:", /* 0E */ "push", /* 0F */ "pop", /* 10 */ "daa", /* 11 */ "das", /* 12 */ "aaa", /* 13 */ "aas", /* 14 */ "inc", /* 15 */ "dec", /* 16 */ "pusha", /* 17 */ "popa", /* 18 */ "bound", /* 19 */ "arpl", /* 1A */ "imul", /* 1B */ "ins", /* 1C */ "outs", /* 1D */ "test", /* 1E */ "xchg", /* 1F */ "lea", /* 20 */ "jo", /* 21 */ "jno", /* 22 */ "jb", /* 23 */ "jnb", /* 24 */ "jz", /* 25 */ "jnz", /* 26 */ "jbe", /* 27 */ "jnbe", /* 28 */ "js", /* 29 */ "jns", /* 2A */ "jp", /* 2B */ "jnp", /* 2C */ "jl", /* 2D */ "jnl", /* 2E */ "jle", /* 2F */ "jnle", /* 30 */ "mov", /* 31 */ "nop", /* 32 */ "cbw", /* 33 */ "cwd", /* 34 */ "cwde", /* 35 */ "cdq", /* 36 */ "callf", /* 37 */ "fwait", /* 38 */ "pushf", /* 39 */ "popf", /* 3A */ "sahf", /* 3B */ "lahf", /* 3C */ "movs", /* 3D */ "cmps", /* 3E */ "stos", /* 3F */ "lods", /* 40 */ "scas", /* 41 */ "ret", /* 42 */ "retf", /* 43 */ "les", /* 44 */ "lds", /* 45 */ "lfs", /* 46 */ "lgs", /* 47 */ "enter", /* 48 */ "leave", /* 49 */ "int", /* 4A */ "int1", /* 4B */ "int3", /* 4C */ "into", /* 4D */ "iret", /* 4E */ "aam", /* 4F */ "aad", /* 50 */ "salc", /* 51 */ "xlatb", /* 52 */ "loopnz", /* 53 */ "loopz", /* 54 */ "loop", /* 55 */ "jcxz", /* 56 */ "in", /* 57 */ "out", /* 58 */ "call", /* 59 */ "jmp", /* 5A */ "jmpf", /* 5B */ "lock:", /* 5C */ "repnz:", /* 5D */ "repz:", /* 5E */ "hlt", /* 5F */ "cmc", /* 60 */ "clc", /* 61 */ "stc", /* 62 */ "cli", /* 63 */ "sti", /* 64 */ "cld", /* 65 */ "std", /* 66 */ "rol", /* 67 */ "ror", /* 68 */ "rcl", /* 69 */ "rcr", /* 6A */ "shl", /* 6B */ "shr", /* 6C */ "sal", /* 6D */ "sar", /* 6E */ "not", /* 6F */ "neg", /* 70 */ "mul", /* 71 */ "div", /* 72 */ "idiv", /* 73 */ "rep:", /* 74 */ "", /* 75 */ "", /* 76 */ "", /* 77 */ "", /* 78 */ "", /* 79 */ "", /* 7A */ "", /* 7B */ "", /* 7C */ "", /* 7D */ "", /* 7E */ "", /* 7F */ "", }; const int ops[256] = { /* Основной набор */ /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0F, /* 08 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0E, 0xFF, /* 10 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E, 0x0F, /* 18 */ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x0E, 0x0F, /* 20 */ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x10, /* 28 */ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x11, /* 30 */ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0A, 0x12, /* 38 */ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0B, 0x13, /* 40 */ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, /* 48 */ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, /* 50 */ 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, /* 58 */ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, /* 60 */ 0x16, 0x17, 0x18, 0x19, 0x0C, 0x0D, 0xFF, 0xFF, /* 68 */ 0x0E, 0x1A, 0x0E, 0x1A, 0x1B, 0x1B, 0x1C, 0x1C, /* 70 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 78 */ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, /* 80 */ 0xFF, 0xFF, 0xFF, 0xFF, 0x1D, 0x1D, 0x1E, 0x1E, /* 88 */ 0x30, 0x30, 0x30, 0x30, 0x30, 0x1F, 0x30, 0x0F, /* 90 */ 0x31, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, /* 98 */ 0x32, 0x33, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, /* A0 */ 0x30, 0x30, 0x30, 0x30, 0x3C, 0x3C, 0x3D, 0x3D, /* A8 */ 0x1D, 0x1D, 0x3E, 0x3E, 0x3F, 0x3F, 0x40, 0x40, /* B0 */ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, /* B8 */ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, /* C0 */ 0xFF, 0xFF, 0x41, 0x41, 0x43, 0x44, 0x30, 0x30, /* C8 */ 0x47, 0x48, 0x42, 0x42, 0x4B, 0x49, 0x4C, 0x4D, /* D0 */ 0xFF, 0xFF, 0xFF, 0xFF, 0x4E, 0x4F, 0x50, 0x51, /* D8 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* E0 */ 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x57, 0x57, /* E8 */ 0x58, 0x59, 0x5A, 0x59, 0x56, 0x56, 0x57, 0x57, /* F0 */ 0x5B, 0x4A, 0x5C, 0x5D, 0x5E, 0x5F, 0xFF, 0xFF, /* F8 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0xFF, 0xFF }; const int modrm_lookup[512] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* A0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* B0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* C0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* D0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* E0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* F0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 }; const char* regnames[] = { /* 00 */ "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", /* 08 */ "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", /* 10 */ "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", /* 18 */ "es", "cs", "ss", "ds", "fs", "gs", "", "" }; const char* rm16names[] = { /* 0 */ "bx+si", /* 1 */ "bx+di", /* 2 */ "bp+si", /* 3 */ "bp+di", /* 4 */ "si", /* 5 */ "di", /* 6 */ "bp", /* 7 */ "bx" }; // FE const char* grp2[] = { /* 0 */ "test", /* 1 */ "test", /* 2 */ "not", /* 3 */ "neg", /* 4 */ "mul", /* 5 */ "imul", /* 6 */ "div", /* 7 */ "idiv" }; // FF const char* grp3[] = { /* 0 */ "inc", /* 1 */ "dec", /* 2 */ "call", /* 3 */ "callf", /* 4 */ "jmp", /* 5 */ "jmpf", /* 6 */ "push", /* 7 */ "(unk)" };
11 мая, 2022
© 2007-2023 Ситуация кушает отлично