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

📄 x86asm.cc

📁 功能较全面的反汇编器:反汇编器ht-2.0.15.tar.gz
💻 CC
📖 第 1 页 / 共 4 页
字号:
		break;	case X86ASM_PREFIX_0F7B:		emitbyte(0x0f);		emitbyte(0x7b);		break;	case X86ASM_PREFIX_DF:	case X86ASM_PREFIX_DE:	case X86ASM_PREFIX_DD:	case X86ASM_PREFIX_DC:	case X86ASM_PREFIX_DB:	case X86ASM_PREFIX_DA:	case X86ASM_PREFIX_D9:	case X86ASM_PREFIX_D8:		opcodeb = 0xd8 + prefix - X86ASM_PREFIX_D8;		break;	}	emitbyte(opcodeb);	/* encode the ops */	for (int i=0; i < 4; i++) {		if (!encode_op(&insn->op[i], &x86_op_type[opcode->op[i]], &esizes[i], eopsize, eaddrsize)) {			clearcode();			return false;		}	}	/* write the rest */	if (modrmv != -1) emitbyte(modrmv);	if (sibv != -1) emitbyte(sibv);		if (drexdest != -1) {		byte oc0 = 0;		if (drexoc0 != -1) {			oc0 = drexoc0;		}		byte drex = (drexdest << 4) | (oc0 << 3) | (rexprefix & 7);		rexprefix = 0;		emitbyte(drex);	}	if (disppos && addrsize == X86_ADDRSIZE64) {		// fix ip-relative disp in PM64 mode		dispsize = 4;		disp -= address + code.size + dispsize + immsize;		if (simmsize(disp, 4) > 4) {			clearcode();			return false;		}	}	switch (dispsize) {	case 1:		emitbyte(disp);		break;	case 2:		emitword(disp);		break;	case 4:		emitdword(disp);		break;	case 8:		emitqword(disp);		break;	}	switch (immsize) {	case 1:		emitbyte(imm);		break;	case 2:		emitword(imm);		break;	case 4:		emitdword(imm);		break;	case 6:		emitdword(imm);		emitword(imm2);		break;	case 8:		emitqword(imm);		break;	}	// fix rex code	if (rexprefix & 0x40) {		code.data[rexpos] = rexprefix;	}		return true;}bool x86asm::encode_vex_insn(x86asm_insn *insn, x86opc_vex_insn *opcode, int opcodeb, int additional_opcode, int eopsize, int eaddrsize){	rexprefix = 0;	disppos = 0;	immsize = 0;	dispsize = 0;	vexvvvv = 0;	modrmv = -1;	sibv = -1;	if (additional_opcode != -1) {		emitmodrm_reg(additional_opcode);	}	switch (insn->lockprefix) {	case X86_PREFIX_LOCK: 		clearcode();		return false;	}	switch (insn->repprefix) {	case X86_PREFIX_REPNZ:	case X86_PREFIX_REPZ: 		clearcode();		return false;	}	switch (insn->segprefix) {	case X86_PREFIX_ES: emitbyte(0x26); break;	case X86_PREFIX_CS: emitbyte(0x2e); break;	case X86_PREFIX_SS: emitbyte(0x36); break;	case X86_PREFIX_DS: emitbyte(0x3e); break;	case X86_PREFIX_FS: emitbyte(0x64); break;	case X86_PREFIX_GS: emitbyte(0x65); break;	}	for (int i=0; i < 5; i++) {		if (!encode_op(&insn->op[i], &x86_op_type[opcode->op[i]], &esizes[i], eopsize, eaddrsize)) {			clearcode();			return false;		}	}	if ((opcode->vex & 0x30) == 0x10 // 0x0f-opcode	 && !(rexprefix & 3)          // no rexb/rexx	 && !(opcode->vex & W1)) {		// use short vex prefix		emitbyte(0xc5);		byte vex = (~rexprefix & 4) << 5			| ((~vexvvvv & 0xf) << 3)			| (opcode->vex & _256) >> 4 			| (opcode->vex & 0x3);		emitbyte(vex);	} else {		// use long vex prefix		emitbyte(0xc4);		byte vex = (~rexprefix & 7) << 5 | ((opcode->vex & 0x30) >> 4);		emitbyte(vex);		vex = (opcode->vex & W1) | ((~vexvvvv & 0xf) << 3) 			| (opcode->vex & _256) >> 4 			| (opcode->vex & 0x3);		emitbyte(vex);	}	emitbyte(opcodeb);	if (modrmv != -1) emitbyte(modrmv);	if (sibv != -1) emitbyte(sibv);	if (disppos && addrsize == X86_ADDRSIZE64) {		// fix ip-relative disp in PM64 mode		dispsize = 4;		disp -= address + code.size + dispsize + immsize;		if (simmsize(disp, 4) > 4) {			clearcode();			return false;		}	}	switch (dispsize) {	case 1:		emitbyte(disp);		break;	case 2:		emitword(disp);		break;	case 4:		emitdword(disp);		break;	}	switch (immsize) {	case 1:		emitbyte(imm);		break;	}	return true;}bool x86asm::encode_modrm(x86_insn_op *op, char size, bool allow_reg, bool allow_mem, int eopsize, int eaddrsize){	switch (op->type) {	case X86_OPTYPE_REG:		if (!allow_reg) return false;		emitmodrm_mod(3);		emitmodrm_rm(op->reg);		if (op->reg > 7) rexprefix |= rexb;		break;	case X86_OPTYPE_MEM: {		if (!allow_mem) return false;		int addrsize = op->mem.addrsize;		int mindispsize = addr2size[addrsize+1];		if (addrsize == X86_ADDRSIZEUNKNOWN) {			addrsize = eaddrsize;			if (this->addrsize == X86_ADDRSIZE64) {				// ip-relative, we check this later				mindispsize = 4;			} else {				mindispsize = op->mem.disp ? simmsize(op->mem.disp, 8) : 0;			}		} else {			mindispsize = op->mem.disp ? simmsize(op->mem.disp, mindispsize) : 0;			if (mindispsize > 4) return false;		}		if (addrsize == X86_ADDRSIZE16) {			int mod, rm, dispsize;			if (!encode_modrm_v(&modrm16, op, mindispsize, &mod, &rm, &dispsize)) return 0;			emitmodrm_mod(mod);			emitmodrm_rm(rm);			emitdisp(op->mem.disp, dispsize);		} else {			int mod, rm, dispsize;			if (!encode_modrm_v(&modrm32, op, mindispsize, &mod, &rm, &dispsize)) {				int scale, index, base, disp=op->mem.disp;				if (encode_sib_v(op, mindispsize, &scale, &index, &base, &mod, &dispsize, &disp)) {					emitmodrm_mod(mod);					emitmodrm_rm(4);		/* SIB */					emitsib_scale(scale);					emitsib_index(index);					emitsib_base(base);					emitdisp(disp, dispsize);				} else return false;			} else {				emitmodrm_mod(mod);				emitmodrm_rm(rm);				emitdisp(op->mem.disp, dispsize);			}		}		break;	}	case X86_OPTYPE_MMX:		if (!allow_reg) return false;		emitmodrm_mod(3);		emitmodrm_rm(op->mmx);		break;	case X86_OPTYPE_XMM:		if (!allow_reg) return false;		emitmodrm_mod(3);		emitmodrm_rm(op->xmm);		break;	case X86_OPTYPE_YMM:		if (!allow_reg) return false;		emitmodrm_mod(3);		emitmodrm_rm(op->ymm);		break;	default:		return false;	}	return true;}bool x86asm::encode_modrm_v(const x86addrcoding (*modrmc)[3][8], x86_insn_op *op, int mindispsize, int *_mod, int *_rm, int *_dispsize){	if (op->mem.scale > 1) return false;	for (int mod=0; mod < 3; mod++) {		for (int rm=0; rm < 8; rm++) {			const x86addrcoding *c=&(*modrmc)[mod][rm];			int r1=c->reg1, r2=c->reg2;			if (r2 == (op->mem.base&~8)) {				int t = r1;				r1 = r2;				r2 = t;			}			if (r1==(op->mem.base&~8) && r2==(op->mem.index&~8) && c->dispsize>=mindispsize) {				*_mod=mod;				*_rm=rm;				*_dispsize=c->dispsize;				if (this->addrsize == X86_ADDRSIZE64				    && mod == 0 && rm == 5) {					// ip-relative addressing					disppos = 1;				}				if (op->mem.base & 8) rexprefix |= rexb;				return true;			}		}	}	return false;}bool x86asm::encode_op(x86_insn_op *op, x86opc_insn_op *xop, int *esize, int eopsize, int eaddrsize){	int psize = op->size;	switch (xop->type) {	case TYPE_0:		return true;	case TYPE_A:		/* direct address without ModR/M */		if (op->type == X86_OPTYPE_FARPTR) {			int size = esizeop_ex(xop->size, eopsize);			emitfarptr(op->farptr.seg, op->farptr.offset, size == 6);		} else {			emitimm(op->imm, op->size);		}		break;	case TYPE_C:		/* reg of ModR/M picks control register */		emitmodrm_reg(op->crx);		if (op->crx > 7) rexprefix |= rexr;		break;	case TYPE_D:		/* reg of ModR/M picks debug register */		emitmodrm_reg(op->drx);		if (op->drx > 7) rexprefix |= rexr;		break;	case TYPE_E:		/* ModR/M (general reg or memory) */		if (!encode_modrm(op, xop->size, true, true, eopsize, eaddrsize)) return false; //XXX		psize = esizeop(xop->size, eopsize); //XXX		break;	case TYPE_F:		/* r/m of ModR/M picks a fpu register */		emitmodrm_rm(op->stx);		break;	case TYPE_Fx:		/* extra picks a fpu register */		return true;	case TYPE_G:		/* reg of ModR/M picks general register */		emitmodrm_reg(op->reg);		if (op->reg > 7) rexprefix |= rexr;				break;	case TYPE_Is: {		/* signed immediate */		int size = esizeop_ex(xop->size, eopsize);		emitimm(op->imm, size);		break;	}	case TYPE_I: {		/* unsigned immediate */		int size = esizeop_ex(xop->size, eopsize);		emitimm(op->imm, size);		break;	}	case TYPE_Ix:		/* fixed immediate */		return true;	case TYPE_I4: {		/* 4 bit immediate (see TYPE_VI, TYPE_YI) */		if (op->imm > 15) return false;		if (immsize == 0) {			immsize = 1;			imm = 0;		}		imm |= op->imm;		break;	}	case TYPE_J: {		/* relative branch offset */		int size = esizeop_ex(xop->size, eopsize);		emitimm(uint32(op->imm - address - code.size - size), size);		break;	}	case TYPE_M:		/* ModR/M (memory only) */		if (!encode_modrm(op, xop->size, false, true, eopsize, eaddrsize)) return false; // XXX		psize = esizeop(xop->size, eopsize); //XXX		break;	case TYPE_MR: {		/* Same as E, but extra picks reg size */		byte xopsize = xop->size;		if (op->type == X86_OPTYPE_REG) {			xopsize = xop->extra;		}		if (!encode_modrm(op, xopsize, true, true, eopsize, eaddrsize)) return false; //XXX		psize = esizeop(xopsize, eopsize); //XXX		break;	}	case TYPE_O: {		/* direct memory without ModR/M */		if (op->mem.base != X86_REG_NO) return false;		if (op->mem.index != X86_REG_NO) return false;		psize = esizeop(xop->size, eopsize); // XXX		switch (eaddrsize) {		case X86_ADDRSIZE16:			if (op->mem.disp > 0xffff) return false;			emitdisp(op->mem.disp, 2);			break;		case X86_ADDRSIZE32:			if (op->mem.disp > 0xffffffff) return false;			emitdisp(op->mem.disp, 4);			break;		case X86_ADDRSIZE64:			emitdisp(op->mem.disp, 8);			break;		}		break;	}	case TYPE_P:		/* reg of ModR/M picks MMX register */		emitmodrm_reg(op->mmx);		break;	case TYPE_PR:		/* rm of ModR/M picks MMX register */		emitmodrm_mod(3);		emitmodrm_rm(op->mmx);		break;	case TYPE_Q:		/* ModR/M (MMX reg or memory) */		if (!encode_modrm(op, xop->size, true, true, eopsize, eaddrsize)) return false; //XXX		psize = esizeop(xop->size, eopsize); //XXX		break;	case TYPE_R:		/* rm of ModR/M picks general register */		emitmodrm_rm(op->reg);		// fall throu	case TYPE_Rx:		if (op->reg > 7) rexprefix |= rexb;		return true;	case TYPE_RXx:		/* extra picks register, no REX */		return true;	case TYPE_S:		/* reg of ModR/M picks segment register */		emitmodrm_reg(op->seg);		break;	case TYPE_Sx:		/* extra picks segment register */		return true;	case TYPE_V:		/* reg of ModR/M picks XMM register */		emitmodrm_reg(op->xmm);		if (op->xmm > 7) rexprefix |= rexr;		break;	case TYPE_VR:		/* rm of ModR/M picks XMM register */		emitmodrm_mod(3);		emitmodrm_rm(op->xmm);		if (op->xmm > 7) rexprefix |= rexb;		break;	case TYPE_Vx:		break;	case TYPE_VV:		vexvvvv = op->xmm;		break;	case TYPE_VI: {		/* bits 7-4 of imm pick XMM register */		if (immsize == 0) {			immsize = 1;			imm = 0;		}		imm |= op->xmm << 4;		break;	}	case TYPE_VD:		if (drexdest == -1) {			drexdest = op->xmm;		} else {			if (drexdest != op->xmm) {				return false;			}		}		break;	case TYPE_VS:		if (op->type == X86_OPTYPE_XMM) {			if (drexoc0 == 0) {				emitmodrm_mod(3);				emitmodrm_rm(op->xmm);				if (op->xmm > 7) rexprefix |= rexb;							} else {				emitmodrm_reg(op->xmm);				if (op->xmm > 7) rexprefix |= rexr;				if (drexoc0 == -1) drexoc0 = 0;			}		} else {			if (drexoc0 == 1) return false;			if (drexoc0 == -1) {				if (xop->info) return false;				drexoc0 = 1;			}			if (!encode_modrm(op, xop->size, true, true, eopsize, eaddrsize)) return false; //XXX			psize = esizeop(xop->size, eopsize); //XXX		}		break;	case TYPE_W:		/* ModR/M (XMM reg or memory) */		if (!encode_modrm(op, xop->size, true, true, eopsize, eaddrsize)) return false; //XXX		psize = esizeop(xop->size, eopsize); //XXX		break;	case TYPE_Y:		/* reg of ModR/M picks YMM register */		emitmodrm_reg(op->ymm);		if (op->ymm > 7) rexprefix |= rexr;		break;	case TYPE_YI: {		/* bits 7-4 of imm pick YMM register */		if (immsize == 0) {			immsize = 1;			imm = 0;		}		imm |= op->xmm << 4;		break;	}	case TYPE_YV:		vexvvvv = op->ymm;		break;	case TYPE_YR:		/* rm of ModR/M picks YMM register */		emitmodrm_mod(3);		emitmodrm_rm(op->ymm);		if (op->ymm > 7) rexprefix |= rexb;		break;	case TYPE_X:		/* ModR/M (YMM reg or memory) */		if (!encode_modrm(op, xop->size, true, true, eopsize, eaddrsize)) return false; //XXX		psize = esizeop(xop->size, eopsize); //XXX		break;	}	if (!psize) {//		set_error_msg(X86ASM_ERRMSG_INTERNAL"FIXME: size ??? %s, %d\n", __FILE__, __LINE__);	}	if (!*esize) *esize = psize;/*	if (!(options & X86ASM_ALLOW_AMBIGUOUS) && *esize != psize) {		ambiguous = 1;		set_error_msg(X86ASM_ERRMSG_AMBIGUOUS);		return 0;	}*/	return true;}bool x86asm::encode_sib_v(x86_insn_op *op, int mindispsize, int *_ss, int *_index, int *_base, int *_mod, int *_dispsize, int *disp){	int ss, scale=op->mem.scale, index=op->mem.index, base=op->mem.base, mod, dispsize;	if (base == X86_REG_NO && index != X86_REG_NO) {		switch (scale) {		case 1: case 4: case 8:			break;		case 2: case 3: case 5: case 9:			scale--;			base = index;			break;		default:			return false;		}	}	if (index == X86_REG_SP) {		if (scale > 1) return false;		if (scale == 1) {			if (base == X86_REG_SP) return false;			int temp = index;			index = base;			base = temp;		}	}	if (index != X86_REG_NO) {		switch (scale) {		case 1:			ss = 0;			break;		case 2:			ss = 1;			break;		case 4:			ss = 2;			break;		case 8:			ss = 3;			break;		default:			return 0;		}					} else {		ss = 0;		index = 4;	}			switch (mindispsize) {

⌨️ 快捷键说明

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