This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Bug in pe_print_idata
- From: Laurent Pinchart <laurent dot pinchart at skynet dot be>
- To: binutils at sources dot redhat dot com
- Date: Mon, 6 May 2002 22:37:41 +0200
- Subject: 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");