• R/O
  • HTTP
  • SSH
  • HTTPS

pexports: 提交

Windows DLL exported symbols listing utility


Commit MetaInfo

修订版156bd26ec5712027956cf065066980d1a48dc73c (tree)
时间2009-09-15 14:37:54
作者Charles Wilson <cwilso11@user...>
CommiterCharles Wilson

Log Message

Import Tor Lilqvist 0.44 release

更改概述

差异

--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,3 @@
11 Anders Norlander <anorland@hem2.passagen.se>
22 Paul Sokolovsky <Paul.Sokolovsky@technologist.com>
3+Tor Lillqvist <tml@iki.fi>
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
1+2008-08-31 Tor Lillqvist <tml@novell.com>
2+
3+ * hlex.l
4+ * hparse.y
5+ * pexports.h
6+ * pexports.c
7+ * str_tree.h
8+ * str_tree.c: Handle also 64-bit executables. Make it work also if
9+ built as 64-bit code. Remove all gcc -Wall warnings. Make it
10+ compilable also with MSVC. Disable Wow64 file system redirection
11+ when running as a 32-bit process on 64-bit Windows. Bump version
12+ to 0.44.
13+ * pe.h: Not needed, removed.
14+ * hparse.h: Remove generated file.
15+
116 2002-11-08 Luke Dunstan <infidel@users.sourceforge.net>
217
318 * pexports.c (dump_exports): fix exports incorrectly
--- a/Makefile.am
+++ /dev/null
@@ -1,7 +0,0 @@
1-bin_PROGRAMS = pexports
2-
3-pexports_SOURCES = hlex.l hparse.h hparse.y pe.h pexports.c pexports.h str_tree.c str_tree.h
4-
5-docdir = $(prefix)/doc/pexports
6-
7-doc_DATA = AUTHORS COPYING README
--- a/README
+++ b/README
@@ -1,4 +1,14 @@
1-PEXPORTS 0.43 README
1+PEXPORTS 0.44 README
2+============================================
3+
4+Anders Norlander <anorland@hem2.passagen.se>
5+URL: hem2.passagen.se/anorland/
6+
7+Hacked by Paul.Sokolovsky@technologist.com
8+URL: http://www.is.lg.ua/~paul/devel/binutils.html
9+
10+Hacked by Tor Lillqvist <tml@iki.fi>
11+
212 ============================================
313
414 PEXPORTS is a program to extract exported symbols from a PE image
@@ -9,8 +19,8 @@ decorated function names for functions using the stdcall calling
919 convention. GCC is used to do the preprocessing so it must be in your
1020 path.
1121
12-Note that the mingw32 version uses ';' as path separator,
13-while the cygwin version uses ':'.
22+Note that the Windows version uses ';' as path separator,
23+while if built for Cygwin it uses ':'.
1424
1525 Command line options:
1626 =====================
@@ -23,14 +33,56 @@ Header files are searched for in the following directories:
2333 1. Current directory
2434 2. Directories in C_INCLUDE_PATH
2535 3. Directories in CPLUS_INCLUDE_PATH
26-4. Directories in PATH
27-
28-NOTE: The header parser is *very* primitive, it only tries to find
29-function prototypes and check the number of arguments a function
30-expects. It is NOT a complete C parser, there are probably many
31-conditions when it will fail (especially complex parameter types),
32-although I it works fine for me. Please report bugs or send me a
33-patch.
36+
37+NOTE: The header parser is *very* primitive, and might be of
38+questionable usefulness. It only tries to find function prototypes and
39+check the number of arguments a function expects. It is NOT a complete
40+C parser, there are probably many conditions when it will fail
41+(especially complex parameter types), although I it works fine for me.
42+Please do not report bugs, but feel free to send patches.
43+
44+CHANGES FROM 0.43:
45+=================
46+
47+Handle also 64-bit executables. Make it work also if built as 64-bit
48+code. Remove all gcc -Wall warnings. Make it compilable also with
49+MSVC.Disable Wow64 file system redirection when running as a 32-bit
50+process on 64-bit Windows. Distribute just sources.
51+
52+CHANGES FROM 0.42:
53+=================
54+* There were bug which led to wrong subcategorizing of symbols as
55+code/data. I thought it was fixed in version on the site, but it turns
56+out that almost year there was wrong version. I greatly apologize to
57+everyone whom it cause problems and confusion.
58+
59+CHANGES FROM 0.41:
60+=================
61+* Data/non-data symbols are now distinguished.
62+
63+CHANGES FROM 0.4:
64+=================
65+* The header parser now accepts all kinds of parameters.
66+
67+CHANGES FROM 0.3:
68+=================
69+* Function pointer parameters are now handled
70+* Handling of function attributes improved
71+* It is no longer always necessary to include windows.h for headers
72+that required it but did not include it themselves.
73+
74+CHANGES FROM 0.2:
75+=================
76+* Completely rewritten parser (the previous one was *very* bad).
77+It is now possible to generate .DEF files for windows system
78+dlls (kernel32,user32,gdi32,shell32 etc)
79+* Enhanced symbol handling (symbols are sorted in a tree).
80+
81+CHANGES FROM 0.1:
82+=================
83+* Fixed bug with unnamed parameters that are pointers.
84+* Extra whitespace is no longer printed
85+* Binary versions available for mingw32 and cygwin32
3486
3587 Pexports, Copyright (C) 1998 Anders Norlander
3688 This program has ABSOLUTELY NO WARRANTY; This is free software, and you are
--- a/hlex.l
+++ b/hlex.l
@@ -7,28 +7,14 @@ OS [ ]*
77 #include <string.h>
88 #include "hparse.h"
99
10+static void comment(void);
1011
1112 %}
1213
1314 %%
1415 "#".* { }
1516 "//".* { }
16-"/*" {
17- char c, c1;
18-
19-loop:
20- while ((c = input()) != '*' && c != 0)
21- putchar(c);
22-
23- if ((c1 = input()) != '/' && c != 0)
24- {
25- unput(c1);
26- goto loop;
27- }
28-
29- if (c != 0)
30- putchar(c1);
31-}
17+"/*" { comment(); }
3218
3319 "__"{L}+ { return(ID); }
3420 "__"{L}+{OS}*"("+{L}({L}|{D})*")"+ { return(ID); }
@@ -48,7 +34,27 @@ loop:
4834
4935 %%
5036
51-yywrap()
37+int
38+yywrap(void)
5239 {
5340 return(1);
5441 }
42+
43+static void
44+comment(void)
45+{
46+ char c, c1;
47+
48+loop:
49+ while ((c = input()) != '*' && c != 0)
50+ putchar(c);
51+
52+ if ((c1 = input()) != '/' && c != 0)
53+ {
54+ unput(c1);
55+ goto loop;
56+ }
57+
58+ if (c != 0)
59+ putchar(c1);
60+}
--- a/hparse.h
+++ /dev/null
@@ -1,7 +0,0 @@
1-typedef union {
2- char *s;
3-} YYSTYPE;
4-#define ID 258
5-
6-
7-extern YYSTYPE yylval;
--- a/hparse.y
+++ b/hparse.y
@@ -1,4 +1,6 @@
11 %{
2+#include <string.h>
3+#include <stdio.h>
24
35 #include "pexports.h"
46
@@ -6,6 +8,10 @@
68 static int inc_flag = 1;
79 static int arg_size = 0;
810
11+extern int yylex(void);
12+
13+static void yyerror(char *s);
14+
915 #define INC_ARGS(n) arg_size += (inc_flag ? n : 0)
1016 %}
1117
@@ -75,11 +81,11 @@ parameter_declaration
7581 INC_ARGS(8);
7682 else if (strcmp($1, "RECT") == 0)
7783 INC_ARGS(16);
78- else if (strcasecmp($1, "float") == 0)
84+ else if (strcmp($1, "float") == 0)
7985 INC_ARGS(sizeof(float));
8086 else if (strcmp($1, "double") == 0)
8187 INC_ARGS(sizeof(double));
82- else if (strcasecmp($1, "void") != 0)
88+ else if (strcmp($1, "void") != 0)
8389 INC_ARGS(4);
8490 }
8591 ;
@@ -90,10 +96,8 @@ parameter_list
9096 ;
9197
9298 %%
93-#include <stdio.h>
94-
95-yyerror(s)
96-char *s;
99+static void
100+yyerror(char *s)
97101 {
98102 /* ignore error */
99103 arg_size = 0;
--- a/pe.h
+++ /dev/null
@@ -1,169 +0,0 @@
1-/* PE COFF header information */
2-
3-#ifndef _PE_H
4-#define _PE_H
5-
6-/* NT specific file attributes */
7-#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
8-#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
9-#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
10-#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
11-#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
12-#define IMAGE_FILE_32BIT_MACHINE 0x0100
13-#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
14-#define IMAGE_FILE_SYSTEM 0x1000
15-#define IMAGE_FILE_DLL 0x2000
16-#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
17-
18-/* additional flags to be set for section headers to allow the NT loader to
19- read and write to the section data (to replace the addresses of data in
20- dlls for one thing); also to execute the section in .text's case */
21-#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
22-#define IMAGE_SCN_MEM_EXECUTE 0x20000000
23-#define IMAGE_SCN_MEM_READ 0x40000000
24-#define IMAGE_SCN_MEM_WRITE 0x80000000
25-
26-/*
27- * Section characteristics added for ppc-nt
28- */
29-
30-#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */
31-
32-#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains code. */
33-#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains initialized data. */
34-#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains uninitialized data. */
35-
36-#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */
37-#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains comments or some other type of information. */
38-#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents will not become part of image. */
39-#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents comdat. */
40-
41-#define IMAGE_SCN_MEM_FARDATA 0x00008000
42-
43-#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
44-#define IMAGE_SCN_MEM_16BIT 0x00020000
45-#define IMAGE_SCN_MEM_LOCKED 0x00040000
46-#define IMAGE_SCN_MEM_PRELOAD 0x00080000
47-
48-#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
49-#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
50-#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
51-#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
52-#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment if no others are specified. */
53-#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
54-#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
55-
56-
57-#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains extended relocations. */
58-#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not cachable. */
59-#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not pageable. */
60-#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is shareable. */
61-
62-/* COMDAT selection codes. */
63-
64-#define IMAGE_COMDAT_SELECT_NODUPLICATES (1) /* Warn if duplicates. */
65-#define IMAGE_COMDAT_SELECT_ANY (2) /* No warning. */
66-#define IMAGE_COMDAT_SELECT_SAME_SIZE (3) /* Warn if different size. */
67-#define IMAGE_COMDAT_SELECT_EXACT_MATCH (4) /* Warn if different. */
68-#define IMAGE_COMDAT_SELECT_ASSOCIATIVE (5) /* Base on other section. */
69-
70-/* Magic values that are true for all dos/nt implementations */
71-#define DOSMAGIC 0x5a4d
72-#define NT_SIGNATURE 0x00004550
73-
74- /* NT allows long filenames, we want to accommodate this. This may break
75- some of the bfd functions */
76-#undef FILNMLEN
77-#define FILNMLEN 18 /* # characters in a file name */
78-
79-
80-#ifdef COFF_IMAGE_WITH_PE
81-/* The filehdr is only weired in images */
82-
83-#undef FILHDR
84-struct external_PE_filehdr
85-{
86- /* DOS header fields */
87- char e_magic[2]; /* Magic number, 0x5a4d */
88- char e_cblp[2]; /* Bytes on last page of file, 0x90 */
89- char e_cp[2]; /* Pages in file, 0x3 */
90- char e_crlc[2]; /* Relocations, 0x0 */
91- char e_cparhdr[2]; /* Size of header in paragraphs, 0x4 */
92- char e_minalloc[2]; /* Minimum extra paragraphs needed, 0x0 */
93- char e_maxalloc[2]; /* Maximum extra paragraphs needed, 0xFFFF */
94- char e_ss[2]; /* Initial (relative) SS value, 0x0 */
95- char e_sp[2]; /* Initial SP value, 0xb8 */
96- char e_csum[2]; /* Checksum, 0x0 */
97- char e_ip[2]; /* Initial IP value, 0x0 */
98- char e_cs[2]; /* Initial (relative) CS value, 0x0 */
99- char e_lfarlc[2]; /* File address of relocation table, 0x40 */
100- char e_ovno[2]; /* Overlay number, 0x0 */
101- char e_res[4][2]; /* Reserved words, all 0x0 */
102- char e_oemid[2]; /* OEM identifier (for e_oeminfo), 0x0 */
103- char e_oeminfo[2]; /* OEM information; e_oemid specific, 0x0 */
104- char e_res2[10][2]; /* Reserved words, all 0x0 */
105- char e_lfanew[4]; /* File address of new exe header, 0x80 */
106- char dos_message[16][4]; /* other stuff, always follow DOS header */
107- char nt_signature[4]; /* required NT signature, 0x4550 */
108-
109- /* From standard header */
110-
111-
112- char f_magic[2]; /* magic number */
113- char f_nscns[2]; /* number of sections */
114- char f_timdat[4]; /* time & date stamp */
115- char f_symptr[4]; /* file pointer to symtab */
116- char f_nsyms[4]; /* number of symtab entries */
117- char f_opthdr[2]; /* sizeof(optional hdr) */
118- char f_flags[2]; /* flags */
119-
120-};
121-
122-
123-#define FILHDR struct external_PE_filehdr
124-#undef FILHSZ
125-#define FILHSZ 152
126-
127-#endif
128-
129-typedef struct
130-{
131- AOUTHDR standard;
132-
133- /* NT extra fields; see internal.h for descriptions */
134- char ImageBase[4];
135- char SectionAlignment[4];
136- char FileAlignment[4];
137- char MajorOperatingSystemVersion[2];
138- char MinorOperatingSystemVersion[2];
139- char MajorImageVersion[2];
140- char MinorImageVersion[2];
141- char MajorSubsystemVersion[2];
142- char MinorSubsystemVersion[2];
143- char Reserved1[4];
144- char SizeOfImage[4];
145- char SizeOfHeaders[4];
146- char CheckSum[4];
147- char Subsystem[2];
148- char DllCharacteristics[2];
149- char SizeOfStackReserve[4];
150- char SizeOfStackCommit[4];
151- char SizeOfHeapReserve[4];
152- char SizeOfHeapCommit[4];
153- char LoaderFlags[4];
154- char NumberOfRvaAndSizes[4];
155- /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
156- char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
157-
158-} PEAOUTHDR;
159-
160-
161-#undef AOUTSZ
162-#define AOUTSZ (AOUTHDRSZ + 196)
163-
164-#undef E_FILNMLEN
165-#define E_FILNMLEN 18 /* # characters in a file name */
166-#endif
167-
168-
169-
--- a/pexports.c
+++ b/pexports.c
@@ -1,6 +1,5 @@
11 #include <string.h>
22 #include <stdlib.h>
3-#include <unistd.h>
43 #include <errno.h>
54 #include <sys/stat.h>
65
@@ -11,17 +10,16 @@
1110 #define PATH_MAX 260
1211 #endif
1312
14-#ifdef __MINGW32__
15-/* mingw32 uses ';' instead if ':' */
13+#ifdef _WIN32
1614 #define PATH_SEPARATOR ';'
1715 #else
1816 #define PATH_SEPARATOR ':'
1917 #endif
2018
2119 /* get pointer to section header n */
22-#define IMAGE_SECTION_HDR(n) ((PIMAGE_SECTION_HEADER) ((DWORD) nt_hdr + \
20+#define IMAGE_SECTION_HDR(n) ((PIMAGE_SECTION_HEADER) ((char *) nt_hdr32 + \
2321 4 + sizeof(IMAGE_FILE_HEADER) + \
24- nt_hdr->FileHeader.SizeOfOptionalHeader + \
22+ nt_hdr32->FileHeader.SizeOfOptionalHeader + \
2523 n * sizeof(IMAGE_SECTION_HEADER)))
2624
2725 /* convert relative virtual address to a useable pointer */
@@ -32,32 +30,33 @@ typedef struct str_list {
3230 struct str_list *next;
3331 } str_list;
3432
33+extern void yyparse(void);
34+
3535 static void *xmalloc(size_t count);
36-static void cleanup(void);
3736 static void add_path_list(char *path);
3837 static const char *find_file(const char *name);
3938 static void str_list_add(str_list **head, const char *s);
40-static void str_list_free(str_list **head);
4139 static void parse_headers();
4240 static void dump_symbol(char *name, int ord, DWORD rva);
4341
44-const char mz_sign[2] = {'M','Z'};
45-const char pe_sign[4] = {'P','E','\0','\0'};
46-const char exp_sign[6] = {'.','e','d','a','t','a'};
42+static const char mz_sign[2] = {'M','Z'};
43+static const char pe_sign[4] = {'P','E','\0','\0'};
44+static const char exp_sign[6] = {'.','e','d','a','t','a'};
4745
48-PIMAGE_DOS_HEADER dos_hdr;
49-PIMAGE_NT_HEADERS nt_hdr;
46+static PIMAGE_DOS_HEADER dos_hdr;
47+static PIMAGE_NT_HEADERS32 nt_hdr32;
48+static PIMAGE_NT_HEADERS64 nt_hdr64;
5049
51-char *filename = NULL;
52-char *program_name;
53-char *cpp = "gcc -E -xc-header";
50+static char *filename = NULL;
51+static char *program_name;
52+static char *cpp = "gcc -E -xc-header";
5453
5554 str_tree *symbols = NULL;
56-str_list *inc_path = NULL;
57-str_list *header_files = NULL;
55+static str_list *inc_path = NULL;
56+static str_list *header_files = NULL;
5857
59-int verbose = 0;
60-int ordinal_flag = 0;
58+static int verbose = 0;
59+static int ordinal_flag = 0;
6160
6261 extern FILE *yyin;
6362
@@ -67,15 +66,38 @@ main(int argc, char *argv[])
6766 PIMAGE_SECTION_HEADER section;
6867 DWORD exp_rva;
6968 int i;
69+#if defined(_WIN32) && !defined(_WIN64)
7070
71- program_name = argv[0];
71+ /* If running on 64-bit Windows and built as a 32-bit process, try
72+ * disable Wow64 file system redirection, so that we can open DLLs
73+ * in the real system32 folder if requested.
74+ */
75+
76+ PVOID old_redirection;
77+
78+ HMODULE kernel32;
79+
80+ extern __declspec(dllimport) HMODULE __stdcall GetModuleHandleA(char *name);
81+ extern __declspec(dllimport) PVOID __stdcall GetProcAddress(HMODULE module, char *name);
82+
83+ BOOL (__stdcall *pWow64DisableWow64FsRedirection) (PVOID *old_value);
7284
73- atexit(cleanup);
85+ kernel32 = GetModuleHandleA("kernel32.dll");
86+ pWow64DisableWow64FsRedirection = GetProcAddress(kernel32, "Wow64DisableWow64FsRedirection");
87+
88+ if (pWow64DisableWow64FsRedirection)
89+ pWow64DisableWow64FsRedirection(&old_redirection);
90+#endif
91+
92+ program_name = argv[0];
7493
7594 /* add standard include paths */
7695 add_path_list(getenv("C_INCLUDE_PATH"));
7796 add_path_list(getenv("CPLUS_INCLUDE_PATH"));
97+#if 0
98+ /* since when does PATH have anything to do with headers? */
7899 add_path_list(getenv("PATH"));
100+#endif
79101
80102 /* parse command line */
81103 for ( i = 1; i < argc; i++ )
@@ -120,6 +142,7 @@ main(int argc, char *argv[])
120142 {
121143 printf("PExports %d.%d Copyright 1998, Anders Norlander\n"
122144 "Changed 1999, Paul Sokolovsky\n"
145+ "Changed 2008, Tor Lillqvist\n"
123146 "This program is free software; you may redistribute it under the terms of\n"
124147 "the GNU General Public License. This program has absolutely no warranty.\n"
125148
@@ -128,7 +151,9 @@ main(int argc, char *argv[])
128151 " -o\tprint ordinals\n"
129152 " -p\tset preprocessor program\n"
130153 " -v\tverbose mode\n"
131- "\nReport bugs to anorland@hem2.passagen.se or Paul.Sokolovsky@technologist.com\n",
154+ "\nReport bugs to anorland@hem2.passagen.se,\n"
155+ "Paul.Sokolovsky@technologist.com\n"
156+ "or tml@iki.fi\n",
132157 VER_MAJOR, VER_MINOR,
133158 program_name);
134159 return 1;
@@ -146,22 +171,30 @@ main(int argc, char *argv[])
146171 return 1;
147172 }
148173
149- nt_hdr = (PIMAGE_NT_HEADERS) ((DWORD) dos_hdr + dos_hdr->e_lfanew);
174+ nt_hdr32 = (PIMAGE_NT_HEADERS32) ((char *) dos_hdr + dos_hdr->e_lfanew);
175+ nt_hdr64 = (PIMAGE_NT_HEADERS64) nt_hdr32;
150176
151- exp_rva = nt_hdr->OptionalHeader.DataDirectory[0].VirtualAddress;
152-
153- section = IMAGE_SECTION_HDR(0);
177+ if (nt_hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
178+ exp_rva = nt_hdr32->OptionalHeader.DataDirectory[0].VirtualAddress;
179+ else
180+ exp_rva = nt_hdr64->OptionalHeader.DataDirectory[0].VirtualAddress;
154181
155- /* Look for export section */
156- for (i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++, section++)
182+ if (verbose)
157183 {
158- if (verbose)
184+ for (i = 0; i < nt_hdr32->FileHeader.NumberOfSections; i++)
159185 {
160- printf("; %8s: RVA: %08x, File offset: %08x\n",
186+ section = IMAGE_SECTION_HDR(i);
187+ printf("; %-8.8s: RVA: %08x, File offset: %08x\n",
161188 section->Name,
162189 section->VirtualAddress,
163190 section->PointerToRawData);
164191 }
192+ }
193+
194+ /* Look for export section */
195+ for (i = 0; i < nt_hdr32->FileHeader.NumberOfSections; i++)
196+ {
197+ section = IMAGE_SECTION_HDR(i);
165198 if (memcmp(section->Name, exp_sign, sizeof(exp_sign)) == 0)
166199 dump_exports(section->VirtualAddress);
167200 else if ((exp_rva >= section->VirtualAddress) &&
@@ -180,20 +213,14 @@ dump_exports(DWORD exports_rva)
180213 PIMAGE_SECTION_HEADER section;
181214 PIMAGE_EXPORT_DIRECTORY exports;
182215 char *export_name;
183- PWORD ordinal_table;
184- char **name_table;
216+ WORD *ordinal_table;
217+ DWORD *name_table;
185218 DWORD *function_table;
186219 int i;
187220 static int first = 1;
188- DWORD exports_end;
189221
190222 section = find_section(exports_rva);
191223
192- if (nt_hdr->OptionalHeader.DataDirectory[0].Size == 0)
193- exports_end = section->VirtualAddress + section->SizeOfRawData;
194- else
195- exports_end = exports_rva + nt_hdr->OptionalHeader.DataDirectory[0].Size;
196-
197224 if (verbose)
198225 printf("; Reading exports from section: %s\n",
199226 section->Name);
@@ -202,8 +229,8 @@ dump_exports(DWORD exports_rva)
202229
203230 /* set up various pointers */
204231 export_name = RVA_TO_PTR(exports->Name,char*);
205- ordinal_table = RVA_TO_PTR(exports->AddressOfNameOrdinals,PWORD);
206- name_table = RVA_TO_PTR(exports->AddressOfNames,char**);
232+ ordinal_table = RVA_TO_PTR(exports->AddressOfNameOrdinals,WORD*);
233+ name_table = RVA_TO_PTR(exports->AddressOfNames,DWORD*);
207234 function_table = RVA_TO_PTR(exports->AddressOfFunctions,void*);
208235
209236 if (verbose)
@@ -212,7 +239,8 @@ dump_exports(DWORD exports_rva)
212239 printf("; Ordinal base: %d\n", exports->Base);
213240 printf("; Ordinal table RVA: %08x\n",
214241 exports->AddressOfNameOrdinals);
215- printf("; Name table RVA: %08x\n", exports->AddressOfNames);
242+ printf("; Name table RVA: %07x\n",
243+ exports->AddressOfNames);
216244 printf("; Export address table RVA: %08x\n",
217245 exports->AddressOfFunctions);
218246 }
@@ -237,7 +265,7 @@ dump_exports(DWORD exports_rva)
237265 for (i = 0; i < exports->NumberOfFunctions; i++)
238266 {
239267 if ( (function_table[i] >= exports_rva) &&
240- (function_table[i] < exports_end))
268+ (function_table[i] <= (section->VirtualAddress + section->SizeOfRawData)))
241269 {
242270 dump_symbol(strchr(RVA_TO_PTR(function_table[i],char*), '.')+1,
243271 i + exports->Base,
@@ -250,13 +278,14 @@ dump_exports(DWORD exports_rva)
250278 }
251279 }
252280
253-static void dump_symbol(char *name, int ord, DWORD rva)
281+static void
282+dump_symbol(char *name, int ord, DWORD rva)
254283 {
255284 char s[256];
256285 str_tree *symbol = str_tree_find(symbols, name);
257286 /* if a symbol was found, emit size of stack */
258287 if (symbol)
259- sprintf(s, "%s@%d", name, (int) symbol->extra);
288+ sprintf(s, "%s@%"INT_PTR_FORMAT, name, (INT_PTR) symbol->extra);
260289 else
261290 sprintf(s, "%s", name);
262291
@@ -269,8 +298,9 @@ static void dump_symbol(char *name, int ord, DWORD rva)
269298 {
270299 PIMAGE_SECTION_HEADER s=find_section(rva);
271300
272-/* Stupid msvc doesn't have .bss section, it spews uninitilized data
273- to no section */
301+ /* Stupid msvc doesn't have .bss section, it spews uninitilized data
302+ * to no section
303+ */
274304 if (!s) { printf(" DATA"); if (verbose) printf (" ; no section"); }
275305 else
276306 {
@@ -289,7 +319,7 @@ find_section(DWORD rva)
289319 {
290320 int i;
291321 PIMAGE_SECTION_HEADER section = IMAGE_SECTION_HDR(0);
292- for (i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++, section++)
322+ for (i = 0; i < nt_hdr32->FileHeader.NumberOfSections; i++, section++)
293323 if ((rva >= section->VirtualAddress) &&
294324 (rva <= (section->VirtualAddress + section->SizeOfRawData)))
295325 return section;
@@ -297,48 +327,60 @@ find_section(DWORD rva)
297327 }
298328
299329 /* convert rva to pointer into loaded file */
300-DWORD
330+void *
301331 rva_to_ptr(DWORD rva)
302332 {
303333 PIMAGE_SECTION_HEADER section = find_section(rva);
304334 if (section->PointerToRawData == 0)
305- return 0;
335+ return NULL;
306336 else
307- return ((DWORD) dos_hdr + (DWORD) rva - (section->VirtualAddress - section->PointerToRawData));
337+ return ((char *) dos_hdr + rva - (section->VirtualAddress - section->PointerToRawData));
308338 }
309339
310340 /* Load a portable executable into memory */
311341 PIMAGE_DOS_HEADER
312342 load_pe_image(const char *filename)
313343 {
344+#ifdef _MSC_VER
345+ struct _stat32 st;
346+#else
314347 struct stat st;
348+#endif
315349 PIMAGE_DOS_HEADER phdr;
316350 FILE *f;
317-
351+
318352 if (stat(filename, &st) == -1)
319- return NULL;
353+ {
354+ perror("stat");
355+ return NULL;
356+ }
320357
321358 phdr = (PIMAGE_DOS_HEADER) xmalloc(st.st_size);
322359
323360 f = fopen(filename, "rb");
361+
324362 if (f == NULL)
325363 {
364+ perror("fopen");
326365 free(phdr);
327366 return NULL;
328367 }
329368
330369 if (fread(phdr, st.st_size, 1, f) != 1)
331370 {
371+ perror("fread");
332372 free(phdr);
333373 phdr = NULL;
334374 }
335375 else if (memcmp(mz_sign, phdr, sizeof(mz_sign)) != 0)
336376 {
377+ fprintf(stderr, "No MZ signature\n");
337378 free(phdr);
338379 phdr = NULL;
339380 }
340381 else if (memcmp((char *) phdr + phdr->e_lfanew, pe_sign, sizeof(pe_sign)) != 0)
341382 {
383+ fprintf(stderr, "No PE signature\n");
342384 free(phdr);
343385 phdr = NULL;
344386 }
@@ -351,6 +393,11 @@ load_pe_image(const char *filename)
351393 void
352394 parse_headers()
353395 {
396+#ifdef _MSC_VER
397+#define popen _popen
398+#define pclose _pclose
399+#endif
400+
354401 str_list *header;
355402 char *cpp_cmd;
356403 int len;
@@ -417,7 +464,8 @@ parse_headers()
417464 }
418465
419466 /* allocate memory; abort on failure */
420-static void *xmalloc(size_t count)
467+static void
468+*xmalloc(size_t count)
421469 {
422470 void *p = malloc(count);
423471 if (p == NULL)
@@ -428,16 +476,9 @@ static void *xmalloc(size_t count)
428476 return p;
429477 }
430478
431-/* clean up */
432-static void cleanup(void)
433-{
434- str_tree_free(&symbols);
435- str_list_free(&inc_path);
436- str_list_free(&header_files);
437-}
438-
439479 /* add string to end of list */
440-static void str_list_add(str_list **head, const char *s)
480+static void
481+str_list_add(str_list **head, const char *s)
441482 {
442483 str_list *node = xmalloc(sizeof(str_list));
443484 node->s = strdup(s);
@@ -455,22 +496,9 @@ static void str_list_add(str_list **head, const char *s)
455496 }
456497 }
457498
458-/* free memory used by string list */
459-static void str_list_free(str_list **head)
460-{
461- str_list *node = *head;
462- while (node)
463- {
464- str_list *tmp = node->next;
465- free(node->s);
466- free(node);
467- node = tmp;
468- }
469- *head = NULL;
470-}
471-
472499 /* find a file in include path */
473-static const char *find_file(const char *name)
500+static const char *
501+find_file(const char *name)
474502 {
475503 static char fullname[PATH_MAX];
476504 FILE *f = fopen(name, "r");
@@ -498,7 +526,8 @@ static const char *find_file(const char *name)
498526 }
499527
500528 /* add a environment-style path list to list of include paths */
501-static void add_path_list(char *path)
529+static void
530+add_path_list(char *path)
502531 {
503532 char *p = path;
504533 if (!p)
--- a/pexports.h
+++ b/pexports.h
@@ -18,15 +18,27 @@
1818 #include "str_tree.h"
1919
2020 #define VER_MAJOR 0
21-#define VER_MINOR 43
21+#define VER_MINOR 44
2222
2323 /* These are needed */
2424 typedef unsigned short WORD;
2525 typedef unsigned int DWORD;
2626 typedef unsigned char BYTE;
27+typedef void* PVOID;
2728 typedef long LONG;
28-typedef WORD *PWORD;
29-typedef DWORD *PDWORD;
29+typedef unsigned __int64 ULONGLONG;
30+typedef int BOOL;
31+typedef void* HMODULE;
32+#ifdef _WIN64
33+typedef __int64 INT_PTR;
34+#define INT_PTR_FORMAT "I64d"
35+#else
36+typedef int INT_PTR;
37+#define INT_PTR_FORMAT "d"
38+#endif
39+
40+#define FALSE 0
41+#define TRUE 1
3042
3143 /* PE structures */
3244 typedef struct _IMAGE_DATA_DIRECTORY {
@@ -44,7 +56,11 @@ typedef struct _IMAGE_FILE_HEADER {
4456 WORD Characteristics;
4557 } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
4658
47-typedef struct _IMAGE_OPTIONAL_HEADER {
59+#define IMAGE_FILE_MACHINE_I386 0x014c
60+#define IMAGE_FILE_MACHINE_IA64 0x0200
61+#define IMAGE_FILE_MACHINE_AMD64 0x8664
62+
63+typedef struct _IMAGE_OPTIONAL_HEADER32 {
4864 WORD Magic;
4965 BYTE MajorLinkerVersion;
5066 BYTE MinorLinkerVersion;
@@ -54,7 +70,6 @@ typedef struct _IMAGE_OPTIONAL_HEADER {
5470 DWORD AddressOfEntryPoint;
5571 DWORD BaseOfCode;
5672 DWORD BaseOfData;
57-
5873 DWORD ImageBase;
5974 DWORD SectionAlignment;
6075 DWORD FileAlignment;
@@ -77,14 +92,52 @@ typedef struct _IMAGE_OPTIONAL_HEADER {
7792 DWORD LoaderFlags;
7893 DWORD NumberOfRvaAndSizes;
7994 IMAGE_DATA_DIRECTORY DataDirectory[16];
80-} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
95+} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
8196
97+typedef struct _IMAGE_OPTIONAL_HEADER64 {
98+ WORD Magic;
99+ BYTE MajorLinkerVersion;
100+ BYTE MinorLinkerVersion;
101+ DWORD SizeOfCode;
102+ DWORD SizeOfInitializedData;
103+ DWORD SizeOfUninitializedData;
104+ DWORD AddressOfEntryPoint;
105+ DWORD BaseOfCode;
106+ ULONGLONG ImageBase;
107+ DWORD SectionAlignment;
108+ DWORD FileAlignment;
109+ WORD MajorOperatingSystemVersion;
110+ WORD MinorOperatingSystemVersion;
111+ WORD MajorImageVersion;
112+ WORD MinorImageVersion;
113+ WORD MajorSubsystemVersion;
114+ WORD MinorSubsystemVersion;
115+ DWORD Win32VersionValue;
116+ DWORD SizeOfImage;
117+ DWORD SizeOfHeaders;
118+ DWORD CheckSum;
119+ WORD Subsystem;
120+ WORD DllCharacteristics;
121+ ULONGLONG SizeOfStackReserve;
122+ ULONGLONG SizeOfStackCommit;
123+ ULONGLONG SizeOfHeapReserve;
124+ ULONGLONG SizeOfHeapCommit;
125+ DWORD LoaderFlags;
126+ DWORD NumberOfRvaAndSizes;
127+ IMAGE_DATA_DIRECTORY DataDirectory[16];
128+} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
129+
130+typedef struct IMAGE_NT_HEADERS32 {
131+ char Signature[4];
132+ IMAGE_FILE_HEADER FileHeader;
133+ IMAGE_OPTIONAL_HEADER32 OptionalHeader;
134+} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
82135
83-typedef struct _IMAGE_NT_HEADERS {
136+typedef struct _IMAGE_NT_HEADERS64 {
84137 char Signature[4];
85138 IMAGE_FILE_HEADER FileHeader;
86- IMAGE_OPTIONAL_HEADER OptionalHeader;
87-} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
139+ IMAGE_OPTIONAL_HEADER64 OptionalHeader;
140+} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
88141
89142 typedef struct _IMAGE_SECTION_HEADER {
90143 BYTE Name[8];
@@ -102,6 +155,8 @@ typedef struct _IMAGE_SECTION_HEADER {
102155 DWORD Characteristics;
103156 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
104157
158+#define IMAGE_SCN_CNT_CODE 0x00000020
159+
105160 typedef struct _IMAGE_EXPORT_DIRECTORY {
106161 DWORD Characteristics;
107162 DWORD TimeDateStamp;
@@ -111,9 +166,9 @@ typedef struct _IMAGE_EXPORT_DIRECTORY {
111166 DWORD Base;
112167 DWORD NumberOfFunctions;
113168 DWORD NumberOfNames;
114- PDWORD *AddressOfFunctions;
115- PDWORD *AddressOfNames;
116- PWORD *AddressOfNameOrdinals;
169+ DWORD AddressOfFunctions;
170+ DWORD AddressOfNames;
171+ DWORD AddressOfNameOrdinals;
117172 } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
118173
119174 typedef struct _IMAGE_DOS_HEADER {
@@ -144,20 +199,13 @@ find_section(DWORD rva);
144199 PIMAGE_DOS_HEADER
145200 load_pe_image(const char *filename);
146201
147-DWORD
202+void *
148203 rva_to_ptr(DWORD rva);
149204
150205 void
151206 dump_exports(DWORD exports_rva);
152207
153-#define ADD_FUNCTION(nm,n) str_tree_add(&symbols, nm, (void*)n)
208+#define ADD_FUNCTION(nm,n) str_tree_add(&symbols, nm, (void*)(INT_PTR)n)
154209 extern str_tree *symbols;
155210
156-/* pe.h from bfd */
157-
158-/* dirty! */
159-#define AOUTHDR int
160-
161-#include "pe.h"
162-
163211 #endif /* _pexports_h */
--- a/str_tree.c
+++ b/str_tree.c
@@ -1,8 +1,10 @@
11 #include <string.h>
2+#include <stdlib.h>
23
34 #include "str_tree.h"
45
5-static str_tree *new_leaf(const char *s, void *extra)
6+static str_tree *
7+new_leaf(const char *s, void *extra)
68 {
79 str_tree *leaf;
810 leaf = (str_tree *) malloc(sizeof(str_tree));
@@ -18,7 +20,9 @@ static str_tree *new_leaf(const char *s, void *extra)
1820 leaf->left = leaf->right = NULL;
1921 return leaf;
2022 }
21-str_tree *str_tree_add(str_tree **root, const char *s, void *extra)
23+
24+str_tree *
25+str_tree_add(str_tree **root, const char *s, void *extra)
2226 {
2327 if (!*root)
2428 return (*root = new_leaf(s, extra));
@@ -28,7 +32,8 @@ str_tree *str_tree_add(str_tree **root, const char *s, void *extra)
2832 return str_tree_add(&(*root)->right, s, extra);
2933 }
3034
31-str_tree *str_tree_find(str_tree *node, const char *s)
35+str_tree *
36+str_tree_find(str_tree *node, const char *s)
3237 {
3338 if (node == NULL)
3439 return NULL;
@@ -39,26 +44,3 @@ str_tree *str_tree_find(str_tree *node, const char *s)
3944 else
4045 return str_tree_find(node->right, s);
4146 }
42-
43-void str_tree_free(str_tree **root)
44-{
45- if (*root)
46- {
47- str_tree *node = *root;
48- free(node->s);
49- str_tree_free(&node->left);
50- str_tree_free(&node->right);
51- free(node);
52- *root = NULL;
53- }
54-}
55-
56-int str_tree_traverse(str_tree *root,int(*f)(str_tree *node))
57-{
58- if (root == NULL) return 1;
59-
60- if (!str_tree_traverse(root->left,f) ||
61- !f(root) ||
62- !str_tree_traverse(root->right,f)) return 0;
63- return 1;
64-}
--- a/str_tree.h
+++ b/str_tree.h
@@ -9,7 +9,5 @@ typedef struct str_tree {
99
1010 str_tree *str_tree_add(str_tree **root, const char *s, void *extra);
1111 str_tree *str_tree_find(str_tree *node, const char *s);
12-void str_tree_free(str_tree **root);
13-int str_tree_traverse(str_tree *root,int(*f)(str_tree *node));
1412
1513 #endif /* _str_tree */
Show on old repository browser