winedump: Use a uniform scheme for dumping file contents.
This commit is contained in:
parent
80b09ccf4c
commit
9ef9d62d4c
|
@ -143,96 +143,30 @@ unsigned long Offset(const void* ptr)
|
|||
return (const char *)ptr - (const char *)dump_base;
|
||||
}
|
||||
|
||||
static void do_dump( enum FileSig sig )
|
||||
static const struct dumper
|
||||
{
|
||||
if (sig == SIG_NE)
|
||||
enum FileSig kind;
|
||||
enum FileSig (*get_kind)(void);
|
||||
file_dumper dumper; /* default dump tool */
|
||||
}
|
||||
dumpers[] =
|
||||
{
|
||||
ne_dump();
|
||||
return;
|
||||
}
|
||||
|
||||
if (sig == SIG_LE)
|
||||
{
|
||||
le_dump();
|
||||
return;
|
||||
}
|
||||
|
||||
pe_dump();
|
||||
}
|
||||
|
||||
static enum FileSig check_headers(void)
|
||||
{
|
||||
const char *p;
|
||||
const WORD* pw;
|
||||
const DWORD* pdw;
|
||||
const IMAGE_DOS_HEADER* dh;
|
||||
enum FileSig sig;
|
||||
|
||||
pw = PRD(0, sizeof(WORD));
|
||||
if (!pw) {printf("Can't get main signature, aborting\n"); return 0;}
|
||||
|
||||
switch (*pw)
|
||||
{
|
||||
case IMAGE_DOS_SIGNATURE:
|
||||
sig = SIG_DOS;
|
||||
dh = PRD(0, sizeof(IMAGE_DOS_HEADER));
|
||||
if (dh)
|
||||
{
|
||||
/* the signature is the first DWORD */
|
||||
pdw = PRD(dh->e_lfanew, sizeof(DWORD));
|
||||
if (pdw)
|
||||
{
|
||||
if (*pdw == IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
sig = SIG_PE;
|
||||
}
|
||||
else if (*(const WORD *)pdw == IMAGE_OS2_SIGNATURE)
|
||||
{
|
||||
sig = SIG_NE;
|
||||
}
|
||||
else if (*(const WORD *)pdw == IMAGE_VXD_SIGNATURE)
|
||||
{
|
||||
sig = SIG_LE;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("No PE Signature found\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Can't get the extented signature, aborting\n");
|
||||
}
|
||||
}
|
||||
return sig;
|
||||
|
||||
case 0x4944: /* "DI" */
|
||||
return SIG_DBG;
|
||||
|
||||
case 0x444D: /* "MD" */
|
||||
pdw = PRD(0, sizeof(DWORD));
|
||||
if (pdw && *pdw == 0x504D444D) /* "MDMP" */
|
||||
return SIG_MDMP;
|
||||
return SIG_UNKNOWN;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p = PRD(0, IMAGE_ARCHIVE_START_SIZE);
|
||||
if (p && !strncmp(p, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
|
||||
return SIG_COFFLIB;
|
||||
|
||||
printf("No known main signature (%.2s/%x), aborting\n", (const char *)pw, *pw);
|
||||
return SIG_UNKNOWN;
|
||||
}
|
||||
{SIG_DOS, get_kind_exec, NULL},
|
||||
{SIG_PE, get_kind_exec, pe_dump},
|
||||
{SIG_DBG, get_kind_dbg, dbg_dump},
|
||||
{SIG_NE, get_kind_exec, ne_dump},
|
||||
{SIG_LE, get_kind_exec, le_dump},
|
||||
{SIG_COFFLIB, get_kind_lib, lib_dump},
|
||||
{SIG_MDMP, get_kind_mdmp, mdmp_dump},
|
||||
{SIG_UNKNOWN, NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
int dump_analysis(const char *name, file_dumper fn, enum FileSig wanted_sig)
|
||||
{
|
||||
int fd;
|
||||
enum FileSig effective_sig;
|
||||
int ret = 1;
|
||||
struct stat s;
|
||||
const struct dumper *dpr;
|
||||
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
|
@ -250,37 +184,16 @@ int dump_analysis(const char *name, file_dumper fn, enum FileSig wanted_sig)
|
|||
if ((unsigned long)read( fd, dump_base, dump_total_len ) != dump_total_len) fatal( "Cannot read file" );
|
||||
}
|
||||
|
||||
effective_sig = check_headers();
|
||||
|
||||
if (wanted_sig == SIG_UNKNOWN || wanted_sig == effective_sig)
|
||||
for (dpr = dumpers; dpr->kind != SIG_UNKNOWN; dpr++)
|
||||
{
|
||||
switch (effective_sig)
|
||||
if (dpr->get_kind() == dpr->kind &&
|
||||
(wanted_sig == SIG_UNKNOWN || wanted_sig == dpr->kind))
|
||||
{
|
||||
case SIG_UNKNOWN: /* shouldn't happen... */
|
||||
printf("Can't get a recognized file signature, aborting\n");
|
||||
ret = 0; break;
|
||||
case SIG_PE:
|
||||
case SIG_NE:
|
||||
case SIG_LE:
|
||||
printf("Contents of \"%s\": %ld bytes\n\n", name, dump_total_len);
|
||||
(*fn)(effective_sig);
|
||||
break;
|
||||
case SIG_DBG:
|
||||
dbg_dump();
|
||||
break;
|
||||
case SIG_DOS:
|
||||
ret = 0; break;
|
||||
case SIG_MDMP:
|
||||
mdmp_dump();
|
||||
break;
|
||||
|
||||
case SIG_COFFLIB:
|
||||
printf("Contents of \"%s\": %ld bytes\n\n", name, dump_total_len);
|
||||
lib_dump(dump_base, dump_total_len);
|
||||
if (fn) fn(); else dpr->dumper();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (dpr->kind == SIG_UNKNOWN)
|
||||
{
|
||||
printf("Can't get a suitable file signature, aborting\n");
|
||||
ret = 0;
|
||||
|
@ -300,5 +213,5 @@ int dump_analysis(const char *name, file_dumper fn, enum FileSig wanted_sig)
|
|||
|
||||
void dump_file(const char* name)
|
||||
{
|
||||
dump_analysis(name, do_dump, SIG_UNKNOWN);
|
||||
dump_analysis(name, NULL, SIG_UNKNOWN);
|
||||
}
|
||||
|
|
|
@ -80,29 +80,33 @@ static void dump_import_object(const IMPORT_OBJECT_HEADER *ioh)
|
|||
}
|
||||
}
|
||||
|
||||
void lib_dump(const char *lib_base, unsigned long lib_size)
|
||||
enum FileSig get_kind_lib(void)
|
||||
{
|
||||
long cur_file_pos;
|
||||
IMAGE_ARCHIVE_MEMBER_HEADER *iamh;
|
||||
|
||||
if (strncmp(lib_base, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
|
||||
{
|
||||
printf("Not a valid COFF library file");
|
||||
return;
|
||||
const char* arch = PRD(0, IMAGE_ARCHIVE_START_SIZE);
|
||||
if (arch && !strncmp(arch, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
|
||||
return SIG_COFFLIB;
|
||||
return SIG_UNKNOWN;
|
||||
}
|
||||
|
||||
iamh = (IMAGE_ARCHIVE_MEMBER_HEADER *)(lib_base + IMAGE_ARCHIVE_START_SIZE);
|
||||
void lib_dump(void)
|
||||
{
|
||||
long cur_file_pos;
|
||||
const IMAGE_ARCHIVE_MEMBER_HEADER *iamh;
|
||||
|
||||
cur_file_pos = IMAGE_ARCHIVE_START_SIZE;
|
||||
|
||||
while (cur_file_pos < lib_size)
|
||||
for (;;)
|
||||
{
|
||||
IMPORT_OBJECT_HEADER *ioh;
|
||||
const IMPORT_OBJECT_HEADER *ioh;
|
||||
long size;
|
||||
|
||||
if (!(iamh = PRD(cur_file_pos, sizeof(*iamh)))) break;
|
||||
cur_file_pos += sizeof(IMAGE_ARCHIVE_MEMBER_HEADER);
|
||||
|
||||
#if 0 /* left here for debugging purposes, also should be helpful for
|
||||
* adding support for new library formats.
|
||||
*/
|
||||
printf("cur_file_pos %08lx\n", (ULONG_PTR)iamh - (ULONG_PTR)lib_base);
|
||||
printf("cur_file_pos %08lx\n", Offset(iamh));
|
||||
|
||||
printf("Name %.16s", iamh->Name);
|
||||
if (!strncmp(iamh->Name, IMAGE_ARCHIVE_LINKER_MEMBER, sizeof(iamh->Name)))
|
||||
|
@ -121,7 +125,7 @@ void lib_dump(const char *lib_base, unsigned long lib_size)
|
|||
/* FIXME: only import library contents with the short format are
|
||||
* recognized.
|
||||
*/
|
||||
ioh = (IMPORT_OBJECT_HEADER *)((char *)iamh + sizeof(IMAGE_ARCHIVE_MEMBER_HEADER));
|
||||
if (!(ioh = PRD(cur_file_pos + sizeof(*iamh), sizeof(*ioh)))) break;
|
||||
if (ioh->Sig1 == IMAGE_FILE_MACHINE_UNKNOWN && ioh->Sig2 == IMPORT_OBJECT_HDR_SIG2)
|
||||
{
|
||||
dump_import_object(ioh);
|
||||
|
@ -130,7 +134,6 @@ void lib_dump(const char *lib_base, unsigned long lib_size)
|
|||
size = strtoul((const char *)iamh->Size, NULL, 10);
|
||||
size = (size + 1) & ~1; /* align to an even address */
|
||||
|
||||
cur_file_pos += size + sizeof(IMAGE_ARCHIVE_MEMBER_HEADER);
|
||||
iamh = (IMAGE_ARCHIVE_MEMBER_HEADER *)((char *)iamh + size + sizeof(IMAGE_ARCHIVE_MEMBER_HEADER));
|
||||
cur_file_pos += size;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,17 @@ static const MINIDUMP_DIRECTORY* get_mdmp_dir(const MINIDUMP_HEADER* hdr, int st
|
|||
return NULL;
|
||||
}
|
||||
|
||||
enum FileSig get_kind_mdmp(void)
|
||||
{
|
||||
const DWORD* pdw;
|
||||
|
||||
pdw = PRD(0, sizeof(DWORD));
|
||||
if (!pdw) {printf("Can't get main signature, aborting\n"); return SIG_UNKNOWN;}
|
||||
|
||||
if (*pdw == 0x444D /* "MDMP" */) return SIG_MDMP;
|
||||
return SIG_UNKNOWN;
|
||||
}
|
||||
|
||||
void mdmp_dump(void)
|
||||
{
|
||||
const MINIDUMP_HEADER* hdr = (const MINIDUMP_HEADER*)PRD(0, sizeof(MINIDUMP_HEADER));
|
||||
|
|
|
@ -784,6 +784,17 @@ static void dump_dir_tls(void)
|
|||
printf(" }\n\n");
|
||||
}
|
||||
|
||||
enum FileSig get_kind_dbg(void)
|
||||
{
|
||||
const WORD* pw;
|
||||
|
||||
pw = PRD(0, sizeof(WORD));
|
||||
if (!pw) {printf("Can't get main signature, aborting\n"); return 0;}
|
||||
|
||||
if (*pw == 0x4944 /* "DI" */) return SIG_DBG;
|
||||
return SIG_UNKNOWN;
|
||||
}
|
||||
|
||||
void dbg_dump(void)
|
||||
{
|
||||
const IMAGE_SEPARATE_DEBUG_HEADER* separateDebugHead;
|
||||
|
@ -1111,6 +1122,32 @@ static void dump_debug(void)
|
|||
dump_stabs(stabs, szstabs, stabstr, szstr);
|
||||
}
|
||||
|
||||
enum FileSig get_kind_exec(void)
|
||||
{
|
||||
const WORD* pw;
|
||||
const DWORD* pdw;
|
||||
const IMAGE_DOS_HEADER* dh;
|
||||
|
||||
pw = PRD(0, sizeof(WORD));
|
||||
if (!pw) {printf("Can't get main signature, aborting\n"); return 0;}
|
||||
|
||||
if (*pw != IMAGE_DOS_SIGNATURE) return SIG_UNKNOWN;
|
||||
|
||||
if ((dh = PRD(0, sizeof(IMAGE_DOS_HEADER))))
|
||||
{
|
||||
/* the signature is the first DWORD */
|
||||
pdw = PRD(dh->e_lfanew, sizeof(DWORD));
|
||||
if (pdw)
|
||||
{
|
||||
if (*pdw == IMAGE_NT_SIGNATURE) return SIG_PE;
|
||||
if (*(const WORD *)pdw == IMAGE_OS2_SIGNATURE) return SIG_NE;
|
||||
if (*(const WORD *)pdw == IMAGE_VXD_SIGNATURE) return SIG_LE;
|
||||
return SIG_DOS;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pe_dump(void)
|
||||
{
|
||||
int all = (globals.dumpsect != NULL) && strcmp(globals.dumpsect, "ALL") == 0;
|
||||
|
@ -1191,7 +1228,7 @@ static void dll_close (void)
|
|||
}
|
||||
*/
|
||||
|
||||
static void do_grab_sym( enum FileSig sig )
|
||||
static void do_grab_sym( void )
|
||||
{
|
||||
const IMAGE_EXPORT_DIRECTORY*exportDir;
|
||||
unsigned i, j;
|
||||
|
|
|
@ -229,7 +229,7 @@ enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_NE, SIG_LE, SIG_MDMP, S
|
|||
const void* PRD(unsigned long prd, unsigned long len);
|
||||
unsigned long Offset(const void* ptr);
|
||||
|
||||
typedef void (*file_dumper)(enum FileSig sig);
|
||||
typedef void (*file_dumper)(void);
|
||||
int dump_analysis(const char*, file_dumper, enum FileSig);
|
||||
|
||||
void dump_data( const unsigned char *ptr, unsigned int size, const char *prefix );
|
||||
|
@ -237,12 +237,16 @@ const char* get_time_str( unsigned long );
|
|||
unsigned int strlenW( const unsigned short *str );
|
||||
void dump_unicode_str( const unsigned short *str, int len );
|
||||
|
||||
enum FileSig get_kind_exec(void);
|
||||
void pe_dump( void );
|
||||
void ne_dump( void );
|
||||
void le_dump( void );
|
||||
enum FileSig get_kind_mdmp(void);
|
||||
void mdmp_dump( void );
|
||||
void lib_dump( const char *lib_base, unsigned long lib_size );
|
||||
enum FileSig get_kind_lib(void);
|
||||
void lib_dump( void );
|
||||
enum FileSig get_kind_dbg(void);
|
||||
void dbg_dump( void );
|
||||
void pe_dump( void );
|
||||
|
||||
void dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr, unsigned szstr);
|
||||
void dump_codeview(unsigned long ptr, unsigned long len);
|
||||
|
|
Loading…
Reference in New Issue