4 * Copyright 2001,2005 Eric Pouech
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
34 #ifdef HAVE_SYS_STAT_H
35 # include <sys/stat.h>
37 #ifdef HAVE_SYS_MMAN_H
42 #define NONAMELESSUNION
43 #define NONAMELESSSTRUCT
49 static void* dump_base;
50 static unsigned long dump_total_len;
52 void dump_data( const unsigned char *ptr, unsigned int size, const char *prefix )
56 printf( "%s%08x: ", prefix, 0 );
62 for (i = 0; i < size; i++)
64 printf( "%02x%c", ptr[i], (i % 16 == 7) ? '-' : ' ' );
68 for (j = 0; j < 16; j++)
69 printf( "%c", isprint(ptr[i-15+j]) ? ptr[i-15+j] : '.' );
70 if (i < size-1) printf( "\n%s%08x: ", prefix, i + 1 );
75 printf( "%*s ", 3 * (16-(i%16)), "" );
76 for (j = 0; j < i % 16; j++)
77 printf( "%c", isprint(ptr[i-(i%16)+j]) ? ptr[i-(i%16)+j] : '.' );
82 const char *get_time_str(unsigned long _t)
84 const time_t t = (const time_t)_t;
85 const char *str = ctime(&t);
89 if (!str) /* not valid time */
91 strcpy(buf, "not valid time");
96 /* FIXME: I don't get the same values from MS' pedump running under Wine...
97 * I wonder if Wine isn't broken wrt to GMT settings...
99 if (len && str[len-1] == '\n') len--;
100 if (len >= sizeof(buf)) len = sizeof(buf) - 1;
101 memcpy( buf, str, len );
106 unsigned int strlenW( const WCHAR *str )
108 const WCHAR *s = str;
113 void dump_unicode_str( const WCHAR *str, int len )
115 if (len == -1) len = strlenW( str );
117 while (len-- > 0 && *str)
122 case '\n': printf( "\\n" ); break;
123 case '\r': printf( "\\r" ); break;
124 case '\t': printf( "\\t" ); break;
125 case '"': printf( "\\\"" ); break;
126 case '\\': printf( "\\\\" ); break;
128 if (c >= ' ' && c <= 126) putchar(c);
129 else printf( "\\u%04x",c);
135 const void* PRD(unsigned long prd, unsigned long len)
137 return (prd + len > dump_total_len) ? NULL : (const char*)dump_base + prd;
140 unsigned long Offset(const void* ptr)
142 if (ptr < dump_base) {printf("<<<<<ptr below\n");return 0;}
143 if ((const char *)ptr >= (const char*)dump_base + dump_total_len) {printf("<<<<<ptr above\n");return 0;}
144 return (const char *)ptr - (const char *)dump_base;
147 static void do_dump( enum FileSig sig, const void* pmt )
151 ne_dump( dump_base, dump_total_len );
157 le_dump( dump_base, dump_total_len );
164 static enum FileSig check_headers(void)
169 const IMAGE_DOS_HEADER* dh;
172 pw = PRD(0, sizeof(WORD));
173 if (!pw) {printf("Can't get main signature, aborting\n"); return 0;}
177 case IMAGE_DOS_SIGNATURE:
179 dh = PRD(0, sizeof(IMAGE_DOS_HEADER));
182 /* the signature is the first DWORD */
183 pdw = PRD(dh->e_lfanew, sizeof(DWORD));
186 if (*pdw == IMAGE_NT_SIGNATURE)
190 else if (*(const WORD *)pdw == IMAGE_OS2_SIGNATURE)
194 else if (*(const WORD *)pdw == IMAGE_VXD_SIGNATURE)
200 printf("No PE Signature found\n");
205 printf("Can't get the extented signature, aborting\n");
210 case 0x4944: /* "DI" */
213 case 0x444D: /* "MD" */
214 pdw = PRD(0, sizeof(DWORD));
215 if (pdw && *pdw == 0x504D444D) /* "MDMP" */
223 p = PRD(0, IMAGE_ARCHIVE_START_SIZE);
224 if (p && !strncmp(p, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
227 printf("No known main signature (%.2s/%x), aborting\n", (const char *)pw, *pw);
231 int dump_analysis(const char *name, file_dumper fn, enum FileSig wanted_sig)
234 enum FileSig effective_sig;
238 setbuf(stdout, NULL);
240 fd = open(name, O_RDONLY | O_BINARY);
241 if (fd == -1) fatal("Can't open file");
243 if (fstat(fd, &s) < 0) fatal("Can't get size");
244 dump_total_len = s.st_size;
247 if ((dump_base = mmap(NULL, dump_total_len, PROT_READ, MAP_PRIVATE, fd, 0)) == (void *)-1)
250 if (!(dump_base = malloc( dump_total_len ))) fatal( "Out of memory" );
251 if ((unsigned long)read( fd, dump_base, dump_total_len ) != dump_total_len) fatal( "Cannot read file" );
254 effective_sig = check_headers();
256 if (wanted_sig == SIG_UNKNOWN || wanted_sig == effective_sig)
258 switch (effective_sig)
260 case SIG_UNKNOWN: /* shouldn't happen... */
261 printf("Can't get a recognized file signature, aborting\n");
266 printf("Contents of \"%s\": %ld bytes\n\n", name, dump_total_len);
267 (*fn)(effective_sig, dump_base);
279 printf("Contents of \"%s\": %ld bytes\n\n", name, dump_total_len);
280 lib_dump(dump_base, dump_total_len);
286 printf("Can't get a suitable file signature, aborting\n");
290 if (ret) printf("Done dumping %s\n", name);
292 if (munmap(dump_base, dump_total_len) == -1)
302 void dump_file(const char* name)
304 dump_analysis(name, do_dump, SIG_UNKNOWN);