OSDN Git Service

Avoid segmentation faults in forwarder function checks.
authorKeith Marshall <keithmarshall@users.sourceforge.net>
Wed, 14 Sep 2011 20:07:54 +0000 (21:07 +0100)
committerKeith Marshall <keithmarshall@users.sourceforge.net>
Wed, 14 Sep 2011 20:07:54 +0000 (21:07 +0100)
ChangeLog
pexports.c
pexports.h

index 7a0f726..259b998 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,19 @@
+2011-09-14  Daniel Collins  <solemnwarning@solemnwarning.net>
+
+       Avoid segmentation faults in forwarder function checks.
+
+       * pexports.h (dump_exports): Adjust prototype to accommodate new
+       'exports_size' argument; this is to be assigned and passed from...
+       * pexports.c (main): ...here; assigned value is determined from the
+       export table size recorded in the PE file image, whence passed to...
+       (dump_exports): ...here; it is used to avoid crashing or corruption
+       when the export table isn't at the end of its section.  Also check
+       for, and filter out duplicated symbol reports.
+
 2009-09-15  Charles Wilson  <cwilso11@users.sourceforge.net>
 
        Slight build improvements.
+
        * README: Update.
        * Makefile: Rewrite dist rule to create a .tar.lzma instead
        of a .zip (and don't create a tarbomb). 
@@ -8,6 +21,7 @@
 2009-09-15  Charles Wilson  <cwilso11@users.sourceforge.net>
 
        Package 0.44-1-mingw32 fixes.
+
        * pexports.c (main): Fix typo in usage statement.
        * pexports.h: Ensure ULONGLONG is defined.
        * Makefile: Force use of flex and bison, not lex and yacc.
@@ -15,6 +29,7 @@
 2008-08-31  Tor Lillqvist  <tml@novell.com>
 
        Release 0.44. Add support for 64-bit executables.
+
        * hlex.l
        * hparse.y
        * pexports.h
index 1c3a6f6..74a38b0 100644 (file)
@@ -64,7 +64,7 @@ int
 main(int argc, char *argv[])
 {
   PIMAGE_SECTION_HEADER section;
-  DWORD exp_rva;
+  DWORD exp_rva, exp_size;
   int i;
 #if defined(_WIN32) && !defined(_WIN64)
 
@@ -174,10 +174,13 @@ main(int argc, char *argv[])
   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)
+  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)
     {
@@ -196,10 +199,10 @@ main(int argc, char *argv[])
     {
       section = IMAGE_SECTION_HDR(i);
       if (memcmp(section->Name, exp_sign, sizeof(exp_sign)) == 0)
-        dump_exports(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);
@@ -208,7 +211,7 @@ main(int argc, char *argv[])
 
 /* dump exported symbols on stdout */
 void
-dump_exports(DWORD exports_rva)
+dump_exports(DWORD exports_rva, DWORD exports_size)
 {
   PIMAGE_SECTION_HEADER section;
   PIMAGE_EXPORT_DIRECTORY exports;
@@ -259,21 +262,35 @@ dump_exports(DWORD exports_rva)
       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)))
+           (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*));
+          }
         }
     }
 }
index 4563a44..fecdcd0 100644 (file)
@@ -207,7 +207,7 @@ void *
 rva_to_ptr(DWORD rva);
 
 void
-dump_exports(DWORD exports_rva);
+dump_exports(DWORD exports_rva, DWORD exports_size);
 
 #define ADD_FUNCTION(nm,n) str_tree_add(&symbols, nm, (void*)(INT_PTR)n)
 extern str_tree *symbols;