#include <string.h>
#include <stdlib.h>
-#include <errno.h>
+#include <inttypes.h>
#include <sys/stat.h>
+#include <errno.h>
#include "str_tree.h"
#include "pexports.h"
#endif
/* get pointer to section header n */
-#define IMAGE_SECTION_HDR(n) ((PIMAGE_SECTION_HEADER) ((char *) nt_hdr32 + \
- 4 + sizeof(IMAGE_FILE_HEADER) + \
- nt_hdr32->FileHeader.SizeOfOptionalHeader + \
- n * sizeof(IMAGE_SECTION_HEADER)))
+#define IMAGE_SECTION_HDR(n) \
+ ((IMAGE_SECTION_HEADER *)((char *) nt_hdr32 \
+ + 4 + sizeof(IMAGE_FILE_HEADER) + nt_hdr32->FileHeader.SizeOfOptionalHeader \
+ + n * sizeof(IMAGE_SECTION_HEADER)) \
+ )
/* convert relative virtual address to a useable pointer */
-#define RVA_TO_PTR(rva,type) ((type) rva_to_ptr((DWORD) rva))
+#define RVA_TO_PTR(rva,type) ((type)(rva_to_ptr((uint32_t)(rva))))
typedef struct str_list {
char *s;
static const char *find_file(const char *name);
static void str_list_add(str_list **head, const char *s);
static void parse_headers();
-static void dump_symbol(char *name, int ord, DWORD rva);
+static void dump_symbol(char *name, int ord, uint32_t rva);
static const char mz_sign[2] = {'M','Z'};
static const char pe_sign[4] = {'P','E','\0','\0'};
static const char exp_sign[6] = {'.','e','d','a','t','a'};
-static PIMAGE_DOS_HEADER dos_hdr;
-static PIMAGE_NT_HEADERS32 nt_hdr32;
-static PIMAGE_NT_HEADERS64 nt_hdr64;
+static IMAGE_DOS_HEADER *dos_hdr;
+static IMAGE_NT_HEADERS32 *nt_hdr32;
+static IMAGE_NT_HEADERS64 *nt_hdr64;
static char *filename = NULL;
static char *program_name;
int
main(int argc, char *argv[])
{
- PIMAGE_SECTION_HEADER section;
- DWORD exp_rva;
+ IMAGE_SECTION_HEADER *section;
+ uint32_t exp_rva, exp_size;
int i;
-#if defined(_WIN32) && !defined(_WIN64)
- /* If running on 64-bit Windows and built as a 32-bit process, try
+# if defined(_WIN32) && !defined(_WIN64)
+ /*
+ * If running on 64-bit Windows and built as a 32-bit process, try
* disable Wow64 file system redirection, so that we can open DLLs
* in the real system32 folder if requested.
*/
+ void *old_redirection;
+ void *kernel32;
- PVOID old_redirection;
-
- HMODULE kernel32;
+ extern __declspec(dllimport) void __stdcall *GetModuleHandleA(char *name);
+ extern __declspec(dllimport) void __stdcall *GetProcAddress(void *module, char *name);
- extern __declspec(dllimport) HMODULE __stdcall GetModuleHandleA(char *name);
- extern __declspec(dllimport) PVOID __stdcall GetProcAddress(HMODULE module, char *name);
-
- BOOL (__stdcall *pWow64DisableWow64FsRedirection) (PVOID *old_value);
+ int32_t (__stdcall *pWow64DisableWow64FsRedirection) (void **old_value);
kernel32 = GetModuleHandleA("kernel32.dll");
pWow64DisableWow64FsRedirection = GetProcAddress(kernel32, "Wow64DisableWow64FsRedirection");
if (pWow64DisableWow64FsRedirection)
pWow64DisableWow64FsRedirection(&old_redirection);
-#endif
+# endif
program_name = argv[0];
if (filename == NULL)
{
- printf("PExports %d.%d Copyright 1998, Anders Norlander\n"
- "Changed 1999, Paul Sokolovsky\n"
- "Changed 2008, Tor Lillqvist\n"
- "This program is free software; you may redistribute it under the terms of\n"
- "the GNU General Public License. This program has absolutely no warranty.\n"
-
- "\nUsage: %s [-v] [-o] [-h header] [-p preprocessor] dll\n"
- " -h\tparse header\n"
- " -o\tprint ordinals\n"
- " -p\tset preprocessor program\n"
- " -v\tverbose mode\n"
- "\nReport bugs to anorland@hem2.passagen.se,\n"
- "Paul.Sokolovsky@technologist.com\n"
- "or tml@iki.fi\n",
- VER_MAJOR, VER_MINOR,
- program_name);
+ printf(
+ "PExports %s; Originally written 1998, Anders Norlander\n"
+ "Updated 1999, Paul Sokolovsky, 2008, Tor Lillqvist, 2013, 2015, Keith Marshall\n"
+ "Copyright (C) 1998, 1999, 2008, 2013, 2015, MinGW.org Project\n\n"
+ "This program is free software; you may redistribute it under the terms of\n"
+ "the GNU General Public License. This program has absolutely no warranty.\n"
+
+ "\nUsage: %s [-v] [-o] [-h header] [-p preprocessor] dll\n"
+ " -h\tparse header\n"
+ " -o\tprint ordinals\n"
+ " -p\tset preprocessor program\n"
+ " -v\tverbose mode\n"
+ "\nReport bugs as directed at %s\n",
+ PACKAGE_VERSION_STRING, program_name, PACKAGE_BUG_REPORT);
return 1;
}
parse_headers();
/* load file */
- dos_hdr = load_pe_image(filename);
- if (dos_hdr == NULL)
+ if( (dos_hdr = load_pe_image(filename)) == NULL )
{
fprintf(stderr, "%s: %s: could not load PE image\n",
program_name, filename);
return 1;
}
- nt_hdr32 = (PIMAGE_NT_HEADERS32) ((char *) dos_hdr + dos_hdr->e_lfanew);
- nt_hdr64 = (PIMAGE_NT_HEADERS64) nt_hdr32;
-
- if (nt_hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
+ nt_hdr32 = (IMAGE_NT_HEADERS32 *) ((char *) dos_hdr + dos_hdr->e_lfanew);
+ nt_hdr64 = (IMAGE_NT_HEADERS64 *) nt_hdr32;
+
+ if (nt_hdr32->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) {
exp_rva = nt_hdr32->OptionalHeader.DataDirectory[0].VirtualAddress;
- else
+ exp_size = nt_hdr32->OptionalHeader.DataDirectory[0].Size;
+ }else{
exp_rva = nt_hdr64->OptionalHeader.DataDirectory[0].VirtualAddress;
+ exp_size = nt_hdr64->OptionalHeader.DataDirectory[0].Size;
+ }
if (verbose)
{
{
section = IMAGE_SECTION_HDR(i);
if (memcmp(section->Name, exp_sign, sizeof(exp_sign)) == 0)
- dump_exports(section->VirtualAddress);
- else if ((exp_rva >= section->VirtualAddress) &&
+ dump_exports(section->VirtualAddress, exp_size);
+ else if ((exp_rva >= section->VirtualAddress) &&
(exp_rva < (section->VirtualAddress + section->SizeOfRawData)))
- dump_exports(exp_rva);
+ dump_exports(exp_rva, exp_size);
}
free(dos_hdr);
/* dump exported symbols on stdout */
void
-dump_exports(DWORD exports_rva)
+dump_exports(uint32_t exports_rva, uint32_t exports_size)
{
- PIMAGE_SECTION_HEADER section;
- PIMAGE_EXPORT_DIRECTORY exports;
+ IMAGE_SECTION_HEADER *section;
+ IMAGE_EXPORT_DIRECTORY *exports;
char *export_name;
- WORD *ordinal_table;
- DWORD *name_table;
- DWORD *function_table;
+ uint16_t *ordinal_table;
+ uint32_t *name_table;
+ uint32_t *function_table;
int i;
static int first = 1;
printf("; Reading exports from section: %s\n",
section->Name);
- exports = RVA_TO_PTR(exports_rva, PIMAGE_EXPORT_DIRECTORY);
+ exports = RVA_TO_PTR(exports_rva, IMAGE_EXPORT_DIRECTORY *);
/* set up various pointers */
- export_name = RVA_TO_PTR(exports->Name,char*);
- ordinal_table = RVA_TO_PTR(exports->AddressOfNameOrdinals,WORD*);
- name_table = RVA_TO_PTR(exports->AddressOfNames,DWORD*);
- function_table = RVA_TO_PTR(exports->AddressOfFunctions,void*);
+ export_name = RVA_TO_PTR(exports->Name, char *);
+ name_table = RVA_TO_PTR(exports->AddressOfNames, uint32_t *);
+ ordinal_table = RVA_TO_PTR(exports->AddressOfNameOrdinals, uint16_t *);
+ function_table = RVA_TO_PTR(exports->AddressOfFunctions, void *);
if (verbose)
{
dump_symbol(RVA_TO_PTR(name_table[i],char*),
ordinal_table[i] + exports->Base,
function_table[ordinal_table[i]]);
+
+ int f_off = ordinal_table[i];
+
+ if(function_table[f_off] >= exports_rva && function_table[f_off] < (exports_rva + exports_size) && verbose) {
+ printf(" ; Forwarder (%s)", RVA_TO_PTR(function_table[f_off], char*));
+ }
+
printf("\n");
}
for (i = 0; i < exports->NumberOfFunctions; i++)
{
- if ( (function_table[i] >= exports_rva) &&
- (function_table[i] <= (section->VirtualAddress + section->SizeOfRawData)))
+ if ( (function_table[i] >= exports_rva) &&
+ (function_table[i] < (exports_rva + exports_size)))
{
- dump_symbol(strchr(RVA_TO_PTR(function_table[i],char*), '.')+1,
- i + exports->Base,
- function_table[i]);
- if (verbose)
- printf(" ; Forwarder\n");
- else
- printf("\n");
+ int name_present = 0, n;
+
+ for(n = 0; n < exports->NumberOfNames; n++) {
+ if(ordinal_table[n] == i) {
+ name_present = 1;
+ break;
+ }
+ }
+
+ if(!name_present) {
+ dump_symbol(strchr(RVA_TO_PTR(function_table[i],char*), '.')+1, i + exports->Base, function_table[i]);
+
+ printf(" ; WARNING: Symbol name guessed from forwarder (%s)\n", RVA_TO_PTR(function_table[i], char*));
+ }
}
}
}
static void
-dump_symbol(char *name, int ord, DWORD rva)
+dump_symbol(char *name, int ord, uint32_t rva)
{
char s[256];
str_tree *symbol = str_tree_find(symbols, name);
/* if a symbol was found, emit size of stack */
if (symbol)
- sprintf(s, "%s@%"INT_PTR_FORMAT, name, (INT_PTR) symbol->extra);
+ sprintf(s, "%s@%"PRIdPTR, name, (intptr_t)(symbol->extra));
else
sprintf(s, "%s", name);
-
+
/* output ordinal */
if (ordinal_flag)
printf("%-24s\t@%d", s, ord);
printf("%s", s);
{
- PIMAGE_SECTION_HEADER s=find_section(rva);
+ IMAGE_SECTION_HEADER *s = find_section(rva);
/* Stupid msvc doesn't have .bss section, it spews uninitilized data
* to no section
}
/* get section to which rva points */
-PIMAGE_SECTION_HEADER
-find_section(DWORD rva)
+IMAGE_SECTION_HEADER *find_section(uint32_t rva)
{
int i;
- PIMAGE_SECTION_HEADER section = IMAGE_SECTION_HDR(0);
+ IMAGE_SECTION_HEADER *section = IMAGE_SECTION_HDR(0);
for (i = 0; i < nt_hdr32->FileHeader.NumberOfSections; i++, section++)
- if ((rva >= section->VirtualAddress) &&
+ if ((rva >= section->VirtualAddress) &&
(rva <= (section->VirtualAddress + section->SizeOfRawData)))
return section;
- return NULL;
+ return NULL;
}
/* convert rva to pointer into loaded file */
void *
-rva_to_ptr(DWORD rva)
+rva_to_ptr(uint32_t rva)
{
- PIMAGE_SECTION_HEADER section = find_section(rva);
- if (section->PointerToRawData == 0)
- return NULL;
- else
- return ((char *) dos_hdr + rva - (section->VirtualAddress - section->PointerToRawData));
+ IMAGE_SECTION_HEADER *section = find_section(rva);
+ return (section->PointerToRawData != 0)
+ ? (char *)(dos_hdr) + rva - section->VirtualAddress + section->PointerToRawData
+ : NULL;
}
/* Load a portable executable into memory */
-PIMAGE_DOS_HEADER
-load_pe_image(const char *filename)
+IMAGE_DOS_HEADER *load_pe_image(const char *filename)
{
#ifdef _MSC_VER
struct _stat32 st;
#else
struct stat st;
#endif
- PIMAGE_DOS_HEADER phdr;
+ IMAGE_DOS_HEADER *phdr;
FILE *f;
-
+
if (stat(filename, &st) == -1)
{
perror("stat");
return NULL;
}
- phdr = (PIMAGE_DOS_HEADER) xmalloc(st.st_size);
-
+ phdr = (IMAGE_DOS_HEADER *) xmalloc(st.st_size);
+
f = fopen(filename, "rb");
if (f == NULL)
}
/* allocate memory; abort on failure */
-static void
-*xmalloc(size_t count)
+static void *xmalloc(size_t count)
{
void *p = malloc(count);
if (p == NULL)