From c1ee46543002070ee83ed7836a4d7522630e313e Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Thu, 17 Oct 2019 11:19:45 -0500 Subject: For PE files, copy dos_message contents from source binary MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------2.23.0" This is a multi-part message in MIME format. --------------2.23.0 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit 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. --- bfd/libcoff-in.h | 1 + bfd/libcoff.h | 1 + bfd/peXXigen.c | 23 +++++------------------ bfd/peicode.h | 22 ++++++++++++++++++++++ 4 files changed, 29 insertions(+), 18 deletions(-) --------------2.23.0 Content-Type: text/x-patch; name="0002-For-PE-files-copy-dos_message-contents-from-source-b.patch" Content-Transfer-Encoding: 8bit Content-Disposition: inline; filename="0002-For-PE-files-copy-dos_message-contents-from-source-b.patch" diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h index c75c9ac595..eae5ba25c1 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 d0e3d0dd90..5ee6632776 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 e6d1425472..b437cb55f8 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -854,24 +854,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); @@ -2970,6 +2955,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 2a564fec98..38eb2f1eaf 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--