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

📄 htxex.cc

📁 功能较全面的反汇编器:反汇编器ht-2.0.15.tar.gz
💻 CC
字号:
/* *	HT Editor *	htxex.cc * *	Copyright (C) 2006 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 <cstdlib>#include <cstring>#include "log.h"#include "endianess.h"#include "htxex.h"#include "htxexhead.h"#include "htxeximg.h"#include "stream.h"#include "tools.h"static format_viewer_if *htxex_ifs[] = {	&htxexheader_if,	&htxeximage_if,	0};static ht_view *htxex_init(Bounds *b, File *file, ht_format_group *format_group){	byte xexmagic[4];	file->seek(0);	file->read(xexmagic, 4);	if (xexmagic[0]!=XEX_MAGIC0 || xexmagic[1]!=XEX_MAGIC1 ||	    xexmagic[2]!=XEX_MAGIC2 || xexmagic[3]!=XEX_MAGIC3) return 0;	ht_xex *g=new ht_xex();	g->init(b, file, htxex_ifs, format_group, 0);	return g;}format_viewer_if htxex_if = {	htxex_init,	0};/* *	CLASS ht_xex */void ht_xex::init(Bounds *b, File *file, format_viewer_if **ifs, ht_format_group *format_group, FileOfs header_ofs){	ht_format_group::init(b, VO_BROWSABLE | VO_SELECTABLE | VO_RESIZE, DESC_XEX, file, false, true, 0, format_group);	VIEW_DEBUG_NAME("ht_xex");	ht_xex_shared_data *xex_shared = ht_malloc(sizeof (ht_xex_shared_data));	shared_data = xex_shared;	xex_shared->v_header = NULL;	xex_shared->image = NULL;	xex_shared->loader_info.type = XEX_LOADER_NONE;	xex_shared->imports.ofs = 0;	/* read header */	file->seek(0);	file->read(&xex_shared->header, sizeof xex_shared->header);	createHostStruct(&xex_shared->header, XEX_IMAGE_HEADER_struct, big_endian);	xex_shared->info_table = ht_malloc(xex_shared->header.number_of_sections * sizeof *xex_shared->info_table);	xex_shared->info_table_cooked = ht_malloc(xex_shared->header.number_of_sections * sizeof *xex_shared->info_table_cooked);	for (uint i=0; i < xex_shared->header.number_of_sections; i++) {		file->read(xex_shared->info_table+i, sizeof *xex_shared->info_table);		createHostStruct(xex_shared->info_table+i, XEX_IMAGE_HEADER_INFO_ENTRY_struct, big_endian);		xex_shared->info_table_cooked[i].type = createHostInt(&xex_shared->info_table[i].type, 4, big_endian);		xex_shared->info_table_cooked[i].start = 0;		xex_shared->info_table_cooked[i].size = xex_shared->info_table[i].b.size;		if (xex_shared->info_table[i].b.size == 0xff) {			FileOfs ofs = file->tell();			file->seek(xex_shared->info_table[i].value);			uint32 s;			if (file->read(&s, 4) == 4) {				xex_shared->info_table_cooked[i].start = xex_shared->info_table[i].value + 4;				xex_shared->info_table_cooked[i].size = createHostInt(&s, 4, big_endian) - 4;			}			file->seek(ofs);		} else if (xex_shared->info_table[i].b.size > 1) {			xex_shared->info_table_cooked[i].start = xex_shared->info_table[i].value;			xex_shared->info_table_cooked[i].size = xex_shared->info_table[i].b.size * 4;		}	}	for (uint i=0; i < xex_shared->header.number_of_sections; i++) {		switch (xex_shared->info_table_cooked[i].type) {		case XEX_HEADER_FIELD_LOADERINFO: {			uint32 size = xex_shared->info_table_cooked[i].size;			if (size > 4) {				XEX_LOADER_INFO_HEADER ldhdr;				file->seek(xex_shared->info_table_cooked[i].start);				if (file->read(&ldhdr, sizeof ldhdr) == sizeof ldhdr) {					size -= 4;					createHostStruct(&ldhdr, XEX_LOADER_INFO_HEADER_struct, big_endian);					if (!ldhdr.crypted && ldhdr.type == XEX_LOADER_RAW) {						int entries = size / 8;						xex_shared->loader_info.type = XEX_LOADER_RAW;						xex_shared->loader_info.raw.sections = new Array(true, entries);						for (int j=0; j < entries; j++) {							XEX_RAW_LOADER_ENTRY e;							if (file->read(&e, sizeof e) != sizeof e) break;							createHostStruct(&e, XEX_RAW_LOADER_ENTRY_struct, big_endian);							xex_shared->loader_info.raw.sections->insert(								new XEXLoaderRawSection(e.raw, e.pad));						}					}				}			}			break;		}		case XEX_HEADER_FIELD_IMPORT:			xex_shared->imports.ofs = xex_shared->info_table[i].value;			break;		case XEX_HEADER_FIELD_ENTRY:			xex_shared->entrypoint = xex_shared->info_table[i].value;			break;		case XEX_HEADER_FIELD_BASE:			xex_shared->image_base = xex_shared->info_table[i].value;			break;		}	}	file->seek(xex_shared->header.file_header_offset);	if (file->read(&xex_shared->file_header, sizeof xex_shared->file_header) == sizeof xex_shared->file_header) {		createHostStruct(&xex_shared->file_header, XEX_FILE_HEADER_struct, big_endian);		xex_shared->image_base = xex_shared->file_header.load_address;		xex_shared->image_size = xex_shared->file_header.image_size;		file->seek(xex_shared->header.file_header_offset+0x184);		xex_shared->pages.page = new XexPage[xex_shared->file_header.pages];		for (int i=0; i < xex_shared->file_header.pages; i++) {			uint32 flags;			file->read(&flags, 4);			flags = createHostInt(&flags, 4, big_endian);			xex_shared->pages.page[i].flags = flags;			file->seek(file->tell()+20);		}		xex_shared->pages.page_shift = 16; // FIXME: can also be 12	} else {		xex_shared->pages.page = NULL;		xex_shared->file_header.hdr_size = 0;		xex_shared->image_size = 0;		xex_shared->image_base = 0;	}		xex_shared->imports.lib_count = 0;	xex_shared->imports.libs = NULL;	try {		if (xex_shared->imports.ofs) {			file->seek(xex_shared->imports.ofs);			uint32 size, sizen, l;			file->readx(&size, 4);	    		file->readx(&sizen, 4);			file->readx(&l, 4);			size = createHostInt(&size, 4, big_endian);			sizen = createHostInt(&sizen, 4, big_endian);			l = createHostInt(&l, 4, big_endian);			FileOfs ofs = xex_shared->imports.ofs + 3*4 + sizen;			XexImportLib *libs = new XexImportLib[l];			if (l) {				String s;				for (uint i=0; i < l; i++) {					s.clear();					file->readStringz(s);					libs[i].name = strdup(s.contentChar());				}								// patch table				for (uint i=0; i < l; i++) {									file->seek(ofs);					file->readx(&sizen, 4);					sizen = createHostInt(&sizen, 4, big_endian);					ofs += sizen;										file->seek(36 + file->tell()); // skip garbage					int count = (sizen - 40) / 4;					libs[i].func_count = count;					if (count) {						libs[i].funcs = new XexImportFunc[count];					} else {						libs[i].funcs = NULL;					}					for (int j=0; j < count; j++) {						uint32 patch;						file->readx(&patch, 4);						libs[i].funcs[j].patch = createHostInt(&patch, 4, big_endian);						libs[i].funcs[j].ord = libs[i].funcs[j].ia = 0;					}				}							}			xex_shared->imports.libs = libs;			xex_shared->imports.lib_count = l;		}	} catch (...) {}		xex_shared->image = new MemoryFile(0, xex_shared->image_size);	try {		if (xex_shared->loader_info.type == XEX_LOADER_RAW) {			file->seek(xex_shared->header.size);			FileOfs ofs = 0;			foreach(XEXLoaderRawSection, section, *xex_shared->loader_info.raw.sections, {				xex_shared->image->seek(ofs);				file->copyTo(xex_shared->image, section->raw);				ofs += section->raw + section->pad;			});		}	} catch (...) {}	uint32 *iat = new uint32[0x8000];	byte *image_ptr = xex_shared->image->getBufPtr();	for (int i=0; i < xex_shared->imports.lib_count; i++) {		memset(iat, 0, 4*0x8000);		// get import ordinals		XexImportLib *lib = xex_shared->imports.libs+i;		for (int j=0; j < lib->func_count; j++) {			uint32 ord;			ord = lib->funcs[j].ord = createHostInt(&image_ptr[lib->funcs[j].patch - xex_shared->image_base], 4, big_endian);			if ((ord & 0xff000000) == 0) {				ord &= 0x7fff;				if (iat[ord]) {//					fprintf(stderr, "%s: warning: duplicate import %d from library '%s'\n", infn, ord, imports[i].lib);				} else {					iat[ord] = lib->funcs[j].patch;				}			}		}//		printf("\n; Library '%s':\n", lib.name);		// resolve imports		for (int j=0; j < lib->func_count; j++) {			uint32 ord = lib->funcs[j].ord;			if (ord & 0xff000000) {				int libidx = (ord & 0x00ff0000) >> 16;				ord &= 0x7fff;				if (libidx != i) {/*					if (libidx < import_count) {						fprintf(stderr, "%s: import %d from library '%s', but in section of library '%s'\n", infn, ord, imports[libidx].lib, imports[i].lib);					} else {						fprintf(stderr, "%s: import %d from unknown library %d, but in section of library '%s'\n", infn, ord, libidx, imports[i].lib);					}					return 1;*/					continue;				}				if (!iat[ord]) {/*					fprintf(stderr, "%s: import %d from library '%s' need to be resolved but is not imported\n", infn, ord, imports[i].lib);					return 1;*/					continue;				}				uint32 ia = iat[ord];								// patch it				uint32 lis_r11 = (0x3d600000 | (ia >> 16)) + !!(ia & 0x8000);				uint32 lwz_r11 = (0x816b0000 | (ia & 0xffff));								createForeignInt(&image_ptr[lib->funcs[j].patch-xex_shared->image_base], lis_r11, 4, big_endian);				createForeignInt(&image_ptr[lib->funcs[j].patch-xex_shared->image_base+4], lwz_r11, 4, big_endian);								lib->funcs[j].ia = ia; /*				char s[100];				snprintf(s, sizeof s, "wrapper_import_%s_%d", imports[i].lib, ord);				printf("function 0x%08x name '%s'\n", imports[i].func[j].patch, s);								printf("xref 0x%08x -> 0x%08x\n", ia, imports[i].func[j].patch + 12);*/							} else {/*				ord &= 0x7fff;				char s[100];				snprintf(s, sizeof s, "import_%s_%d", imports[i].lib, ord);				printf("function_ptr 0x%08x name '%s'\n", imports[i].func[j].patch, s);*/			}		}	}	delete[] iat;		ht_format_group::init_ifs(ifs);}void ht_xex::done(){	ht_format_group::done();	ht_xex_shared_data *xex_shared = (ht_xex_shared_data*)shared_data;	delete[] xex_shared->pages.page;	for (int i=0; i < xex_shared->imports.lib_count; i++) {		free(xex_shared->imports.libs[i].name);		delete[] xex_shared->imports.libs[i].funcs;	}	delete[] xex_shared->imports.libs;	free(xex_shared->info_table);	free(xex_shared->info_table_cooked);	delete xex_shared->image;	free(xex_shared);}bool xex_ofs_to_rva(ht_xex_shared_data *xex_shared, FileOfs ofs, RVA &rva){#if 0	FileOfs xex_ofs = 0;	RVA xex_va = 0;	for (int i = 0; i < g_entry_count; i++) {		if (xex_ofs <= ofs && xex_ofs+g_entries[i].raw > ofs) {			res = xex_va + (ofs - xex_ofs);			return true;		}		xex_va += g_entries[i].raw + g_entries[i].pad;		xex_ofs += g_entries[i].raw;		if (xex_ofs > ofs) return false;	}	return false;#else	if (ofs < xex_shared->image_size) {		rva = ofs;		return true;	} else {		return false;	}#endif}bool xex_rva_to_ofs(ht_xex_shared_data *xex_shared, RVA rva, FileOfs &ofs){#if 0	FileOfs xex_ofs = 0;	RVA xex_va = 0;	for (int i = 0; i < g_entry_count; i++) {		if (xex_va <= va && xex_va + g_entries[i].read > va) {			res = xex_ofs + (va - xex_va);			return true;		}		xex_va += g_entries[i].read + g_entries[i].pad;		xex_ofs += g_entries[i].read;		if (xex_va > va) return false;	}	return false;#else	if (rva < xex_shared->image_size) {		ofs = rva;		return true;	} else {		return false;	}#endif}uint32 xex_get_rva_flags(ht_xex_shared_data *xex_shared, RVA rva){	uint pagen = rva >> xex_shared->pages.page_shift;	XexPage *p = xex_shared->pages.page + pagen;	return p->flags;}

⌨️ 快捷键说明

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