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

📄 analy.cc

📁 功能较全面的反汇编器:反汇编器ht-2.0.15.tar.gz
💻 CC
📖 第 1 页 / 共 3 页
字号:
/* *	HT Editor *	analy.cc * *	Copyright (C) 1999-2002 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 <string.h>#include <stdlib.h>#include <stdio.h>#include "analy.h"#include "analy_names.h"#include "analy_register.h"#include "code_analy.h"#include "data_analy.h"#include "io/types.h"#include "atom.h"#include "except.h"#include "htctrl.h"#include "htdebug.h"#include "strtools.h"#include "language.h"#include "snprintf.h"#include "tools.h"#define DPRINTF(msg...)//#undef DPRINTF//#define DPRINTF(msg...) {global_analyser_address_string_format = ADDRESS_STRING_FORMAT_LEADING_ZEROS;char buf[1024]; ht_snprintf(buf, sizeof buf, ##msg); fprintf(stdout, buf);}int global_analyser_address_string_format = ADDRESS_STRING_FORMAT_COMPACT;int Address::compareDelinear(Address *obj){	return compareTo(obj);}bool Address::isValid(){	return true;}int Address::toString(char *s, int maxlen) const{	return stringify(s, maxlen, global_analyser_address_string_format);}bool InvalidAddress::add(int offset){	return false;}int InvalidAddress::byteSize(){	return 0;}int InvalidAddress::compareTo(const Object *obj) const{	return 0;}void InvalidAddress::putIntoCPUAddress(CPU_ADDR *ca) const{}bool InvalidAddress::difference(int &result, Address *to){	return false;}InvalidAddress *InvalidAddress::clone() const{	return new InvalidAddress(*this);}void InvalidAddress::getFromArray(const byte *array){}void InvalidAddress::getFromCPUAddress(CPU_ADDR *ca){}bool InvalidAddress::getFromUInt64(uint64 u){	return false;}bool InvalidAddress::isValid(){	return false;}int InvalidAddress::parseString(const char *s, int length, Analyser *a){	return 0;}ObjectID InvalidAddress::getObjectID() const{	return ATOM_ADDRESS_INVALID;}void InvalidAddress::putIntoArray(byte *array) const{}bool InvalidAddress::putIntoUInt64(uint64 &u) const{	return false;}int InvalidAddress::stringify(char *s, int max_length, int format) const{	return ht_snprintf(s, max_length, "*INVALID");}int InvalidAddress::stringSize() const{	return 8;}/* * */bool AddressFlat32::add(int offset){	// check for overflow	if ((int)offset < 0) {		if (addr+offset > addr) return false;	} else {		if (addr+offset < addr) return false;	}	addr+=offset;	return true;}int AddressFlat32::byteSize(){	return 4;}int AddressFlat32::compareTo(const Object *obj) const{	assert(getObjectID() == obj->getObjectID());	if (addr > ((AddressFlat32 *)obj)->addr) return 1;	if (addr < ((AddressFlat32 *)obj)->addr) return -1;	return 0;}int AddressFlat32::compareDelinear(Address *to){	assert(getObjectID() == to->getObjectID());	uint32 da = delinearize(addr);	uint32 db = delinearize(((AddressFlat32 *)to)->addr);	if (da > db) return 1;	if (da < db) return -1;	return 0;}bool AddressFlat32::difference(int &result, Address *to){	if (getObjectID() == to->getObjectID()) {		result = addr - ((AddressFlat32 *)to)->addr;		return true;	} else {		return false;	}}AddressFlat32 *AddressFlat32::clone() const{	return new AddressFlat32(*this);}void AddressFlat32::getFromArray(const byte *array){	UNALIGNED_MOVE(addr, *(uint32*)array);}void AddressFlat32::getFromCPUAddress(CPU_ADDR *ca){	addr = ca->addr32.offset;}bool AddressFlat32::getFromUInt64(uint64 u){	if (u <= 0xffffffff) {		addr = u;		return true;	} else {		return false;	}}void AddressFlat32::load(ObjectStream &st){	GET_INT32X(st, addr);}ObjectID AddressFlat32::getObjectID() const{	return ATOM_ADDRESS_FLAT_32;}int AddressFlat32::parseString(const char *s, int length, Analyser *a){	return false;}void AddressFlat32::putIntoArray(byte *array) const{	UNALIGNED_MOVE(*(uint32*)array, addr);}void AddressFlat32::putIntoCPUAddress(CPU_ADDR *ca) const{	ca->addr32.offset = addr;}bool AddressFlat32::putIntoUInt64(uint64 &u) const{	u = addr;	return true;}void AddressFlat32::store(ObjectStream &st) const{	PUT_INT32X(st, addr);}int AddressFlat32::stringify(char *s, int max_length, int format) const{	const char *formats[] = {		"%s%x%s",		"%s%8x%s",		"%s%08x%s",		"",		"%s%X%s",		"%s%8X%s",		"%s%08X%s",		"",	};	return ht_snprintf(s, max_length, formats[format&7], (format & ADDRESS_STRING_FORMAT_ADD_0X) ? "0x":"", addr, (format & ADDRESS_STRING_FORMAT_ADD_H) ? "h":"");}int AddressFlat32::stringSize() const{	return 8;}/* * */bool AddressFlat64::add(int offset){	// check for overflow	// FIXME: XXXXXXXXXXXXX	addr += sint64(offset);	return true;}int AddressFlat64::byteSize(){	return 8;}int AddressFlat64::compareTo(const Object *obj) const{	assert(getObjectID() == obj->getObjectID());	if (addr > ((AddressFlat64 *)obj)->addr) return 1;	if (addr < ((AddressFlat64 *)obj)->addr) return -1;	return 0;}int AddressFlat64::compareDelinear(Address *to){	assert(getObjectID() == to->getObjectID());	uint64 da1, da2;	da1 = delinearize64(addr);	da2 = delinearize64(((AddressFlat64 *)to)->addr);	if (da1 > da2) return 1;	if (da1 < da2) return -1;	return 0;}bool AddressFlat64::difference(int &result, Address *to){	if (getObjectID() == to->getObjectID()) {		uint64 res = addr - ((AddressFlat64 *)to)->addr;		uint32 rh = res >> 32;		if (!rh || rh == 0xffffffff) {			result = res;			return true;		}	}	return false;}AddressFlat64 *AddressFlat64::clone() const{	return new AddressFlat64(*this);}void AddressFlat64::getFromArray(const byte *array){	UNALIGNED_MOVE(addr, *(uint64*)array);}void AddressFlat64::getFromCPUAddress(CPU_ADDR *ca){	addr = ca->flat64.addr;}bool AddressFlat64::getFromUInt64(uint64 u){	addr = u;	return true;}void AddressFlat64::load(ObjectStream &st){	GET_INT64X(st, addr);}ObjectID AddressFlat64::getObjectID() const{	return ATOM_ADDRESS_FLAT_64;}int AddressFlat64::parseString(const char *s, int length, Analyser *a){	return false;}void AddressFlat64::putIntoArray(byte *array) const{	UNALIGNED_MOVE(*(uint64*)array, addr);}void AddressFlat64::putIntoCPUAddress(CPU_ADDR *ca) const{	ca->flat64.addr = addr;}bool AddressFlat64::putIntoUInt64(uint64 &u) const{	u = addr;	return true;}void AddressFlat64::store(ObjectStream &st) const{	PUT_INT64X(st, addr);}int AddressFlat64::stringify(char *s, int max_length, int format) const{	const char *formats[] = {		"%s%qx%s",		"%s%16qx%s",		"%s%016qx%s",		"",		"%s%qx%s",		"%s%16qx%s",		"%s%016qx%s",		"",	};	return ht_snprintf(s, max_length, formats[format&7], (format & ADDRESS_STRING_FORMAT_ADD_0X) ? "0x":"", addr, (format & ADDRESS_STRING_FORMAT_ADD_H) ? "h":"");}int AddressFlat64::stringSize() const{	return 16;}/* * */ AddrXRef::AddrXRef(Address *a, xref_enum_t Type){	addr = a->clone();	type = Type;}AddrXRef::~AddrXRef(){	delete addr;}void AddrXRef::load(ObjectStream &f){	GET_OBJECT(f, addr);	type = (xref_enum_t)GETX_INTX(f, 1, "type");}ObjectID AddrXRef::getObjectID() const{	return ATOM_ADDR_XREF;}void AddrXRef::store(ObjectStream &f) const{	PUT_OBJECT(f, addr);	PUT_INTX(f, type, 1);}int AddrXRef::compareTo(const Object *o) const{	Address *a = ((AddrXRef*)o)->addr;	return addr->compareTo(a);}/* * */AddressQueueItem::AddressQueueItem(Address *aAddr, Address *aFunc){	addr = aAddr->clone();	func = aFunc->clone();}AddressQueueItem::~AddressQueueItem(){	delete addr;	delete func;}ObjectID AddressQueueItem::getObjectID() const{	return ATOM_ADDR_QUEUE_ITEM;}void AddressQueueItem::load(ObjectStream &f){	GET_OBJECT(f, addr);	GET_OBJECT(f, func);}void	AddressQueueItem::store(ObjectStream &f) const{	PUT_OBJECT(f, addr);	PUT_OBJECT(f, func);}/* * */CommentList::CommentList()	: Array(true){}void CommentList::appendPreComment(const char *s){	insert(new String(s));}void CommentList::appendPostComment(const char *s){	insert(new String(s));}void CommentList::appendPreComment(int special){	insert(new UInt(special));}void CommentList::appendPostComment(int special){	insert(new UInt(special+0x10000000));}const char *CommentList::getName(uint i){	Object *d = get(findByIdx(i));//	return d ? ((d->getObjectID()==OBJID_UINT) ? comment_lookup(((UInt*)d)->value): 	return d ? ((String*)d)->contentChar() : NULL;}/* * */void	Analyser::init(){	active = false;	dirty = false;	next_address_is_invalid = false;	addr = new InvalidAddress();	invalid_addr = new InvalidAddress();	addr_queue = new Queue(true);	locations = NULL;	symbols = NULL;	symbol_count = location_count = 0;	cur_addr_ops = cur_label_ops = 1;	setLocationTreeOptimizeThreshold(1000);	setSymbolTreeOptimizeThreshold(1000);	cur_func = NULL;	ops_parsed = 0;	next_explored = new InvalidAddress();	first_explored = new InvalidAddress();	last_explored = new InvalidAddress();	explored = new Area();	explored->init();	initialized = new Area();	initialized->init();	initCodeAnalyser();	initDataAnalyser();	disasm = NULL;	analy_disasm = NULL;	max_opcode_length = 1;	initUnasm();	mode = ANALY_TRANSLATE_SYMBOLS;}static void loadlocations(ObjectStream &st, Location *&loc, int l, int r){	if (l > r) {		loc = NULL;		return;	}	int m = (l+r)/2;	loc = new Location;	loadlocations(st, loc->left, l, m-1);	loc->addr = GETX_OBJECT(st , "addr");	// xrefs	loc->xrefs = GETX_OBJECT(st, "xrefs");		// comments	loc->comments = GETX_OBJECT(st, "comments");		analyser_get_addrtype(st, &loc->type);	// must be resolved later (thisfunc is of type Location not Address)	Address *a = GETX_OBJECT(st, "func");	loc->thisfunc = (Location *)a;	loc->flags = GETX_INT(st, 1, "flags");	loc->label = NULL;	loadlocations(st, loc->right, m+1, r);}static void loadsymbols(Analyser *analy, ObjectStream &st, Symbol *&symbol, int l, int r){	if (l > r) {		symbol = NULL;		return;	}	int m = (l+r)/2;	symbol = new Symbol;	loadsymbols(analy, st, symbol->left, l, m-1);	Address *a = GETX_OBJECT(st, "addr");	(symbol->location = analy->newLocation(a))->label = symbol;	delete a;		symbol->name = st.getString("name");	symbol->type = (labeltype)GETX_INT(st, 1, "type");	loadsymbols(analy, st, symbol->right, m+1, r);}static void resolveaddrs(Analyser *a, Location *loc){	if (loc) {		resolveaddrs(a, loc->left);		Address *tmp = (Address*)loc->thisfunc;		if (tmp->isValid()) {			loc->thisfunc = a->getLocationByAddress(tmp);		} else {			loc->thisfunc = NULL;		}		delete tmp;		resolveaddrs(a, loc->right);	}}/* * */void Analyser::load(ObjectStream &st){	cur_addr_ops = 0;	cur_label_ops = 0;	GET_OBJECT(st, addr);	invalid_addr = new InvalidAddress();	GET_OBJECT(st, addr_queue);	GET_INT32D(st, ops_parsed);	GET_BOOL(st, active);	if (active) {		some_analyser_active++;	}	next_address_is_invalid = false;	GET_OBJECT(st, next_explored);	GET_OBJECT(st, first_explored);	GET_OBJECT(st, last_explored);	GET_INT32X(st, mode);	GET_OBJECT(st, explored);	GET_OBJECT(st, initialized);	cur_addr_ops = cur_label_ops = 1;	setLocationTreeOptimizeThreshold(1000);	setSymbolTreeOptimizeThreshold(1000);	GET_INT32D(st, location_count);	loadlocations(st, locations, 0, location_count-1);	resolveaddrs(this, locations);	GET_INT32D(st, symbol_count);	loadsymbols(this, st, symbols, 0, symbol_count-1);	GET_OBJECT(st, analy_disasm);	GET_OBJECT(st, disasm);     	if (analy_disasm) {		analy_disasm->analy = this;		analy_disasm->disasm = disasm;	}	GET_OBJECT(st, code);	GET_OBJECT(st, data);	if (data) {		data->analy = this;	}	GET_INT32D(st, location_threshold);	GET_INT32D(st, symbol_threshold);	GET_INT32D(st, max_opcode_length);	Address *curfuncaddr = GETX_OBJECT(st, "cur_func");	if (curfuncaddr) {		cur_func = newLocation(curfuncaddr);		delete curfuncaddr;	} else {		cur_func = NULL;	}		dirty = false;}/* * */void	Analyser::done(){	setActive(false);	freeLocations(locations);	freeSymbols(symbols);	delete addr_queue;	if (explored) {		explored->done();		delete explored;	}	if (initialized) {		initialized->done();		delete initialized;	}	if (code) {		code->done();		delete code;	}	if (data) {		data->done();		delete data;	}	if (disasm) {		disasm->done();		delete disasm;	}	if (analy_disasm) {		analy_disasm->done();		delete analy_disasm;	}	delete addr;	delete invalid_addr;	delete next_explored;	delete first_explored;	delete last_explored;}/* *	addAddressSymbol will never overwrite an existing label (like addlabel) */bool Analyser::addAddressSymbol(Address *address, const char *prefix, labeltype type, Location *infunc){	if (!validAddress(address, scvalid)) return false;	char symbol[1024];	global_analyser_address_string_format = ADDRESS_STRING_FORMAT_COMPACT;	ht_snprintf(symbol, sizeof symbol, "%s_%y", prefix, address);	if (addSymbol(address, symbol, type, infunc)) {		return true;	} else {		return false;	}}/* * */void	Analyser::addComment(Address *Addr, int line, const char *c){	// line 0 meens append (at the moment assume append every time ;-))//	if (!validaddr(Addr, scvalid)) return;	Location *a = newLocation(Addr);	CommentList *com = a->comments;	if (!com) {		com = new CommentList();		com->init();		a->comments = com;

⌨️ 快捷键说明

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