📄 x86dis.cc
字号:
switch (op->size) { case 4: d += sprintf(d, "single ptr "); break; case 8: d += sprintf(d, "double ptr "); break; case 10: d += sprintf(d, "extended ptr "); break; } } else if (op->mem.addrptr) { switch (op->size) { case 4: case 6: d += sprintf(d, "far ptr "); break; } } else { switch (op->size) { case 1: d += sprintf(d, "byte ptr "); break; case 2: d += sprintf(d, "word ptr "); break; case 4: d += sprintf(d, "dword ptr "); break; case 6: d += sprintf(d, "pword ptr "); break; case 8: d += sprintf(d, "qword ptr "); break; case 16: d += sprintf(d, "oword ptr "); break; case 32: d += sprintf(d, "ymmword ptr "); break; } } } if (insn->segprefix != X86_PREFIX_NO) { d += sprintf(d, "%s%s:%s", x86_segs[insn->segprefix], cs_symbol, cs_default); } strcpy(d, cs_symbol); d += strlen(cs_symbol); *(d++)='['; strcpy(d, cs_default); d += strlen(cs_default); bool first = true; int reg = 0; switch (insn->eaddrsize) { case X86_ADDRSIZE16: reg = 1; break; case X86_ADDRSIZE32: reg = 2; break; case X86_ADDRSIZE64: reg = 3; break; default: {assert(0);} } bool optimize_addr = options & X86DIS_STYLE_OPTIMIZE_ADDR; if (optimize_addr && op->mem.base != X86_REG_NO && op->mem.base == op->mem.index) { d += sprintf(d, "%s%s*%s%d%s", regs(insn, reg, op->mem.index), cs_symbol, cs_number, op->mem.scale+1, cs_default); first = false; } else { if (op->mem.base != X86_REG_NO) { if (op->mem.base == X86_REG_IP) { d += sprintf(d, "%s", x86_ipregs[reg]); } else { d += sprintf(d, "%s", regs(insn, reg, op->mem.base)); } first = false; } if (op->mem.index != X86_REG_NO) { if (!first) { strcpy(d, cs_symbol); d += strlen(cs_symbol); *(d++) = '+'; strcpy(d, cs_default); d += strlen(cs_default); } if (op->mem.scale == 1) { d += sprintf(d, "%s", regs(insn, reg, op->mem.index)); } else { d += sprintf(d, "%s%s*%s%d%s", regs(insn, reg, op->mem.index), cs_symbol, cs_number, op->mem.scale, cs_default); } first = false; } } if ((!optimize_addr && op->mem.hasdisp) || (optimize_addr && op->mem.disp) || first) { CPU_ADDR a; filloffset(a, op->mem.disp); int slen; char *s=(addr_sym_func) ? addr_sym_func(a, &slen, addr_sym_func_context) : 0; if (s) { if (!first) { strcpy(d, cs_symbol); d += strlen(cs_symbol); *(d++)='+'; strcpy(d, cs_default); d += strlen(cs_default); } memcpy(d, s, slen); d+=slen; *opstrlen=d-opstr; } else { uint32 q; switch (op->mem.addrsize) { case X86_ADDRSIZE16: q = sint32(sint16(op->mem.disp)); if (!first) { strcpy(d, cs_symbol); d += strlen(cs_symbol); if (op->mem.disp & 0x8000) { *(d++) = '-'; q = -q; } else *(d++) = '+'; } strcpy(d, cs_number); d += strlen(cs_number); hexd(&d, 4, options, q); strcpy(d, cs_default); d += strlen(cs_default); break; case X86_ADDRSIZE32: case X86_ADDRSIZE64: q = op->mem.disp; if (!first) { strcpy(d, cs_symbol); d += strlen(cs_symbol); if (op->mem.disp & 0x80000000) { *(d++)='-'; q=-q; } else *(d++)='+'; } strcpy(d, cs_number); d += strlen(cs_number); hexd(&d, 8, options, q); strcpy(d, cs_default); d += strlen(cs_default); break; } } } strcpy(d, cs_symbol); d += strlen(cs_symbol); *(d++)=']'; strcpy(d, cs_default); d += strlen(cs_default); if (*opstrlen) *opstrlen += strlen(cs_symbol) + 1 + strlen(cs_default); *d=0; break; } case X86_OPTYPE_FARPTR: { CPU_ADDR a; a.addr32.seg = op->farptr.seg; a.addr32.offset = op->farptr.offset; int slen; char *s=(addr_sym_func) ? addr_sym_func(a, &slen, addr_sym_func_context) : 0; if (s) { memcpy(opstr, s, slen); opstr[slen]=0; *opstrlen=slen; } else { char *g=opstr; hexd(&g, 4, options, op->farptr.seg); strcpy(g, cs_symbol); g += strlen(cs_symbol); *(g++)=':'; strcpy(g, cs_default); g += strlen(cs_default); switch (op->size) { case 4: hexd(&g, 4, options, op->farptr.offset); break; case 6: hexd(&g, 8, options, op->farptr.offset); break; } } break; } default: opstr[0]=0; }}void x86dis::str_format(char **str, const char **format, char *p, char *n, char *op[3], int oplen[3], char stopchar, int print){ const char *cs_default = get_cs(e_cs_default); const char *cs_symbol = get_cs(e_cs_symbol); const char *f = *format; char *s = *str; while (*f) { if (*f == stopchar) break; switch (*f) { case '\t': if (print) do *(s++)=' '; while ((s-insnstr) % DIS_STYLE_TABSIZE); break; case DISASM_STRF_VAR: f++; if (print) { char *t = NULL; int tl = 0; switch (*f) { case DISASM_STRF_PREFIX: t=p; break; case DISASM_STRF_NAME: t=n; break; case DISASM_STRF_FIRST: t=op[0]; tl=oplen[0]; break; case DISASM_STRF_SECOND: t=op[1]; tl=oplen[1]; break; case DISASM_STRF_THIRD: t=op[2]; tl=oplen[2]; break; case DISASM_STRF_FORTH: t=op[3]; tl=oplen[3]; break; case DISASM_STRF_FIFTH: t=op[4]; tl=oplen[4]; break; } if (tl) { memcpy(s, t, tl); s+=tl; *s=0; } else { strcpy(s, t); s += strlen(s); } } break; case DISASM_STRF_COND: { char *t = NULL; f++; switch (*f) { case DISASM_STRF_PREFIX: t=p; break; case DISASM_STRF_NAME: t=n; break; case DISASM_STRF_FIRST: t=op[0]; break; case DISASM_STRF_SECOND: t=op[1]; break; case DISASM_STRF_THIRD: t=op[2]; break; case DISASM_STRF_FORTH: t=op[3]; break; case DISASM_STRF_FIFTH: t=op[4]; break; } f += 2; if (t && t[0]) { str_format(&s, &f, p, n, op, oplen, *(f-1), 1); } else { str_format(&s, &f, p, n, op, oplen, *(f-1), 0); } break; } default: if (print) { bool x = (strchr(",.-=+-*/[]()", *f) != NULL) && *f; if (x) { strcpy(s, cs_symbol); s += strlen(cs_symbol); } *(s++) = *f; if (x) { strcpy(s, cs_default); s += strlen(cs_default); } } } f++; } *s=0; *format=f; *str=s;}const char *x86dis::str(dis_insn *disasm_insn, int options){ return strf(disasm_insn, options, DISASM_STRF_DEFAULT_FORMAT);}static void pickname(char *result, const char *name, int n){ const char *s = name; do { name = s+1; s = strchr(name, '|'); if (!s) { strcpy(result, name); return; } } while (n--); ht_strlcpy(result, name, s-name+1);}const char *x86dis::strf(dis_insn *disasm_insn, int opt, const char *format){ x86dis_insn *insn = (x86dis_insn*)disasm_insn; char prefix[64]; char *p = prefix; options = opt; *p = 0; if (insn->lockprefix == X86_PREFIX_LOCK) p += sprintf(p, "lock "); if (insn->repprefix == X86_PREFIX_REPZ) { p += sprintf(p, "repz "); } else if (insn->repprefix == X86_PREFIX_REPNZ) { p += sprintf(p, "repnz "); } if (p != prefix && p[-1] == ' ') { p--; *p = 0; } const char *iname = insn->name; bool explicit_params = (options & X86DIS_STYLE_EXPLICIT_MEMSIZE) || iname[0] == '~'; char ops[5][512]; /* FIXME: possible buffer overflow ! */ char *op[5]; int oplen[5]; if (options & DIS_STYLE_HIGHLIGHT) enable_highlighting(); for (int i=0; i < 5; i++) { op[i] = (char*)&ops[i]; str_op(op[i], &oplen[i], insn, &insn->op[i], explicit_params); } char *s=insnstr; if (iname[0] == '~') iname++; char n[32]; switch (iname[0]) { case '|': pickname(n, iname, 0); break; case '?': case '&': switch (insn->eopsize) { case X86_OPSIZE16: pickname(n, iname, 0); break; case X86_OPSIZE32: pickname(n, iname, 1); break; case X86_OPSIZE64: pickname(n, iname, 2); break; default: {assert(0);} } break; case '*': switch (insn->eaddrsize) { case X86_ADDRSIZE16: pickname(n, iname, 0); break; case X86_ADDRSIZE32: pickname(n, iname, 1); break; case X86_ADDRSIZE64: pickname(n, iname, 2); break; default: {assert(0);} } break; default: strcpy(n, iname); } str_format(&s, &format, prefix, n, op, oplen, 0, 1); disable_highlighting(); return insnstr;}void x86dis::store(ObjectStream &f) const{ PUT_INT32X(f, opsize); PUT_INT32X(f, addrsize);}bool x86dis::validInsn(dis_insn *disasm_insn){ return !((x86dis_insn *)disasm_insn)->invalid;}/* * CLASS x86_64dis */x86opc_insn (*x86_64dis::x86_64_insns)[256];x86_64dis::x86_64dis() : x86dis(X86_OPSIZE32, X86_ADDRSIZE64){ prepInsns();}void x86_64dis::prepInsns(){ if (!x86_64_insns) { x86_64_insns = ht_malloc(sizeof *x86_64_insns); memcpy(x86_64_insns, x86_32_insns, sizeof x86_32_insns); int i = 0; while (x86_64_insn_patches[i].opc != -1) { (*x86_64_insns)[x86_64_insn_patches[i].opc] = x86_64_insn_patches[i].insn; i++; } } x86_insns = x86_64_insns;}void x86_64dis::decode_modrm(x86_insn_op *op, char size, bool allow_reg, bool allow_mem, bool mmx, bool xmm, bool ymm){ int modrm = getmodrm(); getdisp(); int mod = mkmod(modrm); int rm = mkrm(modrm); if (mod == 3) { if (!allow_reg) { invalidate(); return; } if (xmm || (mmx && is_xmm_op(&insn, size))) { op->type = X86_OPTYPE_XMM; op->xmm = rm; } else if (mmx) { op->type = X86_OPTYPE_MMX; op->mmx = rm & 0x7; // no rex-extension } else if (ymm) { op->type = X86_OPTYPE_YMM; op->mmx = rm; } else { op->type = X86_OPTYPE_REG; op->reg = rm; } op->size = esizeop(size); } else { if (!allow_mem) { invalidate(); return; } op->mem.addrsize = insn.eaddrsize; op->type = X86_OPTYPE_MEM; op->size = esizeop(size); op->mem.floatptr = isfloat(size); op->mem.addrptr = isaddr(size); if (mod == 0 && (rm & 0x7) == 5) { op->mem.hasdisp = true; op->mem.disp = sint32(disp); fixdisp = true;// op->mem.base = X86_REG_IP; op->mem.base = X86_REG_NO; op->mem.index = X86_REG_NO; op->mem.scale = 0; } else if ((rm & 0x7) == 4) { decode_sib(op, mod); } else { op->mem.base = rm; op->mem.index = X86_REG_NO; op->mem.scale = 1; switch (mod) { case 0: op->mem.hasdisp = false; op->mem.disp = 0; break; case 1: op->mem.hasdisp = true; op->mem.disp = sint64(sint8(disp)); break; case 2: op->mem.hasdisp = true; op->mem.disp = sint64(sint32(disp)); break; } } }}void x86_64dis::prefixes(){ insn.opsizeprefix = X86_PREFIX_NO; insn.lockprefix = X86_PREFIX_NO; insn.repprefix = X86_PREFIX_NO; insn.segprefix = X86_PREFIX_NO; insn.rexprefix = 0; while (codep - ocodep < 15) { c = getbyte(); switch (c) { case 0x26: case 0x2e: case 0x36: case 0x3e: continue; // cs, ds, es, ss prefix ignored case 0x64: insn.segprefix = X86_PREFIX_FS; continue; case 0x65: insn.segprefix = X86_PREFIX_GS; continue; case 0x66: insn.opsizeprefix = X86_PREFIX_OPSIZE; insn.eopsize = X86_OPSIZE16; continue; case 0x67: insn.eaddrsize = X86_ADDRSIZE32; continue; case 0xf0: insn.lockprefix = X86_PREFIX_LOCK; continue; case 0xf2: insn.repprefix = X86_PREFIX_REPNZ; continue; case 0xf3: insn.repprefix = X86_PREFIX_REPZ; continue; } if ((c & 0xf0) == 0x40) { insn.rexprefix = c; if (rexw(c)) { insn.eopsize = X86_OPSIZE64; } c = getbyte(); } break; }}void x86_64dis::checkInfo(x86opc_insn *xinsn){ if (insn.opsizeprefix != X86_PREFIX_OPSIZE && (x86_op_type[xinsn->op[0]].info & INFO_DEFAULT_64)) { // instruction defaults to 64 bit opsize insn.eopsize = X86_OPSIZE64; }}uint64 x86_64dis::getoffset(){ return addr.flat64.addr;}void x86_64dis::filloffset(CPU_ADDR &addr, uint64 offset){ addr.flat64.addr = offset;}void x86_64dis::load(ObjectStream &f){ x86dis::load(f); prepInsns();}ObjectID x86_64dis::getObjectID() const{ return ATOM_DISASM_X86_64;}/* * CLASS x86dis_vxd */x86dis_vxd::x86dis_vxd(X86OpSize opsize, X86AddrSize addrsize) : x86dis(opsize, addrsize){}dis_insn *x86dis_vxd::decode(byte *code, int maxlen, CPU_ADDR addr){ if ((maxlen >= 6) && (code[0] == 0xcd) && (code[1] == 0x20)) { insn.name = "VxDCall"; insn.size = 6; vxd_t *v = find_vxd(vxds, *(uint16*)(code+4)); if (v) { insn.op[0].type = X86_OPTYPE_USER; insn.op[0].user[0].i = *(uint16*)(code+4); insn.op[0].user[1].p = (void*)v->name; const char *vs = NULL; if (v->services) vs = find_vxd_service(v->services, *(uint16*)(code+2) & 0x7fff); if (vs) { insn.op[1].type = X86_OPTYPE_USER; insn.op[1].user[0].i = *(uint16*)(code+2); insn.op[1].user[1].p = (void*)vs; } else { insn.op[1].type = X86_OPTYPE_IMM; insn.op[1].size = 2; insn.op[1].imm = *(uint16*)(code+2); } } else { insn.op[0].type = X86_OPTYPE_IMM; insn.op[0].size = 2; insn.op[0].imm = *(uint16*)(code+4); insn.op[1].type = X86_OPTYPE_IMM; insn.op[1].size = 2; insn.op[1].imm = *(uint16*)(code+2); } insn.op[2].type = X86_OPTYPE_EMPTY; insn.lockprefix = X86_PREFIX_NO; insn.repprefix = X86_PREFIX_NO; insn.segprefix = X86_PREFIX_NO; return &insn; } return x86dis::decode(code, maxlen, addr);}ObjectID x86dis_vxd::getObjectID() const{ return ATOM_DISASM_X86_VXD;}void x86dis_vxd::str_op(char *opstr, int *opstrlen, x86dis_insn *insn, x86_insn_op *op, bool explicit_params){ if (op->type == X86_OPTYPE_USER) { *opstrlen = 0; strcpy(opstr, (char*)op->user[1].p); } else { x86dis::str_op(opstr, opstrlen, insn, op, explicit_params); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -