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

📄 analy.cc

📁 功能较全面的反汇编器:反汇编器ht-2.0.15.tar.gz
💻 CC
📖 第 1 页 / 共 3 页
字号:
	}	com->appendPreComment(c);	DPRINTF("#(%y) comment `%s'\n", Addr, c);}/* * addlabel: create label if there isnt one *           fail if label exist on another address * */bool Analyser::addSymbol(Address *Addr, const char *label, labeltype type, Location *infunc){	if (!validAddress(Addr, scvalid)) return false;	Location *a = newLocation(Addr);	if (!a->label) {		Symbol *l = newSymbol(label, a, type, infunc);		if (l->location->addr->compareTo(Addr) != 0) {			// this label already exists at a different address			return false;		}		a->label = l;		if (a->type.type == dt_unknown || a->type.type == dt_unknown_data) {			if (type == label_func && !validCodeAddress(Addr)) {				type = label_unknown;			}			switch (type) {				case label_unknown:					break;				case label_func:					data->setCodeAddressType(a, dst_function);					break;				case label_loc:					data->setCodeAddressType(a, dst_location);					break;				case label_data:					data->setAddressType(a, dt_unknown_data, 0, 0);					break;			}		}		return true;	} else {		// adress already has a label		return false;	}}/* * */bool Analyser::addXRef(Address *from, Address *to, xref_enum_t action){	if (!validAddress(from, scvalid) || !validAddress(to, scvalid)) return false;	Location *a = newLocation(from);	Container *x = a->xrefs;	if (x) {		AddrXRef tmp(to);		if (x->find(&tmp)) return false;	} else {		x = new AVLTree(true);		a->xrefs = x;	}	x->insert(new AddrXRef(to, action));		DPRINTF("xref %y->%y\n", from, to);	return true;}/* * */void	Analyser::assignComment(Address *Addr, int line, const char *c){	/* not really implemented */	addComment(Addr, line, c);}/* * */bool Analyser::assignSymbol(Address *Addr, const char *label, labeltype type, Location *infunc){	if (!validAddress(Addr, scvalid)) return false;	Location *a = newLocation(Addr);	Symbol *l = newSymbol(label, a, type, infunc);	if (l->location->addr->compareTo(Addr) != 0) {		// label already exists at a different address		return false;	}	if (l->location->type.type == dt_unknown) {		if (type == label_func && !validCodeAddress(Addr)) {			type = label_unknown;		}		switch (type) {			case label_unknown:				break;			case label_func:				data->setCodeAddressType(a, dst_function);				break;			case label_loc:				data->setCodeAddressType(a, dst_location);				break;			case label_data:				data->setAddressType(a, dt_unknown_data, 0, 0);				break;		}	}		if (a->label) {		// overwrite		if (a->label != l) {			// label has to be renamed			disableSymbol(a->label);			a->label = l;		}	} else {		a->label = l;	}	return true;}/* * */void Analyser::assignXRef(Address *from, Address *to, xref_enum_t action){	if (!validAddress(from, scvalid) || !validAddress(to, scvalid)) return;	Location	*a = newLocation(from);	Container	*x = a->xrefs;	if (x) {		AddrXRef *xref;		AddrXRef tmp(to);		if ((xref = (AddrXRef*)x->get(x->find(&tmp)))) {			// update xref			xref->type = action;			DPRINTF("xref %y->%y updated\n", from, to);			return;		}	} else {		x = new AVLTree(true);		a->xrefs = x;	}	x->insert(new AddrXRef(to, action));		DPRINTF("xref %y->%y\n", from, to);}/* * */void	Analyser::beginAnalysis(){	if (queryConfig(Q_DO_ANALYSIS)) {		DPRINTF("################################\nAnalysis started.\n");		if (analy_disasm && disasm) {			ops_parsed = 0;			if (gotoAddress(invalid_addr, invalid_addr)) setActive(true);		} else {			DPRINTF("Analysis can't be started. No disassembler available.");		}	}}/* * */bool	Analyser::continueAnalysis(){	byte			buf[32];	OPCODE		*instr;	int			len;	branch_enum_t	branch;	assert((uint)max_opcode_length <= sizeof buf);	if (!active) return	false;	do {			int diff;//		char tbuf[100];//		char tbuf2[100];//		addr->stringify(tbuf, 100, 0);/*		if (strcmp(tbuf, "200970ec") == 0) {			int as=0;		}*///		printf("*** %s ***\n", tbuf);		if ((addr->difference(diff, next_explored) && (diff >= 0)) || !validCodeAddress(addr)) {			if (!gotoAddress(addr, invalid_addr)) {				finish();				return false;			}               		}		int bz = bufPtr(addr, buf, max_opcode_length);		instr = disasm->decode(buf, bz, mapAddr(addr));		instr = disasm->duplicateInsn(instr);				ops_parsed++;		num_ops_parsed++;		len = disasm->getSize(instr);		last_explored->add(len);		do {			DPRINTF("opcode @%y [func: %y]: %s\n", addr, (cur_func) ? cur_func->addr : invalid_addr, disasm->str(instr, 0));			if (disasm->validInsn(instr)) {				branch = analy_disasm->isBranch(instr);				if (branch != br_nobranch) {					doBranch(branch, instr, len);				} else {					analy_disasm->examineOpcode(instr);				}			} else {				DPRINTF("invalid opcode @%y\n", addr);//				log("invalid opcode at address %y\n", addr);				if (!addr->add(len)) {					delete addr;					addr = new InvalidAddress();				} else {					newLocation(addr)->flags |= AF_FUNCTION_END;					next_address_is_invalid = true;				}			}		} while (disasm->selectNext(instr));		if (next_address_is_invalid || !addr->add(len)) {			gotoAddress(invalid_addr, invalid_addr);			next_address_is_invalid = false;		}		free(instr);	} while ((ops_parsed % MAX_OPS_PER_CONTINUE) !=0);	return true;}/* * */void Analyser::continueAnalysisAt(Address *Addr){	if (!validAddress(Addr, sccode)) return;	if (queryConfig(Q_DO_ANALYSIS)) {		DPRINTF("continueing analysis at %y\n", Addr);		if (active || disasm) {			data->setCodeAddressType(Addr, dst_function);			pushAddress(Addr, Addr);               		}		if (!active) {			if (disasm) {				Analyser::beginAnalysis();			} else {				DPRINTF("couldn't start analysis: no disasm available\n");			}		}	}}/* *	should return a new instance of an apropriate assembler */Assembler *Analyser::createAssembler(){	return NULL;}/* * */void	Analyser::dataAccess(Address *Addr, taccess access){	if (!validAddress(Addr, scvalid)) {		char	msg[100];		global_analyser_address_string_format = ADDRESS_STRING_FORMAT_LEADING_ZEROS;		ht_snprintf(msg, sizeof msg, "access of invalid addr %y at addr %y", Addr, addr);		log(msg);		return;	}	DPRINTF("dataaccess of %y\n", Addr);	// string test	byte buffer[1024];	if (validAddress(Addr, scinitialized)) {		uint bz = bufPtr(Addr, buffer, sizeof buffer);		if (bz > 2) {			analy_string *str = string_test(buffer, bz);			if (str) {				char string1[128], string2[128];				str->render_string(string2, sizeof string2);				ht_snprintf(string1, sizeof string1, "%s_%s", str->name(), string2);				make_valid_name(string2, string1);				if (addAddressSymbol(Addr, string2, label_data)) {					addComment(Addr, 0, "");				}				data->setArrayAddressType(Addr, dst_string, str->length());				str->done();				delete str;				return;			}		}	}	if (validCodeAddress(Addr) && access.type == acoffset) {		if (addAddressSymbol(Addr, LPRFX_OFS, label_func)) {			addComment(Addr, 0, "");		}		Location *a = getLocationByAddress(Addr);		assert(a);		// test if Addr points to code		if ((a->type.type == dt_unknown) || (a->type.type == dt_code)) {			// test if Addr points to valid code (test not yet complete)			byte buf[16];			int bz = bufPtr(Addr, buf, sizeof(buf));			OPCODE *instr = disasm->decode(buf, MIN(bz, max_opcode_length), mapAddr(Addr));			if (disasm->validInsn(instr)) {				data->setCodeAddressType(Addr, dst_cunknown);				pushAddress(Addr, Addr);			}		}	} else {		if (access.type != acoffset) {			switch (access.size) {				case 1: data->setIntAddressType(Addr, dst_ibyte, 1); break;				case 2: data->setIntAddressType(Addr, dst_iword, 2); break;				case 4: data->setIntAddressType(Addr, dst_idword, 4); break;			}		}		if (validAddress(Addr, scinitialized)) {			addAddressSymbol(Addr, LPRFX_DTA, label_data);		} else {			addAddressSymbol(Addr, LPRFX_DTU, label_data);		}	}}/* *	disables address, frees misc */void	Analyser::deleteLocation(Address *Addr){	Location *a = getLocationByAddress(Addr);	if (a) {		disableSymbol(a->label);		a->label = NULL;		a->flags |= AF_DELETED;		location_count--;	}}/* *	disables label of an address and unassigns address' label */void Analyser::deleteSymbol(Address *Addr){	Location *a = getLocationByAddress(Addr);	if (a) {		disableSymbol(a->label);		a->label = NULL;		symbol_count--;	}}/* * */bool Analyser::deleteXRef(Address *from, Address *to){	if (!validAddress(from, scvalid) || !validAddress(to, scvalid)) return false;	Location *a = getLocationByAddress(from);	if (!a) return false;	Container *x = a->xrefs;	if (!x) return false;	DPRINTF("deleted xref %y->%y\n", from, to);		AddrXRef tmp(to);	return x->delObj(&tmp);}/* *	an disabled label will be overwritten as soon as possible, *   and never be returned nor saved. *	performed this way to preserve the labeltrees structure * */void	Analyser::disableSymbol(Symbol *label){	if (label) {		label->location = NULL;	}}/* * */void	Analyser::doBranch(branch_enum_t branch, OPCODE *opcode, int len){	Address *branch_addr = analy_disasm->branchAddr(opcode, branch, true);	if (branch != br_return) {		if (!validCodeAddress(branch_addr)) {			char	msg[100];			global_analyser_address_string_format = ADDRESS_STRING_FORMAT_LEADING_ZEROS;			ht_snprintf(msg, sizeof msg, "branch to invalid addr %y from addr %y", branch_addr, addr);			log(msg);		}	}/*	if (branch != brcall) {		taddr *a = new_addr(addr+len);		if (!a->comments) {			add_comment(a->addr, 0, "");		}	}*/	Address *next_addr = addr->clone();	if (!next_addr->add(len)) {		delete next_addr;		next_addr = new InvalidAddress();	}	switch (branch) {		case	br_jump:			if (next_addr->isValid())				newLocation(next_addr)->flags |= AF_FUNCTION_END;			addXRef(branch_addr, addr, xrefjump);			if (addAddressSymbol(branch_addr, LPRFX_LOC, label_loc, cur_func)) {				addComment(branch_addr, 0, "");			}//			gotoAddress(branch_addr, invalid_addr);			pushAddress(branch_addr, invalid_addr);			next_address_is_invalid = true;			break;		case	br_return:			if (next_addr->isValid())				newLocation(next_addr)->flags |= AF_FUNCTION_END;			next_address_is_invalid = true;			break;		case	br_call: {			addXRef(branch_addr, addr, xrefcall);			bool special_func = false;			const char *lprfx = LPRFX_SUB;			if (!getSymbolByAddress(branch_addr) && validCodeAddress(branch_addr)) {				// should be in code_analy				byte buf[16];				int bz = bufPtr(branch_addr, buf, sizeof(buf));				OPCODE *instr = disasm->decode(buf, MIN(bz, max_opcode_length), mapAddr(branch_addr));				branch_enum_t bt = analy_disasm->isBranch(instr);								if (bt == br_return) {					lprfx = LPRFX_STUB;				} else if (bt == br_jump) {					char buf[1024], label[1024];					Address *wrap_addr = analy_disasm->branchAddr(instr, bt, false);					if (validAddress(wrap_addr, scvalid)) {						Symbol *l = getSymbolByAddress(wrap_addr);						addComment(branch_addr, 0, "");						addComment(branch_addr, 0, ";----------------------------------------------");						global_analyser_address_string_format = ADDRESS_STRING_FORMAT_COMPACT;						if (l && l->name) {							ht_snprintf(buf, sizeof buf, "%s %s", ";  W R A P P E R for", l->name);							ht_snprintf(label, sizeof label, "%s_%s_%y", LPRFX_WRAP, l->name, branch_addr);						} else {							ht_snprintf(buf, sizeof buf, "%s %s %y", ";  W R A P P E R for", "address", wrap_addr);							ht_snprintf(label, sizeof label, "%s_%y_%y", LPRFX_WRAP, wrap_addr, branch_addr);						}						addComment(branch_addr, 0, buf);						addComment(branch_addr, 0, ";----------------------------------------------");						addSymbol(branch_addr, label, label_func);						special_func = true;					}					delete wrap_addr;				}			}			if (!special_func && addAddressSymbol(branch_addr, lprfx, label_func)) {				addComment(branch_addr, 0, "");				addComment(branch_addr, 0, ";-----------------------");				addComment(branch_addr, 0, ";  S U B R O U T I N E");				addComment(branch_addr, 0, ";-----------------------");				if (branch_addr->compareTo(cur_func->addr) == 0) {					addComment(branch_addr, 0, ";  (recursive)");				}			}//			pushAddress(next_addr, cur_func->addr);//			gotoAddress(branch_addr, branch_addr);			pushAddress(branch_addr, branch_addr);			break;		}		case	br_jXX:			addXRef(branch_addr, addr, xrefjump);			if (addAddressSymbol(branch_addr, LPRFX_LOC, label_loc, cur_func)) {				addComment(branch_addr, 0, "");			}//			pushAddress(next_addr, cur_func->addr);//			gotoAddress(branch_addr, invalid_addr);			pushAddress(branch_addr, invalid_addr);			break;		default:{}			// stupid but neccessary	}	delete next_addr;	delete branch_addr;}/* * */void	Analyser::engageCodeanalyser(){	if (queryConfig(Q_ENGAGE_CODE_ANALYSER)) {		DPRINTF("starting code analyser.\n");	}}static void analyserenum_addrs(Location *locs, Address *at, Location *&loc){	if ((at->compareTo(locs->addr) < 0) || !at->isValid()) {		loc = locs;		if (locs->left) analyserenum_addrs(locs->left, at, loc);	} else /*if (at >= locs->addr)*/ {		if (locs->right) analyserenum_addrs(locs->right, at, loc);	}}/* * */Location *Analyser::enumLocations(Address *Addr){	Location *result = NULL;	if (locations) analyserenum_addrs(locations, Addr, result);	while (result && (result->flags & AF_DELETED)) {		Address *a = result->addr;		result = NULL;		analyserenum_addrs(locations, a, result);	}	return result;}static void analyserenum_addrs_back(Location *locs, Address *at, Location *&loc){	if (at->compareTo(locs->addr) <= 0) {		if (locs->left) analyserenum_addrs_back(locs->left, at, loc);	} else /*if (at > locs->addr)*/ {		loc = locs;		if (locs->right) analyserenum_addrs_back(locs->right, at, loc);	}}/* * */Location *Analyser::enumLocationsReverse(Address *Addr){	Location *result = NULL;	if (locations) analyserenum_addrs_back(locations, Addr, result);	while ((result) && (result->flags & AF_DELETED)) {		Address *a = result->addr;		result = NULL;		analyserenum_addrs_back(locations, a, result);	}	return result;}static void analyserenum_labels(Symbol *labels, const char *at, Symbol *&label){	int i = strcmp(at, labels->name);	if (i < 0) {		label = labels;		if (labels->left) analyserenum_labels(labels->left, at, label);	} else /*if (i >= 0)*/ {		if (labels->right) analyserenum_labels(labels->right, at, label);	}}/* *   returns the (alphanumerically) next label to "at" *	or the first if "at" is NULL *	returns NULL if there is no preceding label * */Symbol *Analyser::enumSymbolsByName(const char *at){	Symbol *result = NULL;	if (!at) at="";	if (symbols) analyserenum_labels(symbols, at, result);	// label with !addr mustnt be returned	while ((result) && (!result->location)) {		char *name = result->name;		result = NULL;		analyserenum_labels(symbols, name, result);	}	return result;}static void analyserenum_labels_back(Symbol *labels, const char *at, Symbol *&label){	int i = strcmp(at, labels->name);	if (i <= 0) {		if (labels->left) analyserenum_labels_back(labels->left, at, label);	} else /*if (i >= 0)*/ {		label = labels;		if (labels->right) analyserenum_labels_back(labels->right, at, label);	}}/* * */Symbol *Analyser::enumSymbolsByNameReverse(const char *at){	Symbol *result = NULL;	// FIXME:	if (!at) at="\xff\xff\xff";	if (symbols) analyserenum_labels_back(symbols, at, result);	// labels with !addr mustnt be returned	while ((result) && (!result->location)) {		char *name = result->name;		result = NULL;		analyserenum_labels_back(symbols, name, result);	}	return result;}Symbol *Analyser::enumSymbols(Symbol *sym){	if (sym) {		return enumSymbolsByName(sym->name);	} else {		return enumSymbolsByName(NULL);	}}Symbol *Analyser::enumSymbolsReverse(Symbol *sym){	if (sym) {		return enumSymbolsByNameReverse(sym->name);	} else {		return enumSymbolsByNameReverse(NULL);	}}/* * */taddr_typetype Analyser::examineData(Address *Addr){	if ((validReadAddress(Addr)) && (validAddress(Addr, scinitialized))) {		DPRINTF("examinating data @%y:\n", Addr);	} else return dt_unknown;	return dt_unknown;}/* * */static Location *analyserfindaddr(Location *locs, Address *Addr){	if (locs) {		if (Addr->compareTo(locs->addr) < 0) return analyserfindaddr(locs->left, Addr);		if (Addr->compareTo(locs->addr) > 0) return analyserfindaddr(locs->right, Addr);		return (locs->flags & AF_DELETED) ? NULL : locs;	}	return NULL;}/* * */Location *Analyser::getLocationByAddress(Address *Addr){	return analyserfindaddr(locations, Addr);}/* *   finds the address Addr belongs to (if address has size > 1) */Location *Analyser::getLocationContextByAddress(Address *Addr){	Location *res = enumLocationsReverse(Addr);	if (res && res->type.type != dt_unknown) {		Address *resaddr = res->addr->clone();		resaddr->add(res->type.length);		if (resaddr->compareTo(Addr) > 0) {			delete resaddr;			return res;		}		delete resaddr;	}	return NULL;}/* *	finds the function the Addr belongs to (if possible/applicable). */Location *Analyser::getFunctionByAddress(Address *Addr){	Location *loc = getLocationByAddress(Addr);	if (!loc) loc = enumLocationsReverse(Addr);	while (loc && !(loc->flags & AF_FUNCTION_SET)) {		if (loc->flags & AF_FUNCTION_END) return NULL;		loc = enumLocationsReverse(loc->addr);	}	return loc ? loc->thisfunc : NULL;}/* *	searches back to the last location */Location *Analyser::getPreviousSymbolByAddress(Address *Addr){	Location *loc = getLocationByAddress(Addr);	if (!loc) loc = enumLocationsReverse(Addr);	while (loc && !loc->label) {		if (loc->flags & AF_FUNCTION_END) return NULL;		loc = enumLocationsReverse(loc->addr);	}	return loc ? loc : NULL;

⌨️ 快捷键说明

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