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

📄 x86asm.cc

📁 功能较全面的反汇编器:反汇编器ht-2.0.15.tar.gz
💻 CC
📖 第 1 页 / 共 4 页
字号:
						for (int l=0; l < 2; l++) {							if (match_allops(insn, group[k].op, 4, opsize, eaddrsize)) {								if (encode_insn(insn, &group[k], 0xc0 | j<<3 | k, -1, X86ASM_PREFIX_D8+i, opsize, eaddrsize)) {									pushcode();									newcode();								}							}							switch (eaddrsize) {							case X86_ADDRSIZE64:							case X86_ADDRSIZE16: eaddrsize = X86_ADDRSIZE32; break;							case X86_ADDRSIZE32: eaddrsize = X86_ADDRSIZE16; break;							}						}					}				}			}		}	}}bool x86asm::opreg(x86_insn_op *op, const char *xop){	for (int i=0; i<3; i++) {		for (int j=0; j<8; j++) {			if (x86_regs[i][j] && strcmp(xop, x86_regs[i][j])==0) {				op->type = X86_OPTYPE_REG;				op->size = reg2size[i];				op->reg = j;				return true;			}		}	}	return false;}bool x86asm::opmmx(x86_insn_op *op, const char *xop){	if (strlen(xop) == 3 && xop[0] == 'm' && xop[1] == 'm'	 && xop[2] >= '0' && xop[2] <= '7') {		op->type = X86_OPTYPE_MMX;		op->size = 8;		op->mmx = xop[2] - '0';		return true;	} else {		return false;	}}bool x86asm::opxmm(x86_insn_op *op, const char *xop){	if (strlen(xop) == 4 && xop[0] == 'x' && xop[1] == 'm' && xop[2] == 'm'	 && xop[3] >= '0' && xop[3] <= '7') {		op->type = X86_OPTYPE_XMM;		op->size = 16;		op->xmm = xop[3] - '0';		return true;	} else {		return false;	}}bool x86asm::opymm(x86_insn_op *op, const char *xop){	if (strlen(xop) == 4 && xop[0] == 'y' && xop[1] == 'm' && xop[2] == 'm'	 && xop[3] >= '0' && xop[3] <= '7') {		op->type = X86_OPTYPE_YMM;		op->size = 32;		op->xmm = xop[3] - '0';		return true;	} else {		return false;	}}bool x86asm::opseg(x86_insn_op *op, const char *xop){	for (int i=0; i<8; i++) {		if (x86_segs[i] && strcmp(xop, x86_segs[i])==0) {			op->type = X86_OPTYPE_SEG;			op->size = 2;			op->seg = i;			return true;		}	}	return false;}bool x86asm::opfarptr(x86_insn_op *op, const char *xop){	return false;/*FIXME:	uint64 seg, offset;	char *x = xop;		if (!fetch_number(&x, &seg)) return false;	if (*x != ':') return false;	x++;	if (!fetch_number(&x, &offset)) return false;	if (*x) return false;	op->type = X86_OPTYPE_FARPTR;	if (offset > 0xffff) op->size=6; else op->size=4;	op->farptr.seg = seg;	op->farptr.offset = offset;	return true;*/}bool x86asm::opimm(x86_insn_op *op, const char *xop){	uint64 i;	if (!str2int(xop, i)) return false;	op->type = X86_OPTYPE_IMM;	if (i > 0xffffffffULL) {		op->size = 8; 	} else if (i > 0xffff) {		op->size = 4; 	} else if (i > 0xff) {		op->size = 2; 	} else {		op->size = 1;	}	op->imm = i;	return true;}bool x86asm::opplugimm(x86_insn_op *op, const char *xop){	uint64 d;	if (imm_eval_proc && imm_eval_proc(imm_eval_context, xop, d)) {		op->type = X86_OPTYPE_IMM;		if (d > 0xffffffff) {			op->size = 8; 		} else if (d > 0xffff) {			op->size = 4; 		} else if (d > 0xff) {			op->size = 2; 		} else {			op->size = 1;		}		op->imm = d;		return true;	}	return false;}bool x86asm::opmem(x86asm_insn *asm_insn, x86_insn_op *op, const char *s){	/* FIXME: dirty implementation! */	int opsize = 0, hsize = 0;	bool floatptr = false;	char token[256];	const char *sep = "[]()*+-:";	tok(&s, token, sizeof token, sep);		static const char *types[] = {"byte", "word", "dword", "pword", "qword", "oword", "ymmword", "single", "double", "extended"};	static byte type_size[] = {1, 2, 4, 6, 8, 16, 32, 4, 8, 10};	// typecast	for (uint i=0; i < sizeof types / sizeof types[0]; i++) {		if (strcmp(token, types[i]) == 0) {			hsize = type_size[i];			if (i >= 6) floatptr = true;			break;		}	}	if (hsize) {		tok(&s, token, sizeof token, sep);				if (!(strcmp(token, "ptr") == 0)) return false;		opsize = hsize;		tok(&s, token, sizeof token, sep);	}	// segprefixes (e.g. fs:)	for (int i = 0; i < 8; i++) {		if (x86_segs[i]) {			if (strcmp(x86_segs[i], token)==0) {				tok(&s, token, sizeof token, sep);								if (!(strcmp(token, ":") == 0)) return false;				static const int c2p[8] = {X86_PREFIX_ES, X86_PREFIX_CS, X86_PREFIX_SS, X86_PREFIX_DS, X86_PREFIX_FS, X86_PREFIX_GS, 0, 0};				asm_insn->segprefix = c2p[i];				tok(&s, token, sizeof token, sep);								break;			}		}	}	if (!(strcmp(token, "[") == 0)) return false;	int scale = 0, index = X86_REG_NO, base = X86_REG_NO;	uint64 disp = 0;	int addrsize = X86_ADDRSIZEUNKNOWN;	int lasttokenreg = X86_REG_NO;	bool need_rex = false;	int sign = 1;	sep = "[]()*+-";	while (1) {cont:		tok(&s, token, sizeof token, sep);		if (strcmp(token, "+") == 0) {			if (!sign) sign = 1;			continue;		}		if (strcmp(token, "-") == 0) {			if (sign) {				sign = -sign;			} else {				sign = -1;			}			continue;		}		if (strcmp(token, "]") == 0) {			if (sign) return false;			break;		}		if (strcmp(token, "*") == 0) {			tok(&s, token, sizeof token, sep);			if (lasttokenreg == X86_REG_NO) {				/* FIXME: case "imm*reg" not yet supported! 				cleaner implementation needed! */				return false;			} else {				uint64 v;				if (!str2int(token, v)) return false;				if (v > 1) {					if (index == lasttokenreg) {						scale += v-1;					} else if (base == lasttokenreg) {						if (index != X86_REG_NO) return false;						index = base;						base = X86_REG_NO;						scale = v;					}				}			}			lasttokenreg = X86_REG_NO;			sign = 0;			continue;		}		/* test if reg */		for (int i=1; i < 4; i++) {			for (int j=0; j < 16; j++) {				if (x86_64regs[i][j] && strcmp(token, x86_64regs[i][j])==0) {					if (j > 7 || i == 3) {						if (this->addrsize != X86_ADDRSIZE64) break;						if (j > 7) need_rex = true;					}					if (sign < 0) return false;					static const byte sizer[] = {X86_ADDRSIZE16, X86_ADDRSIZE32, X86_ADDRSIZE64};					int caddrsize = sizer[i-1];					if (addrsize == X86_ADDRSIZEUNKNOWN) {						addrsize = caddrsize;					} else if (addrsize != caddrsize) {						return false;					}					if (index == j) {						scale++;					} else if (base == X86_REG_NO) {						base = j;					} else if (index == X86_REG_NO) {						index = j;						scale = 1;					} else if (base == j && scale == 1) {						int t = index;						index = base;						base = t;						scale = 2;					} else return false;					lasttokenreg = j;					sign = 0;					goto cont;				}			}		}		lasttokenreg = X86_REG_NO;		/* test if number */		uint64 v;		if ((imm_eval_proc && imm_eval_proc(imm_eval_context, token, v))		 || str2int(token, v)) {			if (!sign) return false;			if (sign < 0) disp -= v; else disp += v;			sign = 0;			continue;		}		return false;	}	op->type = X86_OPTYPE_MEM;	op->size = opsize;	op->mem.base = base;	op->mem.index = index;	op->mem.scale = scale;	op->mem.addrsize = addrsize;	op->mem.disp = disp;	op->mem.floatptr = floatptr;	op->need_rex = need_rex;	return true;}bool x86asm::opspecialregs(x86_insn_op *op, const char *xop){	char *e;	if (strcmp(xop, "st")==0) {		op->type=X86_OPTYPE_STX;		op->size=10;		op->stx=0;		return true;	} else if (ht_strncmp(xop, "st", 2)==0 && xop[2]=='(' && xop[4]==')') {		int w = strtol(xop+3, &e, 10);		if (e != xop+4 || w > 7) return false;		op->type = X86_OPTYPE_STX;		op->size = 10;		op->stx = w;		return 1;	}	/* FIXME: do we need this? 	 * strtol sets e to next untranslatable char, 	 * this case is caught below... 	 */	if (strlen(xop) != 3) return 0;	int w = strtol(xop+2, &e, 10);	if (*e || w > 7) return 0;	if (ht_strncmp(xop, "cr", 2) == 0) {		op->type = X86_OPTYPE_CRX;		op->size = 4;		op->crx = w;		return true;	} else if (ht_strncmp(xop, "dr", 2) == 0) {		op->type = X86_OPTYPE_DRX;		op->size = 4;		op->drx = w;		return true;	}	return false;}bool x86asm::translate_str(asm_insn *asm_insn, const char *s){	x86asm_insn *insn=(x86asm_insn*)asm_insn;	char *opp[5], op[5][256];	opp[0]=op[0];	opp[1]=op[1];	opp[2]=op[2];	opp[3]=op[3];	opp[4]=op[4];	for (int i=0; i<5; i++) {		insn->op[i].need_rex = insn->op[i].forbid_rex = false;		insn->op[i].type = X86_OPTYPE_EMPTY;	}	insn->lockprefix = X86_PREFIX_NO;	insn->repprefix = X86_PREFIX_NO;	insn->segprefix = X86_PREFIX_NO;	insn->opsizeprefix = X86_PREFIX_NO;	const char *p = s, *a, *b;	/* prefixes */	whitespaces(p);	a=p;	non_whitespaces(p);	b=p;	if (ht_strncmp(a, "rep", b-a) == 0 || ht_strncmp(a, "repe", b-a) == 0	 || ht_strncmp(a, "repz", b-a) == 0) {		insn->repprefix=X86_PREFIX_REPZ;		s = p;	} else if (ht_strncmp(a, "repne", b-a) == 0 || ht_strncmp(a, "repnz", b-a) == 0) {		insn->repprefix=X86_PREFIX_REPNZ;		s = p;	} else if (ht_strncmp(a, "lock", b-a) == 0) {		insn->lockprefix=X86_PREFIX_LOCK;		s = p;	}	/**/	splitstr(s, insn->n, sizeof insn->n, (char**)&opp, 256);	insn->name=insn->n;	for (int i=0; i<5; i++) {		if (!*op[i]) break;		if (!(opplugimm(&insn->op[i], op[i])		 || opreg(&insn->op[i], op[i])		 || opmmx(&insn->op[i], op[i])		 || opxmm(&insn->op[i], op[i])		 || opymm(&insn->op[i], op[i])		 || opfarptr(&insn->op[i], op[i])		 || opimm(&insn->op[i], op[i])		 || opseg(&insn->op[i], op[i])		 || opmem(insn, &insn->op[i], op[i])		 || opspecialregs(&insn->op[i], op[i]))) {			set_error_msg(X86ASM_ERRMSG_UNKNOWN_SYMBOL, op[i]);			return false;		}	}	return true;}int x86asm::simmsize(uint64 imm, int immsize){	switch (immsize) {	case 1:		if (imm <= 0xff) return 1;		break;	case 2:		if (imm <= 0xffff) imm = sint64(sint16(imm));		break;	case 4:		if (imm <= 0xffffffff) imm = sint64(sint32(imm));		break;	}	if (imm >= 0xffffffffffffff80ULL || imm < 0x80) return 1;	if (imm >= 0xffffffffffff8000ULL || imm < 0x8000) return 2;	if (imm >= 0xffffffff80000000ULL || imm < 0x80000000) return 4;	return 8;}void x86asm::splitstr(const char *s, char *name, int size, char *op[5], int opsize){	const char *a, *b;	bool wantbreak = false;	*name=0;	*op[0]=0;	*op[1]=0;	*op[2]=0;	*op[3]=0;	*op[4]=0;	/* find name */	whitespaces(s);	a = s;	non_whitespaces(s);	b = s;	ht_strlcpy(name, a, MIN(b-a+1, size));	/* find ops */	for (int i = 0; i < 5; i++) {		whitespaces(s);		if (!*s) break;		a = s;		waitforchar(s, ',');		while (is_whitespace(s[-1])) s--;		if (!*s) wantbreak = true;		b = s;		whitespaces(s);		if (!*s) wantbreak = true;		ht_strlcpy(op[i], a, MIN(b-a+1, opsize));		whitespaces(s);		if (wantbreak || *s != ',') break;		s++;	}}void x86asm::tok(const char **s, char *res, int reslen, const char *sep){	if (reslen <= 0) return;	whitespaces(*s);	if (strchr(sep, **s)) {		if (reslen > 0) *res++ = *((*s)++);	} else {		while (reslen > 1) {			*res++ = *((*s)++);			reslen--;			if (**s == ' ' || **s == '\t') break;			if (strchr(sep, **s)) break;		}	}	*res = 0;}/************************************************************************ * */x86opc_insn (*x86_64asm::x86_64_insns)[256];x86_64asm::x86_64asm()	: x86asm(X86_OPSIZE32, X86_ADDRSIZE64){	prepInsns();}void x86_64asm::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;}x86dis *x86_64asm::createCompatibleDisassembler(){	return new x86_64dis();}bool x86_64asm::opreg(x86_insn_op *op, const char *xop){	for (int i=0; i < 4; i++) {		for (int j=0; j < 16; j++) {			if (x86_64regs[i][j] && strcmp(xop, x86_64regs[i][j])==0) {				op->type = X86_OPTYPE_REG;				op->size = reg2size[i];				op->reg = j;				if (j > 7 || (i == 0 && j > 3)) {					op->need_rex = true;				}				return true;			}		}	}	// check for legacy ah, ch, dh, bh	for (int j=4; j < 8; j++) {		if (x86_regs[0][j] && strcmp(xop, x86_regs[0][j])==0) {			op->type = X86_OPTYPE_REG;			op->size = reg2size[0];			op->reg = j;			op->forbid_rex = true;			return true;		}	}	return false;}bool x86_64asm::opxmm(x86_insn_op *op, const char *xop){	int slen = strlen(xop);	if ((slen == 4 || slen == 5) && xop[0] == 'x' && xop[1] == 'm' && xop[2] == 'm'	 && xop[3] >= '0' && xop[3] <= '9') {		int x = xop[3] - '0';		if (slen == 5) {			if (xop[4] < '0' || xop[4] > '9') return false;			x *= 10;			x += xop[4] - '0';			if (x > 15) return false;		}		op->type = X86_OPTYPE_XMM;		op->size = 16;		op->xmm = x;		if (x > 7) op->need_rex = true;		return true;	} else {		return false;	}}bool x86_64asm::opymm(x86_insn_op *op, const char *xop){	int slen = strlen(xop);	if ((slen == 4 || slen == 5) && xop[0] == 'y' && xop[1] == 'm' && xop[2] == 'm'	 && xop[3] >= '0' && xop[3] <= '9') {		int x = xop[3] - '0';		if (slen == 5) {			if (xop[4] < '0' || xop[4] > '9') return false;			x *= 10;			x += xop[4] - '0';			if (x > 15) return false;		}		op->type = X86_OPTYPE_YMM;		op->size = 32;		op->xmm = x;		if (x > 7) op->need_rex = true;		return true;	} else {		return false;	}}

⌨️ 快捷键说明

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