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

📄 mfile.cc

📁 功能较全面的反汇编器:反汇编器ht-2.0.15.tar.gz
💻 CC
📖 第 1 页 / 共 2 页
字号:
			memcpy(b->buf, m->buf+d, b->size);			m->size = d;			m->buf = (byte*)realloc(m->buf, d);			mods += b;			// create new MFAs between 'a' and 'b'			FileOfs start = t;			while (ssize != 0) {				FileOfs k = MAX_MFA_SIZE;				if (k > ssize) k = ssize;				mods += new ModifiedFileArea(start, k);				ssize -= k;				start += k;			}		}	} else {		// no, append.		FileOfs start = t;		while (ssize != 0) {			FileOfs k = MAX_MFA_SIZE;			if (k > ssize) k = ssize;			mods += new ModifiedFileArea(start, k);			ssize -= k;			start += k;		}	}		// (2) write data	const byte *b = (const byte*)buf;	FileOfs o = t;	h = findArea(o);	while (size && (h != invObjHandle)) {		FileArea *a = (FileArea*)mods.get(h);		FileOfs s = o - a->start;		FileOfs z = a->size - s;		if (z > size) z = size;		if (z > a->size) z = a->size;//		ht_printf("%qx, now write %qx\n", a->start, z);		write1(a, s, b, z);		o += z;		size -= z;		b += z;		h = mods.findNext(h);	}	newsize += o-t;	seek(o);	mcount++;}void FileModificator::makeAreaModified(ObjHandle h, FileOfs rstart, FileOfs size){	FileArea *a = (FileArea*)mods.get(h);	if (a->getObjectID() == OBJID_CFA) {		// not marked modified, do something		CopiedFileArea *c = (CopiedFileArea*)a;		FileOfs csrc_start = c->src_start;		FileOfs cstart = c->start;		FileOfs csize = c->size;		bool have_head_gap = rstart != 0;		bool have_tail_gap = csize > rstart+size;		ModifiedFileArea *prev_m = (ModifiedFileArea*)mods.get(mods.findPrev(h));//		ASSERT(!prev_m || (prev_m->getObjectID() == OBJID_MFA));		if (prev_m && (prev_m->getObjectID() != OBJID_MFA)) prev_m = NULL;		ModifiedFileArea *next_m = (ModifiedFileArea*)mods.get(mods.findNext(h));		if (next_m && (next_m->getObjectID() != OBJID_MFA)) next_m = NULL;//		ASSERT(!next_m || (next_m->getObjectID() == OBJID_MFA));		// "min condition"		// ===============		// trick for FA packing: we simply make modified areas bigger		// than they would have to be. (either at least MIN_COND_MFA_SIZE		// big or adjacent/mergable with another MFA)		bool min_condition = (size < MIN_COND_MFA_SIZE) && (!prev_m || have_head_gap) && (!next_m || have_tail_gap);		FileOfs min_addsize;		FileOfs min_ofs;		FileOfs min_src_ofs;		if (min_condition) {			// if the MFA we will create would be too small, make it bigger			// (compare gap sizes, then try to reach boundary to			// reduce number of FAs)			if (rstart < csize-rstart-size) {				// head gap is smaller than tail gap				FileOfs z = rstart;				if (z+size > MIN_COND_MFA_SIZE) z = MIN_COND_MFA_SIZE-size;				min_addsize = z;				min_ofs = cstart+rstart-z;				min_src_ofs = csrc_start+rstart-z;				rstart -= z;			} else {				// tail gap is smaller than head gap				FileOfs z = csize-rstart-size;				if (z+size > MIN_COND_MFA_SIZE) z = MIN_COND_MFA_SIZE-size;				min_addsize = z;				min_ofs = cstart+rstart+size;				min_src_ofs = csrc_start+rstart+size;			}			size += min_addsize;			have_head_gap = rstart != 0;			have_tail_gap = csize > rstart+size;		}		if (have_head_gap) {			c->size = rstart;			cstart += rstart;			csrc_start += rstart;			csize -= rstart;		} else {			mods -= h;		}					if (next_m && !have_tail_gap) {			// merge with next MFA (successor)			FileOfs nnsize = next_m->size + size;			if (nnsize > MAX_MFA_SIZE) nnsize = MAX_MFA_SIZE;			mods.removeObj(next_m);			FileOfs rnnsize = nnsize - next_m->size;			next_m->buf = (byte*)realloc(next_m->buf, nnsize);			next_m->start -= rnnsize;			memmove(next_m->buf+rnnsize, next_m->buf, next_m->size);			next_m->size = nnsize;			mods += next_m;			csize -= rnnsize;			size -= rnnsize;		}		if (prev_m && !have_head_gap) {			// merge with previous MFA (predecessor)			FileOfs pnsize = prev_m->size + size;			if (pnsize > MAX_MFA_SIZE) pnsize = MAX_MFA_SIZE;			FileOfs rpnsize = pnsize - prev_m->size;			prev_m->size = pnsize;			prev_m->buf = (byte*)realloc(prev_m->buf, pnsize);			csrc_start += rpnsize;			cstart += rpnsize;			csize -= rpnsize;			size -= rpnsize;		}		while (size != 0) {			FileOfs k = MAX_MFA_SIZE;			if (k > size) k = size;			mods += new ModifiedFileArea(cstart, k);			size -= k;			csize -= k;			cstart += k;			csrc_start += k;		}		if (have_tail_gap) {			mods += new CopiedFileArea(cstart, csize, csrc_start);		}		if (min_condition) {			byte *buf = ht_malloc(min_addsize);			mFile->seek(min_src_ofs);			mFile->readx(buf, min_addsize);			ObjHandle ha = findArea(min_ofs);			while (min_addsize != 0) {				FileArea *a = (FileArea*)mods.get(ha);				assert(dynamic_cast<ModifiedFileArea*>(a));				FileOfs k = min_addsize;				if (k > a->size- (min_ofs-a->start)) k = a->size- (min_ofs-a->start);				write1(a, min_ofs - a->start, buf, k);				min_addsize -= k;				min_ofs += k;				ha = mods.findNext(ha);			}			free(buf);		}	}}void FileModificator::read1(FileArea *a, FileOfs rstart, byte *buf, uint count){	CopiedFileArea *c;	ModifiedFileArea *m;	if ((m = dynamic_cast<ModifiedFileArea*>(a))) {		memcpy(buf, m->buf + rstart, count);	} else if ((c = dynamic_cast<CopiedFileArea*>(a))) {		mFile->seek(c->src_start+rstart);		mFile->read(buf, count);	} else assert(0);}uint FileModificator::read(void *buf, uint size){	if (!(getAccessMode() & IOAM_READ)) throw IOException(EACCES);	FileOfs t = tell();	if (t == 0x00000000ULL) {		int a = 1;	}	FileOfs o = t;	ObjHandle h = findArea(o);	byte *b = (byte*)buf;	while (size && h != invObjHandle) {		FileArea *a = (FileArea*)mods.get(h);		FileOfs s = o - a->start;		FileOfs z = a->size - s;		if (z > size) z = size;		h = mods.findNext(h);		read1(a, s, b, z);		o += z;		size -= z;		b += z;	}	seek(o);	return o - t;}void FileModificator::seek(FileOfs offset){	if (offset > newsize) throw IOException(EINVAL);	pos = offset;}FileOfs FileModificator::tell() const{	return pos;}void FileModificator::truncate(FileOfs Newsize){	if (Newsize == newsize) return;	if (Newsize > newsize) throw IOException(EINVAL);	if (!(getAccessMode() & IOAM_WRITE)) throw IOException(EACCES);	seek(0);	ObjHandle h = findArea(Newsize);	FileArea *a = (FileArea*)mods.get(h);	if (a->start < Newsize) {		if (a->getObjectID() == OBJID_CFA) {			CopiedFileArea *c = (CopiedFileArea*)a;			c->size = Newsize - a->start;		} else {			ModifiedFileArea *m = (ModifiedFileArea*)a;			m->size = Newsize - a->start;			m->buf = (byte*)realloc(m->buf, m->size);		}		h = mods.findNext(h);	}	while (h != invObjHandle) {		ObjHandle hnext = mods.findNext(h);		FileArea *a = (FileArea*)mods.get(hnext);		mods -= h;		if (!a) break;		h = findArea(a->start);	}	newsize = Newsize;	mcount++;}void FileModificator::flushMods(){	// make sure we can read and write	int e;	IOAccessMode old_am = mFile->getAccessMode();	e = mFile->setAccessMode(IOAM_READ | IOAM_WRITE);	if (e) throw IOException(e);	// start work	if (newsize > mFile->getSize()) mFile->extend(newsize);	// store CFAs with start > src_start in descending order	foreachbwd(FileArea, fa, mods,		if (fa->getObjectID() == OBJID_CFA) {			CopiedFileArea *cfa = (CopiedFileArea*)fa;			if (cfa->start > cfa->src_start) {				mFile->move(cfa->src_start, cfa->start, cfa->size);			}		}	);	// store CFAs with start < src_start in ascending order	foreach(FileArea, fa, mods,		if (fa->getObjectID() == OBJID_CFA) {			CopiedFileArea *cfa = (CopiedFileArea*)fa;			if (cfa->start < cfa->src_start) {				mFile->move(cfa->src_start, cfa->start, cfa->size);			}		}	);	// store MFAs	foreach(FileArea, fa, mods,		if (fa->getObjectID() == OBJID_MFA) {			ModifiedFileArea *mfa = (ModifiedFileArea*)fa;			mFile->seek(mfa->start);			mFile->writex(mfa->buf, mfa->size);		}	);	//	if (newsize < mFile->getSize()) mFile->truncate(newsize);	// restore old access mode	e = mFile->setAccessMode(old_am);	if (e) throw IOException(e);	//	inv_mcount = mcount;	invalidateMods();}void FileModificator::invalidateMods(){	mods.delAll();	newsize = mFile->getSize();	if (newsize != 0) mods += new CopiedFileArea(0, newsize, 0);	pos = 0;	mcount = inv_mcount;}bool FileModificator::isModified() const{	if (newsize != mFile->getSize()) return true;	foreach(FileArea, fa, mods,		CopiedFileArea *cfa = dynamic_cast<CopiedFileArea*>(fa);		if (!cfa || (cfa->start != cfa->src_start)) return true;	);	return false;}bool FileModificator::isModifiedByte(FileOfs o){	ObjHandle h = findArea(o);	FileArea *fa = (FileArea*)mods.get(h);	if (!fa) return true;	if (fa->getObjectID() == OBJID_MFA) {		ModifiedFileArea *mfa = (ModifiedFileArea*)fa;		int pg_ofs = o - fa->start;		byte b;		mFile->seek(o);		mFile->readx(&b, 1);		return mfa->buf[pg_ofs] != b;	} else if (fa->getObjectID() == OBJID_CFA) {		CopiedFileArea *cfa = (CopiedFileArea*)fa;		if (cfa->src_start == cfa->start) return false;		int pg_ofs = o - fa->start;		byte b1, b2;		mFile->seek(o);		mFile->readx(&b1, 1);		mFile->seek(cfa->src_start + pg_ofs);		mFile->readx(&b2, 1);		return (b1 != b2);	}	return false;}int FileModificator::vcntl(uint cmd, va_list vargs){	switch (cmd) {	case FCNTL_MODS_INVD:		invalidateMods();		return 0;	case FCNTL_MODS_FLUSH:		flushMods();		return 0;	case FCNTL_MODS_CLEAR_DIRTY_RANGE: {/*		// BEFORE-IMPLEMENT: decl changed !		FileOfs o = va_arg(vargs, FileOfs);		uint s = va_arg(vargs, uint);		uint i = 0;		while (s--) {			cleardirtybyte(o+i);			i++;		}*/		return 0;	}	case FCNTL_MODS_IS_DIRTY: {		// const FileOfs offset, const FileOfs range, bool &isdirty		FileOfs o = va_arg(vargs, FileOfs);		FileOfs s = va_arg(vargs, FileOfs);		bool &b = (bool&)*va_arg(vargs, bool*);		if (o == 0 && s == newsize) {			b = isModified();		} else if (s <= 16) {			try {				bool bb = false;				while (s--) {					bb |= isModifiedByte(o++);				}				b = bb;			} catch (const IOException &x) {				return EIO;			}		} else {			return ENOSYS;		}		return 0;	}	case FCNTL_GET_MOD_COUNT: {	// int &mcount		int *mc = va_arg(vargs, int *);		*mc = mcount;		return 0;	}			}	return mFile->vcntl(cmd, vargs);}void FileModificator::write1(FileArea *a, FileOfs rstart, const byte *buf, uint count){	assert(a->getObjectID() == OBJID_MFA);//	ObjectID id = a->getObjectID();	ModifiedFileArea *m = (ModifiedFileArea*)a;	memcpy(m->buf+rstart, buf, count);}uint FileModificator::write(const void *buf, uint size){	if (!(getAccessMode() & IOAM_WRITE)) throw IOException(EACCES);	// (1) make areas modified	FileOfs t = tell();	FileOfs o = t;	uint osize = size;	while (size) {		ObjHandle h = findArea(o);		if (h == invObjHandle) break;		FileArea *a = (FileArea*)mods.get(h);		FileOfs s = o - a->start;		FileOfs z = a->size - s;		if (z > size) z = size;		makeAreaModified(h, s, z);		o += z;		size -= z;	}	// (2) write data	const byte *b = (const byte*)buf;	o = t;	size = osize;	ObjHandle h = findArea(o);	while (size && (h != invObjHandle)) {		FileArea *a = (FileArea*)mods.get(h);		FileOfs s = o - a->start;		FileOfs z = a->size - s;		if (z > size) z = size;		if (z > a->size) z = a->size;		write1(a, s, b, z);		o += z;		size -= z;		b += z;		h = mods.findNext(h);	}	seek(o);	mcount++;	return o - t;}

⌨️ 快捷键说明

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