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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
53 static void* dump_base
;
54 static unsigned long dump_total_len
;
56 void dump_data( const unsigned char *ptr
, unsigned int size
, const char *prefix
)
60 printf( "%s%08x: ", prefix
, 0 );
66 for (i
= 0; i
< size
; i
++)
68 printf( "%02x%c", ptr
[i
], (i
% 16 == 7) ? '-' : ' ' );
72 for (j
= 0; j
< 16; j
++)
73 printf( "%c", isprint(ptr
[i
-15+j
]) ? ptr
[i
-15+j
] : '.' );
74 if (i
< size
-1) printf( "\n%s%08x: ", prefix
, i
+ 1 );
79 printf( "%*s ", 3 * (16-(i
%16)), "" );
80 for (j
= 0; j
< i
% 16; j
++)
81 printf( "%c", isprint(ptr
[i
-(i
%16)+j
]) ? ptr
[i
-(i
%16)+j
] : '.' );
86 const char* get_time_str(DWORD _t
)
88 time_t t
= (time_t)_t
;
89 const char *str
= ctime(&t
);
90 size_t len
= strlen(str
);
92 /* FIXME: I don't get the same values from MS' pedump running under Wine...
93 * I wonder if Wine isn't broken wrt to GMT settings...
95 if (len
&& str
[len
-1] == '\n') len
--;
96 if (len
>= sizeof(buf
)) len
= sizeof(buf
) - 1;
97 memcpy( buf
, str
, len
);
102 unsigned int strlenW( const WCHAR
*str
)
104 const WCHAR
*s
= str
;
109 void dump_unicode_str( const WCHAR
*str
, int len
)
111 if (len
== -1) len
= strlenW( str
);
113 while (len
-- > 0 && *str
)
118 case '\n': printf( "\\n" ); break;
119 case '\r': printf( "\\r" ); break;
120 case '\t': printf( "\\t" ); break;
121 case '"': printf( "\\\"" ); break;
122 case '\\': printf( "\\\\" ); break;
124 if (c
>= ' ' && c
<= 126) putchar(c
);
125 else printf( "\\u%04x",c
);
131 void* PRD(unsigned long prd
, unsigned long len
)
133 return (prd
+ len
> dump_total_len
) ? NULL
: (char*)dump_base
+ prd
;
136 unsigned long Offset(void* ptr
)
138 if (ptr
< dump_base
) {printf("<<<<<ptr below\n");return 0;}
139 if ((char *)ptr
>= (char*)dump_base
+ dump_total_len
) {printf("<<<<<ptr above\n");return 0;}
140 return (char*)ptr
- (char*)dump_base
;
143 static void do_dump( enum FileSig sig
, void* pmt
)
147 ne_dump( dump_base
, dump_total_len
);
153 le_dump( dump_base
, dump_total_len
);
160 static enum FileSig
check_headers(void** pmt
)
164 IMAGE_DOS_HEADER
* dh
;
167 pw
= PRD(0, sizeof(WORD
));
168 if (!pw
) {printf("Can't get main signature, aborting\n"); return 0;}
173 case IMAGE_DOS_SIGNATURE
:
175 dh
= PRD(0, sizeof(IMAGE_DOS_HEADER
));
176 if (dh
&& dh
->e_lfanew
>= sizeof(*dh
)) /* reasonable DOS header ? */
178 /* the signature is the first DWORD */
179 pdw
= PRD(dh
->e_lfanew
, sizeof(DWORD
));
182 if (*pdw
== IMAGE_NT_SIGNATURE
)
184 *pmt
= PRD(dh
->e_lfanew
, sizeof(DWORD
)+sizeof(IMAGE_FILE_HEADER
));
187 else if (*(WORD
*)pdw
== IMAGE_OS2_SIGNATURE
)
191 else if (*(WORD
*)pdw
== IMAGE_VXD_SIGNATURE
)
197 printf("No PE Signature found\n");
202 printf("Can't get the extented signature, aborting\n");
206 case 0x4944: /* "DI" */
209 case 0x444D: /* "MD" */
210 pdw
= PRD(0, sizeof(DWORD
));
211 if (pdw
&& *pdw
== 0x504D444D) /* "MDMP" */
217 printf("No known main signature (%.2s/%x), aborting\n", (char*)pw
, *pw
);
224 int dump_analysis(const char* name
, void (*fn
)(enum FileSig
, void*), enum FileSig wanted_sig
)
227 enum FileSig effective_sig
;
232 setbuf(stdout
, NULL
);
234 fd
= open(name
, O_RDONLY
| O_BINARY
);
235 if (fd
== -1) fatal("Can't open file");
237 if (fstat(fd
, &s
) < 0) fatal("Can't get size");
238 dump_total_len
= s
.st_size
;
241 if ((dump_base
= mmap(NULL
, dump_total_len
, PROT_READ
, MAP_PRIVATE
, fd
, 0)) == (void *)-1)
244 if (!(dump_base
= malloc( dump_total_len
))) fatal( "Out of memory" );
245 if ((unsigned long)read( fd
, dump_base
, dump_total_len
) != dump_total_len
) fatal( "Cannot read file" );
248 effective_sig
= check_headers(&pmt
);
250 if (effective_sig
== SIG_UNKNOWN
)
252 printf("Can't get a recognized file signature, aborting\n");
255 else if (wanted_sig
== SIG_UNKNOWN
|| wanted_sig
== effective_sig
)
257 switch (effective_sig
)
259 case SIG_UNKNOWN
: /* shouldn't happen... */
264 printf("Contents of \"%s\": %ld bytes\n\n", name
, dump_total_len
);
265 (*fn
)(effective_sig
, pmt
);
279 printf("Can't get a suitable file signature, aborting\n");
283 if (ret
) printf("Done dumping %s\n", name
);
285 if (munmap(dump_base
, dump_total_len
) == -1)
295 void dump_file(const char* name
)
297 dump_analysis(name
, do_dump
, SIG_UNKNOWN
);