This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Bug in pe_print_idata


Hi everybody,

I found a bug in pe_print_idata. In some PE files (namely drivers) the 'first 
thunk' is not located in the same section as the import table itself. This 
leads to weird behaviours, and segfaults.

I attached a patch to fix the problem to this mail. It would be nice if 
someone with more binutils (especially bfd) knowledge than me could have a 
look at it, correct it (it works here but I'm pretty sure that I forgot 
something) and apply it.

Please cc: me if you reply to this email as I'm not subscribed to this list.

Laurent Pinchart
Index: peXXigen.c
===================================================================
RCS file: /cvs/src/src/bfd/peXXigen.c,v
retrieving revision 1.6
diff -u -r1.6 peXXigen.c
--- peXXigen.c	30 Jan 2002 16:07:28 -0000	1.6
+++ peXXigen.c	6 May 2002 20:35:52 -0000
@@ -1219,10 +1219,53 @@
 
       if (hint_addr != first_thunk && time_stamp == 0)
 	{
+          bfd_byte *ft_data;
+	  asection *ft_section;
+	  bfd_vma ft_addr;
+	  bfd_size_type ft_datasize;
+	  int ft_idx;
 	  int differ = 0;
-	  int idx2;
+	  int ft_allocated = 0;
 
-	  idx2 = first_thunk - adj;
+          ft_addr = first_thunk + extra->ImageBase;
+
+	  /* Find the section which contains the first thunk */
+	  for (ft_section = abfd->sections; ft_section != NULL; ft_section = ft_section->next)
+	    {
+	      ft_datasize = bfd_section_size (abfd, ft_section);
+	      if (ft_addr >= ft_section->vma && ft_addr < ft_section->vma + ft_datasize)
+		break;
+	    }
+
+	  if (ft_section == NULL)
+	    {
+	      fprintf (file,
+		   _("\nThere is a first thunk, but the section containing it could not be found\n"));
+	      continue;
+	    }
+
+	  if (ft_section == section)
+	    {
+	      ft_data = data;
+              ft_idx = first_thunk - adj;
+	    }
+	  else
+	    {
+              ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
+	      ft_data = (bfd_byte *) bfd_malloc (datasize);
+	      if (ft_data == NULL)
+		continue;
+
+	      /* Read datasize bfd_bytes starting at offset ft_idx.  */
+	      if (! bfd_get_section_contents (abfd, ft_section, (PTR) ft_data, (bfd_vma) ft_idx, datasize))
+		{
+		  free (ft_data);
+		  continue;
+		}
+
+	      ft_idx = 0;
+	      ft_allocated = 1;
+	    }
 
 	  for (j = 0; j < datasize; j += 4)
 	    {
@@ -1233,7 +1276,7 @@
 
 	      if (hint_addr != 0)
 		hint_member = bfd_get_32 (abfd, data + idx + j);
-	      iat_member = bfd_get_32 (abfd, data + idx2 + j);
+	      iat_member = bfd_get_32 (abfd, ft_data + ft_idx + j);
 
 	      if (hint_addr == 0 && iat_member == 0)
 		break;
@@ -1269,6 +1312,9 @@
 	  if (differ == 0)
 	    fprintf (file,
 		     _("\tThe Import Address Table is identical\n"));
+
+	  if (ft_allocated)
+	    free (ft_data);
 	}
 
       fprintf (file, "\n");

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]