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

📄 x86asm.cc

📁 功能较全面的反汇编器:反汇编器ht-2.0.15.tar.gz
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* *	HT Editor *	x86asm.cc * *	Copyright (C) 1999-2002 Stefan Weyergraf *	Copyright (C) 2005-2007 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 <stdlib.h>#include <string.h>#include "x86asm.h"#include "snprintf.h"#include "strtools.h"enum {	X86ASM_PREFIX_NO,	X86ASM_PREFIX_0F,	X86ASM_PREFIX_F20F,	X86ASM_PREFIX_F30F,	X86ASM_PREFIX_0F0F,	X86ASM_PREFIX_0F38,	X86ASM_PREFIX_660F38,	X86ASM_PREFIX_F20F38,	X86ASM_PREFIX_0F3A,	X86ASM_PREFIX_660F3A,	X86ASM_PREFIX_0F7A,	X86ASM_PREFIX_0F7B,	X86ASM_PREFIX_0F24,	X86ASM_PREFIX_0F25,	X86ASM_PREFIX_D8,	X86ASM_PREFIX_D9,	X86ASM_PREFIX_DA,	X86ASM_PREFIX_DB,	X86ASM_PREFIX_DC,	X86ASM_PREFIX_DD,	X86ASM_PREFIX_DE,	X86ASM_PREFIX_DF,};#define X86ASM_ERRMSG_AMBIGUOUS		"ambiguous command"#define X86ASM_ERRMSG_UNKNOWN_COMMAND	"unknown command '%s'"#define X86ASM_ERRMSG_INVALID_PREFIX	"invalid prefix"#define X86ASM_ERRMSG_UNKNOWN_SYMBOL	"unknown symbol '%s'"#define X86ASM_ERRMSG_INVALID_OPERANDS	"invalid operand(s)"#define X86ASM_ERRMSG_INTERNAL		"internal error: "#define rexw 0x48#define rexr 0x44#define rexx 0x42#define rexb 0x41static const x86addrcoding modrm16[3][8] = {/* mod = 0 */{{X86_REG_BX, X86_REG_SI, 0},{X86_REG_BX, X86_REG_DI, 0},{X86_REG_BP, X86_REG_SI, 0},{X86_REG_BP, X86_REG_DI, 0},{X86_REG_SI, X86_REG_NO, 0},{X86_REG_DI, X86_REG_NO, 0},{X86_REG_NO, X86_REG_NO, 2},{X86_REG_BX, X86_REG_NO, 0}},/* mod = 1 */{{X86_REG_BX, X86_REG_SI, 1},{X86_REG_BX, X86_REG_DI, 1},{X86_REG_BP, X86_REG_SI, 1},{X86_REG_BP, X86_REG_DI, 1},{X86_REG_SI, X86_REG_NO, 1},{X86_REG_DI, X86_REG_NO, 1},{X86_REG_BP, X86_REG_NO, 1},{X86_REG_BX, X86_REG_NO, 1}},/* mod = 2 */{{X86_REG_BX, X86_REG_SI, 2},{X86_REG_BX, X86_REG_DI, 2},{X86_REG_BP, X86_REG_SI, 2},{X86_REG_BP, X86_REG_DI, 2},{X86_REG_SI, X86_REG_NO, 2},{X86_REG_DI, X86_REG_NO, 2},{X86_REG_BP, X86_REG_NO, 2},{X86_REG_BX, X86_REG_NO, 2}}};static const x86addrcoding modrm32[3][8] = {/* mod = 0 */{{X86_REG_AX, X86_REG_NO, 0},{X86_REG_CX, X86_REG_NO, 0},{X86_REG_DX, X86_REG_NO, 0},{X86_REG_BX, X86_REG_NO, 0},{X86_REG_INVALID, X86_REG_INVALID, -1},		/* special: SIB */{X86_REG_NO, X86_REG_NO, 4},{X86_REG_SI, X86_REG_NO, 0},{X86_REG_DI, X86_REG_NO, 0}},/* mod = 1 */{{X86_REG_AX, X86_REG_NO, 1},{X86_REG_CX, X86_REG_NO, 1},{X86_REG_DX, X86_REG_NO, 1},{X86_REG_BX, X86_REG_NO, 1},{X86_REG_INVALID, X86_REG_INVALID, -1},		/* special: SIB + disp8 */{X86_REG_BP, X86_REG_NO, 1},{X86_REG_SI, X86_REG_NO, 1},{X86_REG_DI, X86_REG_NO, 1}},/* mod = 2 */{{X86_REG_AX, X86_REG_NO, 4},{X86_REG_CX, X86_REG_NO, 4},{X86_REG_DX, X86_REG_NO, 4},{X86_REG_BX, X86_REG_NO, 4},{X86_REG_INVALID, X86_REG_INVALID, -1},		/* special: SIB + disp32 */{X86_REG_BP, X86_REG_NO, 4},{X86_REG_SI, X86_REG_NO, 4},{X86_REG_DI, X86_REG_NO, 4}}};/* convert logical operand types to hardware operand types */static const byte lop2hop[12][9] = {	/* X86_OPTYPE_EMPTY */	{},	/* X86_OPTYPE_IMM */	{TYPE_I, TYPE_Is, TYPE_J, TYPE_A, TYPE_Ix, TYPE_I4},	/* X86_OPTYPE_REG */	{TYPE_R, TYPE_Rx, TYPE_RXx, TYPE_G, TYPE_E, TYPE_MR},	/* X86_OPTYPE_SEG */	{TYPE_S, TYPE_Sx},	/* X86_OPTYPE_MEM */	{TYPE_E, TYPE_M, TYPE_MR, TYPE_O, TYPE_Q, TYPE_W, TYPE_VS, TYPE_X},	/* X86_OPTYPE_CRX */	{TYPE_C},	/* X86_OPTYPE_DRX */	{TYPE_D},	/* X86_OPTYPE_STX */	{TYPE_F, TYPE_Fx},	/* X86_OPTYPE_MMX */	{TYPE_P, TYPE_Q, TYPE_PR},	/* X86_OPTYPE_XMM */	{TYPE_V, TYPE_W, TYPE_VR, TYPE_Vx, TYPE_VV, TYPE_VI, TYPE_VS, TYPE_VD},	/* X86_OPTYPE_YMM */	{TYPE_Y, TYPE_X, TYPE_YR, TYPE_YV, TYPE_YI},	/* X86_OPTYPE_FARPTR */	{},};static const char immhsz8_16[] = { SIZE_B, SIZE_BV, SIZE_W, SIZE_V, SIZE_VV, 0 };static const char immhsz16_16[] = { SIZE_W, SIZE_V, SIZE_VV, 0 };static const char immhsz32_16[] = { 0 };static const char immhsz64_16[] = { 0 };static const char immhsz8_32[] = { SIZE_B, SIZE_BV, SIZE_W, SIZE_V, SIZE_VV, 0 };static const char immhsz16_32[] = { SIZE_W, SIZE_V, SIZE_VV, 0 };static const char immhsz32_32[] = { SIZE_V, SIZE_VV, 0 };static const char immhsz64_32[] = { 0 };static const char immhsz8_64[] = { SIZE_B, SIZE_BV, SIZE_W, SIZE_V, SIZE_VV, 0 };static const char immhsz16_64[] = { SIZE_W, SIZE_V, SIZE_VV, 0 };static const char immhsz32_64[] = { SIZE_V, SIZE_VV, 0 };static const char immhsz64_64[] = { SIZE_V, 0 };static const char hsz8_16[] = { SIZE_B, 0 };static const char hsz16_16[] = { SIZE_W, SIZE_V, SIZE_VV, 0 };static const char hsz32_16[] = { SIZE_D, SIZE_P, SIZE_Z, SIZE_R, 0 };static const char hsz48_16[] = { 0 };static const char hsz64_16[] = { SIZE_Q, SIZE_U, SIZE_Z, 0};static const char hsz128_16[] = { SIZE_O, SIZE_U, 0};static const char hsz256_16[] = { SIZE_Y, 0};static const char hsz8_32[] = { SIZE_B, 0 };static const char hsz16_32[] = { SIZE_W, 0 };static const char hsz32_32[] = { SIZE_D, SIZE_V, SIZE_VV, SIZE_R, SIZE_Z, 0 };static const char hsz48_32[] = { SIZE_P, 0 };static const char hsz64_32[] = { SIZE_Q, SIZE_U, SIZE_Z, 0};static const char hsz128_32[] = { SIZE_O, SIZE_U, 0};static const char hsz256_32[] = { SIZE_Y, 0};static const char hsz8_64[] = { SIZE_B, 0 };static const char hsz16_64[] = { SIZE_W, 0 };static const char hsz32_64[] = { SIZE_D, SIZE_Z, 0 };static const char hsz48_64[] = { 0 };static const char hsz64_64[] = { SIZE_Q, SIZE_U, SIZE_V, SIZE_VV, SIZE_R, SIZE_Z, 0};static const char hsz128_64[] = { SIZE_O, SIZE_U, 0};static const char hsz256_64[] = { SIZE_Y, 0};static const int reg2size[4] = {1, 2, 4, 8};static const int addr2size[4] = {-1, 2, 4, 8};/* *	CLASS x86asm */x86asm::x86asm(X86OpSize o, X86AddrSize a): Assembler(false){	opsize = o;	addrsize = a;	if (a != X86_ADDRSIZE64) {		prepInsns();	}}x86opc_insn (*x86asm::x86_32a_insns)[256];void x86asm::prepInsns(){	if (!x86_32a_insns) {		x86_32a_insns = ht_malloc(sizeof *x86_32a_insns);		memcpy(x86_32a_insns, x86_32_insns, sizeof x86_32_insns);			(*x86_32a_insns)[0xc4] = x86_les;		(*x86_32a_insns)[0xc5] = x86_lds;	}	x86_insns = x86_32a_insns;}asm_insn *x86asm::alloc_insn(){	return ht_malloc(sizeof (x86asm_insn));}x86dis *x86asm::createCompatibleDisassembler(){	return new x86dis(opsize, addrsize);}void x86asm::delete_nonsense(CPU_ADDR addr){	x86dis *dis = createCompatibleDisassembler();restart:	asm_code *c=codes;	while (c) {		if (delete_nonsense_insn(c, dis, addr)) goto restart;		c = c->next;	}	delete dis;}static void skip_prefixes(byte **p, int &sizep, int addrsize){	while (sizep > 0) {		if (**p == 0x66 || **p == 0x67 || **p == 0xf2 || **p == 0xf3		|| (addrsize == X86_ADDRSIZE64 && (**p & 0xf0) == 0x40)) {			sizep--; (*p)++;		} else {			break;		}	}}static bool cmp_insn_normal(byte *p, int sizep, byte *q, int sizeq, int addrsize, x86dis *dis, CPU_ADDR addr){	// UGLY: compare disassembly	char s[200];	dis_insn *d = dis->decode(p, sizep, addr);	ht_strlcpy(s, dis->str(d, X86DIS_STYLE_EXPLICIT_MEMSIZE), sizeof s);	d = dis->decode(q, sizeq, addr);	if (strcmp(s, dis->str(d, X86DIS_STYLE_EXPLICIT_MEMSIZE))) return false;	// different disassembly --> not the same			// compare opcodes (w/o prefixes)	skip_prefixes(&p, sizep, addrsize);	skip_prefixes(&q, sizeq, addrsize);	if (sizep != sizeq) return false;	// -> different raw opcodes --> not the same	return memcmp(p, q, sizep) == 0;}bool x86asm::delete_nonsense_insn(asm_code *code, x86dis *dis, CPU_ADDR addr){	asm_code *c = codes;	while (c) {		if (c != code && code->size <= c->size) {			if (cmp_insn_normal(c->data, c->size, code->data, code->size, addrsize, dis, addr)) {				deletecode(c);				return true;			}		}		c = c->next;	}	return false;}void x86asm::emitdisp(uint64 d, int size){	dispsize = size;	disp = d;}void x86asm::emitimm(uint64 i, int size){	immsize = size;	imm = i;}void x86asm::emitfarptr(uint32 s, uint32 o, bool big){	if (big) {		immsize = 6;		imm = o;		imm2 = s;	} else {		immsize = 4;		imm = (s<<16) | (o & 0xffff);	}}void x86asm::emitmodrm(int modrm){	modrmv = modrm;}void x86asm::emitmodrm_mod(int mod){	if (modrmv == -1) modrmv = 0;	modrmv = (modrmv & ~(3<<6)) | ((mod & 3)<<6);}void x86asm::emitmodrm_reg(int reg){	if (modrmv == -1) modrmv = 0;	modrmv = (modrmv & ~(7<<3)) | ((reg & 7)<<3);}void x86asm::emitmodrm_rm(int rm){	if (modrmv == -1) modrmv = 0;	modrmv = (modrmv & ~7) | (rm & 7);}void x86asm::emitsib_base(int base){	if (sibv == -1) sibv = 0;	sibv = (sibv & ~7) | (base & 7);}void x86asm::emitsib_index(int index){	if (sibv == -1) sibv = 0;	sibv = (sibv & ~(7<<3)) | ((index & 7)<<3);}void x86asm::emitsib_scale(int scale){	if (sibv == -1) sibv = 0;	sibv = (sibv & ~(3<<6)) | ((scale & 3)<<6);}#define MATCHOPNAME_NOMATCH		0#define MATCHOPNAME_MATCH		1#define MATCHOPNAME_MATCH_IF_OPSIZE16	2#define MATCHOPNAME_MATCH_IF_OPSIZE32	3#define MATCHOPNAME_MATCH_IF_OPSIZE64	4#define MATCHOPNAME_MATCH_IF_ADDRSIZE16	5#define MATCHOPNAME_MATCH_IF_ADDRSIZE32	6#define MATCHOPNAME_MATCH_IF_ADDRSIZE64	7#define MATCHOPNAME_MATCH_IF_OPPREFIX	8#define MATCHOPNAME_MATCH_IF_NOOPPREFIX	9asm_code *x86asm::encode(asm_insn *asm_insn, int options, CPU_ADDR cur_address){	Assembler::encode(asm_insn, options, cur_address);	x86asm_insn *insn = (x86asm_insn*)asm_insn;			newcode();	namefound = false;	if (addrsize == X86_ADDRSIZE64) {		address = cur_address.flat64.addr;	} else {		address = cur_address.addr32.offset;	}	esizes[0] = 0;	esizes[1] = 0;	esizes[2] = 0;	esizes[3] = 0;	esizes[4] = 0;	ambiguous = false;	match_opcodes(*x86_insns, insn, X86ASM_PREFIX_NO, MATCHOPNAME_MATCH);	if (!namefound && insn->repprefix != X86_PREFIX_NO) {		set_error_msg(X86ASM_ERRMSG_INVALID_PREFIX);	} else {		match_fopcodes(insn);        	match_opcodes(x86_insns_ext, insn, X86ASM_PREFIX_0F, MATCHOPNAME_MATCH_IF_NOOPPREFIX);        	match_opcodes(x86_insns_ext_66, insn, X86ASM_PREFIX_0F, MATCHOPNAME_MATCH_IF_OPPREFIX);        	match_opcodes(x86_insns_ext_f2, insn, X86ASM_PREFIX_F20F, MATCHOPNAME_MATCH_IF_NOOPPREFIX);        	match_opcodes(x86_insns_ext_f3, insn, X86ASM_PREFIX_F30F, MATCHOPNAME_MATCH_IF_NOOPPREFIX);        	match_opcodes(x86_opc_group_insns[0], insn, X86ASM_PREFIX_0F38, MATCHOPNAME_MATCH_IF_NOOPPREFIX);        	match_opcodes(x86_opc_group_insns[1], insn, X86ASM_PREFIX_660F38, MATCHOPNAME_MATCH_IF_OPPREFIX);        	match_opcodes(x86_opc_group_insns[2], insn, X86ASM_PREFIX_F20F38, MATCHOPNAME_MATCH_IF_NOOPPREFIX);        	match_opcodes(x86_opc_group_insns[3], insn, X86ASM_PREFIX_0F3A, MATCHOPNAME_MATCH_IF_NOOPPREFIX);        	match_opcodes(x86_opc_group_insns[4], insn, X86ASM_PREFIX_660F3A, MATCHOPNAME_MATCH_IF_OPPREFIX);        	match_opcodes(x86_opc_group_insns[5], insn, X86ASM_PREFIX_0F7A, MATCHOPNAME_MATCH_IF_NOOPPREFIX);        	match_opcodes(x86_opc_group_insns[6], insn, X86ASM_PREFIX_0F7B, MATCHOPNAME_MATCH_IF_NOOPPREFIX);        	match_opcodes(x86_opc_group_insns[7], insn, X86ASM_PREFIX_0F24, MATCHOPNAME_MATCH_IF_NOOPPREFIX);        	match_opcodes(x86_opc_group_insns[8], insn, X86ASM_PREFIX_0F25, MATCHOPNAME_MATCH_IF_NOOPPREFIX);        	match_vex_opcodes(insn);	}	if (error) {		free_asm_codes();	} else if (!codes) {		if (namefound) {			set_error_msg(X86ASM_ERRMSG_INVALID_OPERANDS);		} else {			set_error_msg(X86ASM_ERRMSG_UNKNOWN_COMMAND, insn->name);		}	} else {		delete_nonsense(cur_address);	}	return codes;}bool x86asm::encode_insn(x86asm_insn *insn, x86opc_insn *opcode, int opcodeb, int additional_opcode, int prefix, int eopsize, int eaddrsize){		rexprefix = 0;	disppos = 0;	bool opsize_depend = false;	for (int i = 0; i < 4; i++) {		switch (x86_op_type[opcode->op[i]].size) {		case SIZE_BV:		case SIZE_V:		case SIZE_VV:		case SIZE_P:			opsize_depend = true;			break;		}	}	code.context = (void*)opsize_depend;		/* test rex thingies */	for (int i=0; i < 4; i++) {		if (insn->op[i].need_rex) {			rexprefix |= 0x40;		}		if (insn->op[i].forbid_rex) {			rexprefix |= 0x80;		}	}	modrmv = -1;	sibv = -1;	drexdest = -1;	drexoc0 = -1;	dispsize = 0;	immsize = 0;	if (additional_opcode != -1) {		if (additional_opcode & 0x800) {			emitmodrm_mod(3);			emitmodrm_reg(additional_opcode & 0x7);			emitmodrm_rm((additional_opcode >> 3) & 0x7);		} else {			emitmodrm_reg(additional_opcode);		}	}	if (addrsize == X86_ADDRSIZE64) {		if (eopsize == X86_ADDRSIZE64) {			if (insn->opsizeprefix == X86_PREFIX_OPSIZE) emitbyte(0x66);			if (!(x86_op_type[opcode->op[0]].info & INFO_DEFAULT_64)) {				// instruction doesn't default to 64 bit opsize				rexprefix |= rexw;			}		} else if (eopsize == X86_ADDRSIZE32) {			if (x86_op_type[opcode->op[0]].info & INFO_DEFAULT_64) {				// instruction defaults to 64 bit opsize				// it's not possible to switch to 32 bit				return false;			}			if (insn->opsizeprefix == X86_PREFIX_OPSIZE) emitbyte(0x66);		} else if (eopsize == X86_ADDRSIZE16) {			if (insn->opsizeprefix == X86_PREFIX_NOOPSIZE) return false;			emitbyte(0x66);		}		if (eaddrsize == X86_ADDRSIZE16) return false;		if (eaddrsize == X86_ADDRSIZE32) emitbyte(0x67);	} else {		if (eopsize != opsize || insn->opsizeprefix == X86_PREFIX_OPSIZE) {			if (insn->opsizeprefix == X86_PREFIX_NOOPSIZE) return false;			emitbyte(0x66);		}		if (eaddrsize != addrsize) emitbyte(0x67);	}		if ((rexprefix & 0xc0) == 0xc0) {		// can't combine insns which simultaneously need REX and forbid REX		clearcode();		return false;	}	/* write lock, rep and/or seg prefixes if needed */	switch (insn->lockprefix) {		case X86_PREFIX_LOCK: emitbyte(0xf0); break;	}	switch (insn->repprefix) {		case X86_PREFIX_REPNZ: emitbyte(0xf2); break;		case X86_PREFIX_REPZ: emitbyte(0xf3); break;	}	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;	}	switch (prefix) {	case X86ASM_PREFIX_F20F:	case X86ASM_PREFIX_F20F38:		emitbyte(0xf2);		break;	case X86ASM_PREFIX_F30F:		emitbyte(0xf3);		break;	}	int rexpos = code.size;	if ((rexprefix & 0x40)	 && prefix != X86ASM_PREFIX_0F24	 && prefix != X86ASM_PREFIX_0F25) {		emitbyte(0xff); // dummy value	}		/* write opcodeprefixes and opcode */	switch (prefix) {	case X86ASM_PREFIX_0F0F:		emitbyte(0x0f);	case X86ASM_PREFIX_F20F:	case X86ASM_PREFIX_F30F:	case X86ASM_PREFIX_0F:		emitbyte(0x0f);	case X86ASM_PREFIX_NO:		break;	case X86ASM_PREFIX_0F38:	case X86ASM_PREFIX_660F38:	case X86ASM_PREFIX_F20F38:		emitbyte(0x0f);		emitbyte(0x38);		break;	case X86ASM_PREFIX_0F3A:	case X86ASM_PREFIX_660F3A:		emitbyte(0x0f);		emitbyte(0x3a);		break;	case X86ASM_PREFIX_0F24:		emitbyte(0x0f);		emitbyte(0x24);		break;	case X86ASM_PREFIX_0F25:		emitbyte(0x0f);		emitbyte(0x25);		break;	case X86ASM_PREFIX_0F7A:		emitbyte(0x0f);		emitbyte(0x7a);

⌨️ 快捷键说明

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