[PATCH 2/2] For PE files, copy dos_message contents from source binary
Andrew Eikum
aeikum@codeweavers.com
Tue Oct 29 13:05:00 GMT 2019
Hey Nick,
Thanks for merging that patch. This is the other one in the series.
The first patch changed size of the dos_message field so it could be
used here in the memcpy()s.
Thanks,
Andrew
On Thu, Oct 17, 2019 at 02:28:02PM -0500, Andrew Eikum wrote:
> Wine uses a special message in this area to mark its own binaries.
> strip(1) would discard the message from the original binary and replace
> it with a hard-coded string. This would break Wine when its libraries
> are built as PE files and installed with strip(1).
>
> For example, see the special message in the original DLL from a Wine
> build tree, starting at offset 0x40:
>
> $ xxd ~/src/wine.win64/dlls/ieframe/ieframe.dll | head
> 00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000 MZ..............
> 00000010: b800 0000 0000 0000 4000 0000 0000 0000 ........@.......
> 00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> 00000030: 0000 0000 0000 0000 0000 0000 8000 0000 ................
> 00000040: 5769 6e65 2062 7569 6c74 696e 2044 4c4c Wine builtin DLL
> 00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> 00000060: 7420 6265 2072 756e 2069 6e20 444f 5320 t be run in DOS
> 00000070: 6d6f 6465 2e0d 0d0a 2400 0000 0000 0000 mode....$.......
> 00000080: 5045 0000 6486 1200 58f1 9c5d 0030 3900 PE..d...X..].09.
> 00000090: 6817 0000 f000 2620 0b02 0220 0030 0300 h.....& ... .0..
>
> And see how it is removed after stripping:
>
> $ strip -o /tmp/ieframe.dll ~/src/wine.win64/dlls/ieframe/ieframe.dll
> $ xxd /tmp/ieframe.dll | head
> 00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000 MZ..............
> 00000010: b800 0000 0000 0000 4000 0000 0000 0000 ........@.......
> 00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
> 00000030: 0000 0000 0000 0000 0000 0000 8000 0000 ................
> 00000040: 0e1f ba0e 00b4 09cd 21b8 014c cd21 5468 ........!..L.!Th
> 00000050: 6973 2070 726f 6772 616d 2063 616e 6e6f is program canno
> 00000060: 7420 6265 2072 756e 2069 6e20 444f 5320 t be run in DOS
> 00000070: 6d6f 6465 2e0d 0d0a 2400 0000 0000 0000 mode....$.......
> 00000080: 5045 0000 6486 0b00 0000 0000 0000 0000 PE..d...........
> 00000090: 0000 0000 f000 2e22 0b02 0220 0030 0300 ......."... .0..
>
> This patch copies the message from the original binary into the new
> binary.
>
> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com>
> ---
> bfd/libcoff-in.h | 1 +
> bfd/libcoff.h | 1 +
> bfd/peXXigen.c | 23 +++++------------------
> bfd/peicode.h | 22 ++++++++++++++++++++++
> 4 files changed, 29 insertions(+), 18 deletions(-)
>
> diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
> index 783d54a88a..5386236bc0 100644
> --- a/bfd/libcoff-in.h
> +++ b/bfd/libcoff-in.h
> @@ -128,6 +128,7 @@ typedef struct pe_tdata
> int has_reloc_section;
> int dont_strip_reloc;
> bfd_boolean insert_timestamp;
> + int dos_message[16];
> bfd_boolean (*in_reloc_p) (bfd *, reloc_howto_type *);
> flagword real_flags;
>
> diff --git a/bfd/libcoff.h b/bfd/libcoff.h
> index f2613c2e77..cdd483535f 100644
> --- a/bfd/libcoff.h
> +++ b/bfd/libcoff.h
> @@ -132,6 +132,7 @@ typedef struct pe_tdata
> int has_reloc_section;
> int dont_strip_reloc;
> bfd_boolean insert_timestamp;
> + int dos_message[16];
> bfd_boolean (*in_reloc_p) (bfd *, reloc_howto_type *);
> flagword real_flags;
>
> diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
> index ab0da7f532..f6daf85859 100644
> --- a/bfd/peXXigen.c
> +++ b/bfd/peXXigen.c
> @@ -861,24 +861,9 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
>
> filehdr_in->pe.e_lfanew = 0x80;
>
> - /* This next collection of data are mostly just characters. It
> - appears to be constant within the headers put on NT exes. */
> - filehdr_in->pe.dos_message[0] = 0x0eba1f0e;
> - filehdr_in->pe.dos_message[1] = 0xcd09b400;
> - filehdr_in->pe.dos_message[2] = 0x4c01b821;
> - filehdr_in->pe.dos_message[3] = 0x685421cd;
> - filehdr_in->pe.dos_message[4] = 0x70207369;
> - filehdr_in->pe.dos_message[5] = 0x72676f72;
> - filehdr_in->pe.dos_message[6] = 0x63206d61;
> - filehdr_in->pe.dos_message[7] = 0x6f6e6e61;
> - filehdr_in->pe.dos_message[8] = 0x65622074;
> - filehdr_in->pe.dos_message[9] = 0x6e757220;
> - filehdr_in->pe.dos_message[10] = 0x206e6920;
> - filehdr_in->pe.dos_message[11] = 0x20534f44;
> - filehdr_in->pe.dos_message[12] = 0x65646f6d;
> - filehdr_in->pe.dos_message[13] = 0x0a0d0d2e;
> - filehdr_in->pe.dos_message[14] = 0x24;
> - filehdr_in->pe.dos_message[15] = 0x0;
> + memcpy (filehdr_in->pe.dos_message, pe_data (abfd)->dos_message,
> + sizeof (filehdr_in->pe.dos_message));
> +
> filehdr_in->pe.nt_signature = IMAGE_NT_SIGNATURE;
>
> H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
> @@ -2979,6 +2964,8 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
> && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED))
> pe_data (obfd)->dont_strip_reloc = 1;
>
> + memcpy (ope->dos_message, ipe->dos_message, sizeof (ope->dos_message));
> +
> /* The file offsets contained in the debug directory need rewriting. */
> if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size != 0)
> {
> diff --git a/bfd/peicode.h b/bfd/peicode.h
> index 1e2b104430..fed2b2d586 100644
> --- a/bfd/peicode.h
> +++ b/bfd/peicode.h
> @@ -271,6 +271,24 @@ pe_mkobject (bfd * abfd)
> /* in_reloc_p is architecture dependent. */
> pe->in_reloc_p = in_reloc_p;
>
> + /* default dos message string */
> + pe->dos_message[0] = 0x0eba1f0e;
> + pe->dos_message[1] = 0xcd09b400;
> + pe->dos_message[2] = 0x4c01b821;
> + pe->dos_message[3] = 0x685421cd;
> + pe->dos_message[4] = 0x70207369;
> + pe->dos_message[5] = 0x72676f72;
> + pe->dos_message[6] = 0x63206d61;
> + pe->dos_message[7] = 0x6f6e6e61;
> + pe->dos_message[8] = 0x65622074;
> + pe->dos_message[9] = 0x6e757220;
> + pe->dos_message[10] = 0x206e6920;
> + pe->dos_message[11] = 0x20534f44;
> + pe->dos_message[12] = 0x65646f6d;
> + pe->dos_message[13] = 0x0a0d0d2e;
> + pe->dos_message[14] = 0x24;
> + pe->dos_message[15] = 0x0;
> +
> memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr);
> return TRUE;
> }
> @@ -325,6 +343,8 @@ pe_mkobject_hook (bfd * abfd,
> coff_data (abfd) ->flags = 0;
> #endif
>
> + memcpy (pe->dos_message, internal_f->pe.dos_message, sizeof (pe->dos_message));
> +
> return (void *) pe;
> }
>
> @@ -1456,6 +1476,8 @@ pe_bfd_object_p (bfd * abfd)
> return NULL;
> }
>
> + memcpy (internal_f.pe.dos_message, dos_hdr.dos_message, sizeof (internal_f.pe.dos_message));
> +
> /* Read the optional header, which has variable size. */
> opt_hdr_size = internal_f.f_opthdr;
>
> --
> 2.23.0
>
More information about the Binutils
mailing list