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

📄 x86dis.cc

📁 功能较全面的反汇编器:反汇编器ht-2.0.15.tar.gz
💻 CC
📖 第 1 页 / 共 3 页
字号:
				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 + -