⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x86dis.cc

📁 功能较全面的反汇编器:反汇编器ht-2.0.15.tar.gz
💻 CC
📖 第 1 页 / 共 3 页
字号:
/* *	HT Editor *	x86dis.cc * *	Copyright (C) 1999-2002 Stefan Weyergraf *	Copyright (C) 2005-2008 Sebastian Biallas (sb@biallas.net) * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License version 2 as *	published by the Free Software Foundation. * *	This program is distributed in the hope that it will be useful, *	but WITHOUT ANY WARRANTY; without even the implied warranty of *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *	GNU General Public License for more details. * *	You should have received a copy of the GNU General Public License *	along with this program; if not, write to the Free Software *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <cstdio>#include <cstring>#include "htdebug.h"#include "stream.h"#include "snprintf.h"#include "strtools.h"#include "tools.h"#include "vxd.h"#include "x86dis.h"#define mkscale mkmod#define mkbase mkrm#define rexw(rex) ((rex)&0x08)#define rexr(rex) ((rex)&0x04)#define rexx(rex) ((rex)&0x02)#define rexb(rex) ((rex)&0x01)#define drexdest(drex) ((drex)>>4)#define oc0(drex) (!!((drex)&8))#define vexw(vex) (!!((vex)&0x80))#define vexr(vex) (!((vex)&0x80))#define vexx(vex) (!((vex)&0x40))#define vexb(vex) (!((vex)&0x20))#define vexl(vex) (!!((vex)&0x04))#define vexmmmm(vex) ((vex)&0xf)#define vexvvvv(vex) (((~(vex))>>3)&0xf)#define vexpp(vex) ((vex)&0x3)static int modrm16_1[8] = { X86_REG_BX, X86_REG_BX, X86_REG_BP, X86_REG_BP,                     X86_REG_SI, X86_REG_DI, X86_REG_BP, X86_REG_BX};static int modrm16_2[8] = { X86_REG_SI, X86_REG_DI, X86_REG_SI, X86_REG_DI,                     X86_REG_NO, X86_REG_NO, X86_REG_NO, X86_REG_NO};static int sibscale[4] = {1, 2, 4, 8};/* *	CLASS x86dis */x86dis::x86dis(X86OpSize aOpsize, X86AddrSize aAddrsize){	opsize = aOpsize;	addrsize = aAddrsize;	insn.invalid = true;	x86_insns = &x86_32_insns;}void x86dis::checkInfo(x86opc_insn *xinsn){}dis_insn *x86dis::decode(byte *code, int Maxlen, CPU_ADDR Addr){	ocodep = code;	codep = ocodep;	maxlen = Maxlen;	addr = Addr;	modrm = -1;	sib = -1;	drex = -1;	special_imm = -1;	have_disp = false;	memset(&insn, 0, sizeof insn);	insn.invalid = false;	insn.eopsize = opsize;	insn.eaddrsize = addrsize;	prefixes();	fixdisp = false;	insn.opcode = c;	decode_insn(&(*x86_insns)[insn.opcode]);	if (insn.invalid) {		insn.name = "db";		insn.size = 1;		insn.op[0].type = X86_OPTYPE_IMM;		insn.op[0].size = 1;		insn.op[0].imm = *code;		insn.opsizeprefix = X86_PREFIX_NO;		insn.lockprefix = X86_PREFIX_NO;		insn.repprefix = X86_PREFIX_NO;		insn.segprefix = X86_PREFIX_NO;		insn.rexprefix = 0;		for (int i = 1; i < 5; i++) insn.op[i].type = X86_OPTYPE_EMPTY;	} else {		insn.size = codep - ocodep;		if (fixdisp) {			// ip-relativ addressing in PM64			for (int i = 0; i < 2; i++) {				if (insn.op[i].type == X86_OPTYPE_MEM && insn.op[i].mem.hasdisp) {					insn.op[i].mem.disp += getoffset() + insn.size;				}			}		}	}	return &insn;}uint x86dis::mkmod(uint modrm){	return modrm>>6 & 0x03;}uint x86dis::mkreg(uint modrm){	return (modrm>>3 & 0x07) | !!rexr(insn.rexprefix) << 3;}uint x86dis::mkindex(uint sib){	return (sib>>3 & 0x07) | !!rexx(insn.rexprefix) << 3;	}uint x86dis::mkrm(uint modrm){	return (modrm & 0x07) | !!rexb(insn.rexprefix) << 3;	}static bool is_xmm_op(x86dis_insn *insn, char size){	if (insn->opsizeprefix == X86_PREFIX_OPSIZE	 && (size == SIZE_U || size == SIZE_Z)) {		return true;	} else {		return false;	}}void x86dis::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) {		/* reg */		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;		} else if (ymm) {			op->type = X86_OPTYPE_YMM;			op->xmm = rm;		} else {			op->type = X86_OPTYPE_REG;			op->reg = rm;		}		op->size = esizeop(size);	} else {		/* mem */		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 (insn.eaddrsize == X86_ADDRSIZE16) {			if (mod == 0 && rm == 6) {				op->mem.hasdisp = true;				op->mem.disp = disp;				op->mem.base = X86_REG_NO;				op->mem.index = X86_REG_NO;				op->mem.scale = 0;			} else {				op->mem.base = modrm16_1[rm];				op->mem.index = modrm16_2[rm];				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(sint16(disp));					break;				}			}		} else {			if (mod == 0 && rm == 5) {				op->mem.hasdisp = true;				op->mem.disp = disp;				op->mem.base = X86_REG_NO;				op->mem.index = X86_REG_NO;				op->mem.scale = 0;			} else if (rm == 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 x86dis::decode_sib(x86_insn_op *op, int mod){	int sib = getsib();	int scale = mkscale(sib);	int index = mkindex(sib);	int base = mkbase(sib);	int sdisp = mod;	if ((base & 0x7) == 5 && mod == 0) {		base = X86_REG_NO;		sdisp = 2;	}	if (index == 4) {		index = X86_REG_NO;	}	op->mem.base = base;	op->mem.index = index;	op->mem.scale = sibscale[scale];	switch (sdisp) {	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 x86dis::decode_vex_insn(x86opc_vex_insn *xinsn){	if (xinsn) {		byte vex = (insn.vexprefix.w << 7) | (insn.vexprefix.l << 6)			| (insn.vexprefix.mmmm << 4) | insn.vexprefix.pp;		while (!xinsn->name && xinsn->op[0] == SPECIAL_TYPE_GROUP) {			if (xinsn->vex == vex) {				getdisp();				int m = mkreg(getmodrm()) & 0x7;				xinsn = &x86_group_vex_insns[xinsn->op[1]][m];				if (!xinsn->name) {					invalidate();				} else {					insn.name = xinsn->name;					for (int i = 0; i < 5; i++) {						decode_op(&insn.op[i], &x86_op_type[xinsn->op[i]]);					}					return;				}			}			xinsn++;		}		while (xinsn->name) {			if (xinsn->vex == vex) {				insn.name = xinsn->name;								for (int i = 0; i < 5; i++) {					x86opc_insn_op *op = &x86_op_type[xinsn->op[i]];					switch (op->type) {					case TYPE_E:					case TYPE_M:					case TYPE_W:					case TYPE_X:						/* get whole modrm/sib/disp stuff first		    				 * (otherwise a TYPE_VI immediate might 						 * get fetched fetched before the modrm stuff)						 */						getdisp();					}				}								for (int i = 0; i < 5; i++) {					decode_op(&insn.op[i], &x86_op_type[xinsn->op[i]]);				}				return;			}			xinsn++;		}	}	invalidate();}void x86dis::decode_insn(x86opc_insn *xinsn){	if (!xinsn->name) {		byte specialtype = xinsn->op[0];		byte specialdata = xinsn->op[1];		switch (specialtype) {		case SPECIAL_TYPE_INVALID:			invalidate();			break;		case SPECIAL_TYPE_PREFIX:			switch (c) {			case 0x0f:				if (insn.opcodeclass == X86DIS_OPCODE_CLASS_STD) {					insn.opcode = getbyte();					switch (insn.repprefix) {					case X86_PREFIX_REPNZ:						if (insn.opsizeprefix == X86_PREFIX_OPSIZE) {							invalidate();						} else {							insn.repprefix = X86_PREFIX_NO;							insn.opcodeclass = X86DIS_OPCODE_CLASS_EXT_F2;							decode_insn(&x86_insns_ext_f2[insn.opcode]);						}						break;					case X86_PREFIX_REPZ:						if (insn.opsizeprefix == X86_PREFIX_OPSIZE) {							invalidate();						} else {							insn.repprefix = X86_PREFIX_NO;							insn.opcodeclass = X86DIS_OPCODE_CLASS_EXT_F3;							decode_insn(&x86_insns_ext_f3[insn.opcode]);						}						break;					default:						if (insn.opsizeprefix == X86_PREFIX_NO) {							insn.opcodeclass = X86DIS_OPCODE_CLASS_EXT;							decode_insn(&x86_insns_ext[insn.opcode]);						} else {							insn.opcodeclass = X86DIS_OPCODE_CLASS_EXT_66;							decode_insn(&x86_insns_ext_66[insn.opcode]);						}					}					break;				}				invalidate();				break;			case 0xc4:			case 0xc5: {				if (insn.opsizeprefix != X86_PREFIX_NO				 || insn.lockprefix != X86_PREFIX_NO				 || insn.repprefix != X86_PREFIX_NO				 || insn.rexprefix != 0) {					invalidate();					break;				}				byte vex = getbyte();				if (addrsize != X86_ADDRSIZE64				 && (vex & 0xc0) != 0xc0) {					modrm = vex;					decode_insn(c == 0xc4 ? &x86_les : &x86_lds);					break;				}				insn.rexprefix = 0x40;				insn.rexprefix = vexr(vex) << 2;				if (c == 0xc4) {					// 3 byte vex					insn.rexprefix |= vexx(vex) << 1;					insn.rexprefix |= vexb(vex);					insn.vexprefix.mmmm = vexmmmm(vex);					if (insn.vexprefix.mmmm == 0					 || insn.vexprefix.mmmm > 3) {						invalidate();						break;					}					vex = getbyte();					insn.vexprefix.w |= vexw(vex);				} else {					// 2 byte vex					insn.vexprefix.mmmm = 1;				}				insn.vexprefix.vvvv = vexvvvv(vex);				insn.vexprefix.l = vexl(vex);				insn.vexprefix.pp = vexpp(vex);				if (addrsize != X86_ADDRSIZE64) {					insn.rexprefix = 0;				}								insn.opcode = getbyte();				decode_vex_insn(x86_vex_insns[insn.opcode]);				break;			}			default:				invalidate();				break;			}			break;		case SPECIAL_TYPE_OPC_GROUP: {			insn.opcodeclass = X86DIS_OPCODE_CLASS_EXT;			insn.opcode = getbyte();			decode_insn(&x86_opc_group_insns[specialdata][insn.opcode]);			break;		}		case SPECIAL_TYPE_GROUP: {			int m = mkreg(getmodrm()) & 0x7;			decode_insn(&x86_group_insns[specialdata][m]);			break;		}		case SPECIAL_TYPE_SGROUP: {			int m = getmodrm();			if (mkmod(m) != 3) {				m = 8;			} else {				m = mkrm(m) & 0x7;			}			decode_insn(&x86_special_group_insns[specialdata][m]);			break;		}		case SPECIAL_TYPE_FGROUP: {			int m = getmodrm();			if (mkmod(m) == 3) {				x86opc_finsn f = x86_float_group_insns[specialdata][mkreg(m) & 0x7];/*				fprintf(stderr, "special.data=%d, m=%d, mkreg(m)=%d, mkrm(m)=%d\n", special.data, m, mkreg(m), mkrm(m));*/				if (f.group) {					decode_insn(&f.group[mkrm(m) & 0x7]);				} else if (f.insn.name) {					decode_insn(&f.insn);				} else invalidate();			} else {				decode_insn(&x86_modfloat_group_insns[specialdata][mkreg(m) & 0x7]);			}			break;		}		}	} else {		checkInfo(xinsn);				insn.name = xinsn->name;		for (int i = 0; i < 4; i++) {			decode_op(&insn.op[i], &x86_op_type[xinsn->op[i]]);		}	}}void x86dis::decode_op(x86_insn_op *op, x86opc_insn_op *xop){	switch (xop->type) {	case TYPE_0:		return;	case TYPE_A: {		/* direct address without ModR/M */		op->type = X86_OPTYPE_FARPTR;		op->size = esizeop(xop->size);		switch (op->size) {		case 4:			op->farptr.offset = getword();			op->farptr.seg = getword();			break;		case 6:			op->farptr.offset = getdword();			op->farptr.seg = getword();			break;		}		break;	}	case TYPE_C: {		/* reg of ModR/M picks control register */		op->type = X86_OPTYPE_CRX;		op->size = esizeop(xop->size);		op->crx = mkreg(getmodrm());		break;	}	case TYPE_D: {		/* reg of ModR/M picks debug register */		op->type = X86_OPTYPE_DRX;		op->size = esizeop(xop->size);		op->drx = mkreg(getmodrm());		break;	}	case TYPE_E: {		/* ModR/M (general reg or memory) */		decode_modrm(op, xop->size, (xop->size != SIZE_P), true, false, false, false);		break;	}	case TYPE_F: {		/* r/m of ModR/M picks a fpu register */		op->type = X86_OPTYPE_STX;		op->size = 10;		op->stx = mkrm(getmodrm());		break;	}	case TYPE_Fx: {		/* extra picks a fpu register */		op->type = X86_OPTYPE_STX;		op->size = 10;		op->stx = xop->extra;		break;	}	case TYPE_G: {		/* reg of ModR/M picks general register */		op->type = X86_OPTYPE_REG;		op->size = esizeop(xop->size);		op->reg = mkreg(getmodrm());		break;	}	case TYPE_Is: {		/* signed immediate */		op->type = X86_OPTYPE_IMM;		op->size = esizeop(xop->size);		int s = esizeop_ex(xop->size);		switch (s) {		case 1:			op->imm = sint64(sint8(getbyte()));			break;		case 2:			op->imm = sint64(sint16(getword()));			break;		case 4:			op->imm = sint64(sint32(getdword()));			break;		case 8:			op->imm = getqword();			break;		}		switch (op->size) {		case 1:			op->imm &= 0xff;			break;		case 2:			op->imm &= 0xffff;			break;		case 4:			op->imm &= 0xffffffff;			break;		}		break;	}	case TYPE_I: {		/* unsigned immediate */		op->type = X86_OPTYPE_IMM;		op->size = esizeop(xop->size);		int s = esizeop_ex(xop->size);		switch (s) {		case 1:			op->imm = getbyte();			break;		case 2:			op->imm = getword();			break;		case 4:			op->imm = sint64(sint32(getdword()));			break;		case 8:			op->imm = getqword();			break;		}		switch (op->size) {		case 1:			op->imm &= 0xff;			break;		case 2:			op->imm &= 0xffff;			break;		case 4:			op->imm &= 0xffffffff;			break;		}		break;	}	case TYPE_Ix: {		/* fixed immediate */		op->type = X86_OPTYPE_IMM;		op->size = esizeop(xop->size);		op->imm = xop->extra;		break;	}	case TYPE_I4: {		/* 4 bit immediate (see TYPE_VI, TYPE_YI) */		op->type = X86_OPTYPE_IMM;		op->size = 1;		op->imm = getspecialimm() & 0xf;		break;	}	case TYPE_J: {		/* relative branch offset */		op->type = X86_OPTYPE_IMM;		switch (addrsize) {		case X86_ADDRSIZE16:			op->size = 2;			break;		case X86_ADDRSIZE32:			op->size = 4;			break;		case X86_ADDRSIZE64:			op->size = 8;			break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -