?? x86dis.cc
字號:
default: {assert(0);} } int s = esizeop(xop->size); sint64 addr = getoffset() + (codep - ocodep); switch (s) { case 1: op->imm = sint8(getbyte()) + addr + 1; break; case 2: op->imm = sint16(getword()) + addr + 2; break; case 4: case 8: op->imm = sint32(getdword()) + addr + 4; break; } break; } case TYPE_M: { /* ModR/M (memory only) */ decode_modrm(op, xop->size, false, true, false, false, false); break; } case TYPE_MR: { /* ModR/M (memory only) */ int modrm = getmodrm(); int mod = mkmod(modrm); byte xopsize = xop->size; if (mod == 3) { xopsize = xop->extra; } decode_modrm(op, xopsize, (xopsize != SIZE_P), true, false, false, false); break; } case TYPE_O: { /* direct memory without ModR/M */ op->type = X86_OPTYPE_MEM; op->size = esizeop(xop->size); op->mem.floatptr = isfloat(xop->size); op->mem.addrptr = isaddr(xop->size); op->mem.addrsize = insn.eaddrsize; op->mem.hasdisp = true; switch (insn.eaddrsize) { case X86_ADDRSIZE16: op->mem.disp = getword(); break; case X86_ADDRSIZE32: op->mem.disp = getdword(); break; case X86_ADDRSIZE64: op->mem.disp = getqword(); break; default: {assert(0);} } op->mem.base = X86_REG_NO; op->mem.index = X86_REG_NO; op->mem.scale = 1; break; } case TYPE_P: { /* reg of ModR/M picks MMX register */ if (is_xmm_op(&insn, xop->size)) { op->type = X86_OPTYPE_XMM; op->xmm = mkreg(getmodrm()); } else { op->type = X86_OPTYPE_MMX; op->mmx = mkreg(getmodrm()); } op->size = esizeop(xop->size); break; } case TYPE_PR: { /* rm of ModR/M picks MMX register */ if (mkmod(getmodrm()) == 3) { if (is_xmm_op(&insn, xop->size)) { op->type = X86_OPTYPE_XMM; op->xmm = mkrm(getmodrm()); } else { op->type = X86_OPTYPE_MMX; op->mmx = mkrm(getmodrm()); } op->size = esizeop(xop->size); } else { invalidate(); } break; } case TYPE_Q: { /* ModR/M (MMX reg or memory) */ decode_modrm(op, xop->size, true, true, true, false, false); break; } case TYPE_R: { /* rm of ModR/M picks general register */ op->type = X86_OPTYPE_REG; op->size = esizeop(xop->size); op->reg = mkrm(getmodrm()); break; } case TYPE_Rx: { /* extra picks register */ op->type = X86_OPTYPE_REG; op->size = esizeop(xop->size); op->reg = xop->extra | !!rexb(insn.rexprefix) << 3; break; } case TYPE_RXx: { /* extra picks register */ op->type = X86_OPTYPE_REG; op->size = esizeop(xop->size); op->reg = xop->extra; break; } case TYPE_S: { /* reg of ModR/M picks segment register */ op->type = X86_OPTYPE_SEG; op->size = esizeop(xop->size); op->seg = mkreg(getmodrm()) & 0x7; if (op->seg > 5) invalidate(); break; } case TYPE_Sx: { /* extra picks segment register */ op->type = X86_OPTYPE_SEG; op->size = esizeop(xop->size); op->seg = xop->extra; if (op->seg > 5) invalidate(); break; } case TYPE_V: { /* reg of ModR/M picks XMM register */ op->type = X86_OPTYPE_XMM; op->size = 16; op->xmm = mkreg(getmodrm()); break; } case TYPE_VI: { /* bits 7-4 of imm picks XMM register */ op->type = X86_OPTYPE_XMM; op->size = 16; op->xmm = getspecialimm() >> 4; break; } case TYPE_VV: { /* VEX.vvvv picks XMM register */ op->type = X86_OPTYPE_XMM; op->size = 16; op->xmm = insn.vexprefix.vvvv; break; } case TYPE_Vx: { /* extra picks XMM register */ op->type = X86_OPTYPE_XMM; op->size = 16; op->reg = xop->extra; break; } case TYPE_VR: /* rm of ModR/M picks XMM register */ if (mkmod(getmodrm()) == 3) { op->type = X86_OPTYPE_XMM; op->size = esizeop(xop->size); op->xmm = mkrm(getmodrm()); } else { invalidate(); } break; case TYPE_W: /* ModR/M (XMM reg or memory) */ decode_modrm(op, xop->size, true, true, false, true, false); break; case TYPE_VD: op->type = X86_OPTYPE_XMM; op->size = 16; op->reg = drexdest(getdrex()); break; case TYPE_VS: if (xop->info && oc0(getdrex())) { invalidate(); } if (oc0(getdrex()) ^ xop->extra) { decode_modrm(op, xop->size, true, true, false, true, false); } else { op->type = X86_OPTYPE_XMM; op->size = 16; op->xmm = mkreg(getmodrm()); } break; case TYPE_Y: /* reg of ModR/M picks XMM register */ op->type = X86_OPTYPE_YMM; op->size = 32; op->ymm = mkreg(getmodrm()); break; case TYPE_YV: { /* VEX.vvvv picks YMM register */ op->type = X86_OPTYPE_YMM; op->size = 32; op->ymm = insn.vexprefix.vvvv; break; } case TYPE_YI: /* bits 7-4 of imm picks YMM register */ op->type = X86_OPTYPE_YMM; op->size = 32; op->ymm = getspecialimm() >> 4; break; case TYPE_X: /* ModR/M (XMM reg or memory) */ decode_modrm(op, xop->size, true, true, false, false, true); break; }}dis_insn *x86dis::duplicateInsn(dis_insn *disasm_insn){ x86dis_insn *insn = ht_malloc(sizeof (x86dis_insn)); *insn = *(x86dis_insn *)disasm_insn; return insn;}int x86dis::esizeop(uint c){ switch (c) { case SIZE_B: return 1; case SIZE_W: return 2; case SIZE_D: case SIZE_S: return 4; case SIZE_Q: case SIZE_L: return 8; case SIZE_O: return 16; case SIZE_Y: return 32; case SIZE_T: return 10; case SIZE_V: case SIZE_BV: case SIZE_VV: switch (insn.eopsize) { case X86_OPSIZE16: return 2; case X86_OPSIZE32: return 4; case X86_OPSIZE64: return 8; default: {assert(0);} } case SIZE_R: if (insn.eopsize == X86_OPSIZE64) return 8; else return 4; case SIZE_U: if (insn.opsizeprefix == X86_PREFIX_OPSIZE) return 16; else return 8; case SIZE_Z: if (insn.opsizeprefix == X86_PREFIX_OPSIZE) return 8; else return 4; case SIZE_P: if (insn.eopsize == X86_OPSIZE16) return 4; else return 6; } return 0;}int x86dis::esizeop_ex(uint c){ switch (c) { case SIZE_BV: return 1; case SIZE_VV: switch (insn.eopsize) { case X86_OPSIZE16: return 2; case X86_OPSIZE32: case X86_OPSIZE64: return 4; default: {assert(0);} } } return esizeop(c);}byte x86dis::getbyte(){ if (codep-ocodep+1 <= maxlen) { return *(codep++); } else { invalidate(); return 0; }}uint16 x86dis::getword(){ if (codep-ocodep+2 <= maxlen) { uint16 w; w = codep[0] | (codep[1]<<8); codep += 2; return w; } else { invalidate(); return 0; }}uint32 x86dis::getdword(){ if (codep-ocodep+4 <= maxlen) { uint32 w; w = codep[0] | codep[1]<<8 | codep[2]<<16 | codep[3]<<24; codep += 4; return w; } else { invalidate(); return 0; }}uint64 x86dis::getqword(){ if (codep-ocodep+8 <= maxlen) { uint64 w; w = uint64(codep[0])<< 0 | uint64(codep[1])<< 8 | uint64(codep[2])<<16 | uint64(codep[3])<<24 | uint64(codep[4])<<32 | uint64(codep[5])<<40 | uint64(codep[6])<<48 | uint64(codep[7])<<56; codep += 8; return w; } else { invalidate(); return 0; }}void x86dis::getOpcodeMetrics(int &min_length, int &max_length, int &min_look_ahead, int &avg_look_ahead, int &addr_align){ min_length = 1; max_length = 15; min_look_ahead = 120; // 1/2/3/4/5/6/8/10/12/15 avg_look_ahead = 24; // 1/2/3/4/6/8/12/24 addr_align = 1;}uint64 x86dis::getoffset(){ return addr.addr32.offset;}void x86dis::filloffset(CPU_ADDR &addr, uint64 offset){ addr.addr32.offset = offset;}uint32 x86dis::getdisp(){ if (have_disp) return disp; have_disp = true; int modrm = getmodrm(); int mod = mkmod(modrm); if (mod == 3) return 0; int rm = mkrm(modrm); if (insn.eaddrsize == X86_ADDRSIZE16) { if (mod == 0 && rm == 6) { disp = getword(); } else { switch (mod) { case 1: disp = getbyte(); break; case 2: disp = getword(); break; } } } else { if (mod == 0 && rm == 5) { disp = getdword(); } else if (rm == 4) { int sib = getsib(); int base = mkbase(sib); int d = mod; if ((base & 0x7) == 5 && mod == 0) { d = 2; } switch (d) { case 1: disp = getbyte(); break; case 2: disp = getdword(); break; } } else { switch (mod) { case 1: disp = getbyte(); break; case 2: disp = getdword(); break; } } } return disp;}int x86dis::getmodrm(){ if (modrm == -1) modrm = getbyte(); return modrm;}int x86dis::getdrex(){ if (drex == -1) { getmodrm(); int modrm = getmodrm(); int mod = mkmod(modrm); int rm = mkrm(modrm); if (mod != 3 && (rm & 7) == 4) { getsib(); } drex = getbyte(); if (addrsize != X86_ADDRSIZE64) { drex &= 0x78; } insn.rexprefix = drex & 0x7; } return drex;}int x86dis::getspecialimm(){ if (special_imm == -1) special_imm = getbyte(); return special_imm;}const char *x86dis::getName(){ return "x86/Disassembler";}int x86dis::getsib(){ if (sib == -1) sib = getbyte(); return sib;}byte x86dis::getSize(dis_insn *disasm_insn){ return ((x86dis_insn*)disasm_insn)->size;}void x86dis::invalidate(){ insn.invalid = true;}bool x86dis::isfloat(char c){ switch (c) { case SIZE_S: case SIZE_L: case SIZE_T: return true; } return false;}bool x86dis::isaddr(char c){ switch (c) { case SIZE_P: return true; } return false;}void x86dis::load(ObjectStream &f){ Disassembler::load(f); opsize = (X86OpSize)GETX_INT32(f, "opsize"); addrsize = (X86AddrSize)GETX_INT32(f, "addrsize"); x86_insns = &x86_32_insns;}ObjectID x86dis::getObjectID() const{ return ATOM_DISASM_X86;}void x86dis::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: insn.segprefix = X86_PREFIX_ES; continue; case 0x2e: insn.segprefix = X86_PREFIX_CS; continue; case 0x36: insn.segprefix = X86_PREFIX_SS; continue; case 0x3e: insn.segprefix = X86_PREFIX_DS; continue; 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 = (opsize == X86_OPSIZE16) ? X86_OPSIZE32 : X86_OPSIZE16; continue; case 0x67: insn.eaddrsize = (addrsize == X86_ADDRSIZE16) ? X86_ADDRSIZE32 : X86_ADDRSIZE16; 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; } /* no prefix found -> exit loop */ break; }}static const char *regs(x86dis_insn *insn, int mode, int nr){ if (insn->rexprefix) { return x86_64regs[mode][nr]; } else { return x86_regs[mode][nr]; }}void x86dis::str_op(char *opstr, int *opstrlen, x86dis_insn *insn, x86_insn_op *op, bool explicit_params){ const char *cs_default = get_cs(e_cs_default); const char *cs_number = get_cs(e_cs_number); const char *cs_symbol = get_cs(e_cs_symbol); *opstrlen=0; switch (op->type) { case X86_OPTYPE_IMM: { CPU_ADDR a; filloffset(a, op->imm); int slen; char *s=(addr_sym_func) ? addr_sym_func(a, &slen, addr_sym_func_context) : NULL; if (s) { memcpy(opstr, s, slen); opstr[slen] = 0; *opstrlen = slen; } else { char *g = opstr; strcpy(g, cs_number); g += strlen(cs_number); switch (op->size) { case 1: hexd(&g, 2, options, op->imm); break; case 2: hexd(&g, 4, options, op->imm); break; case 4: hexd(&g, 8, options, op->imm); break; case 8: hexq(&g, 16, options, op->imm); break; } strcpy(g, cs_default); g += strlen(cs_default); } break; } case X86_OPTYPE_REG: { int j = -1; switch (op->size) { case 1: j = 0; break; case 2: j = 1; break; case 4: j = 2; break; case 8: j = 3; break; default: {assert(0);} } if (!insn->rexprefix) { sprintf(opstr, x86_regs[j][op->reg]); } else { sprintf(opstr, x86_64regs[j][op->reg]); } break; } case X86_OPTYPE_SEG: if (x86_segs[op->seg]) { sprintf(opstr, x86_segs[op->seg]); } break; case X86_OPTYPE_CRX: sprintf(opstr, "cr%d", op->crx); break; case X86_OPTYPE_DRX: sprintf(opstr, "dr%d", op->drx); break; case X86_OPTYPE_STX: if (op->stx) { sprintf(opstr, "st%s(%s%d%s)%s", cs_symbol, cs_number, op->stx, cs_symbol, cs_default); } else { strcpy(opstr, "st"); } break; case X86_OPTYPE_MMX: sprintf(opstr, "mm%d", op->mmx); break; case X86_OPTYPE_XMM: sprintf(opstr, "xmm%d", op->xmm); break; case X86_OPTYPE_YMM: sprintf(opstr, "ymm%d", op->ymm); break; case X86_OPTYPE_MEM: { char *d=opstr; if (explicit_params) { if (op->mem.floatptr) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -