[PATCH] PE image checksum
Casper Hornstrup
chorns@users.sourceforge.net
Fri Nov 16 10:57:00 GMT 2001
More information about the Binutils mailing list
Fri Nov 16 10:57:00 GMT 2001
- Previous message (by thread): New libtool for GCC 3.1?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi all. This patch computes and applies a checksum to PE images. One thing I'm unsure of is if the call to coff_apply_checksum () is in the right place - inside the "if (abfd->flags & EXEC_P)" statement. Does EXEC_P mean that the output is an executable file? Casper Hornstrup 2001-12-01 Casper S. Hornstrup <chorns@users.sourceforge.net> * coffcode.h (coff_read_word): New. (coff_compute_checksum): New. (coff_apply_checksum): New. (coff_write_object_contents): Call coff_apply_checksum () to apply checksum to PE image. Index: bfd/coffcode.h =================================================================== RCS file: /cvs/src/src/bfd/coffcode.h,v retrieving revision 1.64 diff -u -w -r1.64 coffcode.h --- coffcode.h 2001/10/10 12:08:27 1.64 +++ coffcode.h 2001/12/01 00:06:24 @@ -324,6 +324,9 @@ static boolean coff_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, unsigned long)) ATTRIBUTE_UNUSED; static boolean coff_compute_section_file_positions PARAMS ((bfd *)); +static boolean coff_read_word PARAMS ((bfd *, unsigned int *)); +static unsigned int coff_compute_checksum PARAMS ((bfd *)); +static boolean coff_apply_checksum PARAMS ((bfd *)); static boolean coff_write_object_contents PARAMS ((bfd *)) ATTRIBUTE_UNUSED; static boolean coff_set_section_contents PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); @@ -3216,6 +3219,95 @@ #endif /* 0 */ +static unsigned int pelength; +static unsigned int peheader; + +static boolean +coff_read_word (abfd, value) + bfd *abfd; + unsigned int *value; +{ + unsigned char b[2]; + int status; + + status = bfd_bread (b, (bfd_size_type) 2, abfd); + if (status < 1) + { + *value = 0; + return false; + } + + *value = (unsigned int) (b[0] + (b[1] << 8)); + + pelength += (unsigned int) status; + + return true; +} + +static unsigned int +coff_compute_checksum (abfd) + bfd *abfd; +{ + boolean more_data; + file_ptr filepos; + unsigned int value; + unsigned int total; + + total = 0; + pelength = 0; + filepos = (file_ptr) 0; + + do + { + if (bfd_seek (abfd, filepos, SEEK_SET) != 0) + { + return 0; + } + more_data = coff_read_word (abfd, &value); + total += value; + total = 0xffff & (total + (total >> 0x10)); + filepos += 2; + } while (more_data); + + return (0xffff & (total + (total >> 0x10))); +} + +static boolean +coff_apply_checksum (abfd) + bfd *abfd; +{ + unsigned int computed; + unsigned int checksum = 0; + + if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0) + { + return false; + } + + if (!coff_read_word (abfd, &peheader)) + { + return false; + } + + if (bfd_seek (abfd, peheader, SEEK_SET) != 0) + { + return false; + } + + computed = coff_compute_checksum (abfd); + + checksum = computed + pelength; + + if (bfd_seek (abfd, peheader + 0x58, SEEK_SET) != 0) + { + return false; + } + + bfd_bwrite (&checksum, (bfd_size_type) 4, abfd); + + return true; +} + /* SUPPRESS 558 */ /* SUPPRESS 529 */ static boolean @@ -4001,6 +4093,9 @@ if (amount != bfd_coff_aoutsz (abfd)) return false; + + if (!coff_apply_checksum (abfd)) + return false; } #ifdef RS6000COFF_C else
- Previous message (by thread): New libtool for GCC 3.1?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list