This is the mail archive of the binutils@sourceware.org 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]

Re: [PATCH] Make PE images deterministic by default.


Verified working fine in Wine and Win7 with zero'd timestamps.

Regards,
Cory

On Wed, Nov 20, 2013 at 3:19 PM, Cory Fields <cory@coryfields.com> wrote:
> Use --insert-timestamp to restore previous behavior.
>
> binutils/Changelog
> 2013-11-20  Cory Fields  <cory@coryfields.com>
>     * bfd/libcoff-in.h: Add insert_timestamp flag to the pe_data struct.
>     * bfd/libcoff.h: Update after change to bfd/libcoff-in.h.
>     * bfd/peXXigen.c (_bfd_XXi_only_swap_filehdr_out): Only use a real
>       timestamp if --insert-timestamp was used.
>     * ld/pe-dll.c (fill_edata): Likewise.
>     * ld/emultempl/pe.em: Add the --insert-timestamp option.
>     * ld/emultempl/pep.em: Likewise for 64bit.
>     * ld/ld.texinfo:  Document the --insert-timestamp option.
> ---
>  bfd/libcoff-in.h    |  1 +
>  bfd/libcoff.h       |  1 +
>  bfd/peXXigen.c      |  5 ++++-
>  binutils/ChangeLog  | 10 ++++++++++
>  ld/emultempl/pe.em  | 12 +++++++++++-
>  ld/emultempl/pep.em | 11 ++++++++++-
>  ld/ld.texinfo       |  6 ++++++
>  ld/pe-dll.c         |  7 +++----
>  8 files changed, 46 insertions(+), 7 deletions(-)
>
> diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
> index 6efbc52..17617d6 100644
> --- a/bfd/libcoff-in.h
> +++ b/bfd/libcoff-in.h
> @@ -118,6 +118,7 @@ typedef struct pe_tdata
>    int dll;
>    int has_reloc_section;
>    int dont_strip_reloc;
> +  bfd_boolean insert_timestamp;
>    bfd_boolean (*in_reloc_p) (bfd *, reloc_howto_type *);
>    flagword real_flags;
>  } pe_data_type;
> diff --git a/bfd/libcoff.h b/bfd/libcoff.h
> index 6270bab..d0959a9 100644
> --- a/bfd/libcoff.h
> +++ b/bfd/libcoff.h
> @@ -122,6 +122,7 @@ typedef struct pe_tdata
>    int dll;
>    int has_reloc_section;
>    int dont_strip_reloc;
> +  bfd_boolean insert_timestamp;
>    bfd_boolean (*in_reloc_p) (bfd *, reloc_howto_type *);
>    flagword real_flags;
>  } pe_data_type;
> diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
> index d0f7a96..e1bde2a 100644
> --- a/bfd/peXXigen.c
> +++ b/bfd/peXXigen.c
> @@ -793,7 +793,10 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
>    H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
>    H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
>
> -  H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
> +  // Only use a real timestamp if the option was chosen
> +  if ((pe_data (abfd)->insert_timestamp))
> +    H_PUT_32 (abfd, time(0), filehdr_out->f_timdat);
> +
>    PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
>                       filehdr_out->f_symptr);
>    H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
> diff --git a/binutils/ChangeLog b/binutils/ChangeLog
> index cc9c6f9..1aea955 100644
> --- a/binutils/ChangeLog
> +++ b/binutils/ChangeLog
> @@ -1,3 +1,13 @@
> +2013-11-20  Cory Fields  <cory@coryfields.com>
> +       * bfd/libcoff-in.h: Add insert_timestamp flag to the pe_data struct.
> +       * bfd/libcoff.h: Update after change to bfd/libcoff-in.h.
> +       * bfd/peXXigen.c (_bfd_XXi_only_swap_filehdr_out): Only use a real
> +         timestamp if --insert-timestamp was used.
> +       * ld/pe-dll.c (fill_edata): Likewise.
> +       * ld/emultempl/pe.em: Add the --insert-timestamp option.
> +       * ld/emultempl/pep.em: Likewise for 64bit.
> +       * ld/ld.texinfo: Document the --insert-timestamp option.
> +
>  2013-11-13  Martin Mitas  <mity@morous.org>
>
>         * rescoff.c (write_coff_file): Use 64-bit alignment for resource
> diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
> index 4df7753..bb25e53 100644
> --- a/ld/emultempl/pe.em
> +++ b/ld/emultempl/pe.em
> @@ -130,6 +130,7 @@ static int support_old_code = 0;
>  static char * thumb_entry_symbol = NULL;
>  static lang_assignment_statement_type *image_base_statement = 0;
>  static unsigned short pe_dll_characteristics = 0;
> +static bfd_boolean insert_timestamp = FALSE;
>
>  #ifdef DLL_SUPPORT
>  static int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable.  */
> @@ -259,8 +260,10 @@ fragment <<EOF
>                                         (OPTION_LEADING_UNDERSCORE + 1)
>  #define OPTION_DISABLE_LONG_SECTION_NAMES \
>                                         (OPTION_ENABLE_LONG_SECTION_NAMES + 1)
> +#define OPTION_INSERT_TIMESTAMP \
> +                                        (OPTION_DISABLE_LONG_SECTION_NAMES + 1)
>  /* DLLCharacteristics flags */
> -#define OPTION_DYNAMIC_BASE            (OPTION_DISABLE_LONG_SECTION_NAMES + 1)
> +#define OPTION_DYNAMIC_BASE            (OPTION_INSERT_TIMESTAMP + 1)
>  #define OPTION_FORCE_INTEGRITY         (OPTION_DYNAMIC_BASE + 1)
>  #define OPTION_NX_COMPAT               (OPTION_FORCE_INTEGRITY + 1)
>  #define OPTION_NO_ISOLATION            (OPTION_NX_COMPAT + 1)
> @@ -301,6 +304,7 @@ gld${EMULATION_NAME}_add_options
>       OPTION_USE_NUL_PREFIXED_IMPORT_TABLES},
>      {"no-leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE},
>      {"leading-underscore", no_argument, NULL, OPTION_LEADING_UNDERSCORE},
> +    {"insert-timestamp", no_argument, NULL, OPTION_INSERT_TIMESTAMP},
>  #ifdef DLL_SUPPORT
>      /* getopt allows abbreviations, so we do this to stop it
>         from treating -o as an abbreviation for this option.  */
> @@ -438,6 +442,8 @@ gld_${EMULATION_NAME}_list_options (FILE *file)
>    fprintf (file, _("  --support-old-code                 Support interworking with old code\n"));
>    fprintf (file, _("  --[no-]leading-underscore          Set explicit symbol underscore prefix mode\n"));
>    fprintf (file, _("  --thumb-entry=<symbol>             Set the entry point to be Thumb <symbol>\n"));
> +  fprintf (file, _("  --insert-timestamp                 Use a real timestamp rather than zero.\n"));
> +  fprintf (file, _("                                     This makes binaries non-deterministic\n"));
>  #ifdef DLL_SUPPORT
>    fprintf (file, _("  --add-stdcall-alias                Export symbols with and without @nn\n"));
>    fprintf (file, _("  --disable-stdcall-fixup            Don't link _sym to _sym@nn\n"));
> @@ -754,6 +760,9 @@ gld${EMULATION_NAME}_handle_option (int optc)
>      case OPTION_LEADING_UNDERSCORE:
>        pe_leading_underscore = 1;
>        break;
> +    case OPTION_INSERT_TIMESTAMP:
> +      insert_timestamp = TRUE;
> +      break;
>  #ifdef DLL_SUPPORT
>      case OPTION_OUT_DEF:
>        pe_out_def_filename = xstrdup (optarg);
> @@ -1255,6 +1264,7 @@ gld_${EMULATION_NAME}_after_open (void)
>    pe_data (link_info.output_bfd)->pe_opthdr = pe;
>    pe_data (link_info.output_bfd)->dll = init[DLLOFF].value;
>    pe_data (link_info.output_bfd)->real_flags |= real_flags;
> +  pe_data (link_info.output_bfd)->insert_timestamp = insert_timestamp;
>
>    /* At this point we must decide whether to use long section names
>       in the output or not.  If the user hasn't explicitly specified
> diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
> index 3e8b65e..c6cb626 100644
> --- a/ld/emultempl/pep.em
> +++ b/ld/emultempl/pep.em
> @@ -146,6 +146,7 @@ static flagword real_flags = IMAGE_FILE_LARGE_ADDRESS_AWARE;
>  static int support_old_code = 0;
>  static lang_assignment_statement_type *image_base_statement = 0;
>  static unsigned short pe_dll_characteristics = 0;
> +static bfd_boolean insert_timestamp = FALSE;
>
>  #ifdef DLL_SUPPORT
>  static int    pep_enable_stdcall_fixup = 1; /* 0=disable 1=enable (default).  */
> @@ -241,7 +242,8 @@ enum options
>    OPTION_NO_SEH,
>    OPTION_NO_BIND,
>    OPTION_WDM_DRIVER,
> -  OPTION_TERMINAL_SERVER_AWARE
> +  OPTION_TERMINAL_SERVER_AWARE,
> +  OPTION_INSERT_TIMESTAMP,
>  };
>
>  static void
> @@ -316,6 +318,7 @@ gld${EMULATION_NAME}_add_options
>      {"no-bind", no_argument, NULL, OPTION_NO_BIND},
>      {"wdmdriver", no_argument, NULL, OPTION_WDM_DRIVER},
>      {"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},
> +    {"insert-timestamp", no_argument, NULL, OPTION_INSERT_TIMESTAMP},
>      {NULL, no_argument, NULL, 0}
>    };
>
> @@ -402,6 +405,8 @@ gld_${EMULATION_NAME}_list_options (FILE *file)
>    fprintf (file, _("  --subsystem <name>[:<version>]     Set required OS subsystem [& version]\n"));
>    fprintf (file, _("  --support-old-code                 Support interworking with old code\n"));
>    fprintf (file, _("  --[no-]leading-underscore          Set explicit symbol underscore prefix mode\n"));
> +  fprintf (file, _("  --insert-timestamp                 Use a real timestamp rather than zero.\n"));
> +  fprintf (file, _("                                     This makes binaries non-deterministic\n"));
>  #ifdef DLL_SUPPORT
>    fprintf (file, _("  --add-stdcall-alias                Export symbols with and without @nn\n"));
>    fprintf (file, _("  --disable-stdcall-fixup            Don't link _sym to _sym@nn\n"));
> @@ -707,6 +712,9 @@ gld${EMULATION_NAME}_handle_option (int optc)
>      case OPTION_LEADING_UNDERSCORE:
>        pep_leading_underscore = 1;
>        break;
> +    case OPTION_INSERT_TIMESTAMP:
> +      insert_timestamp = TRUE;
> +      break;
>  #ifdef DLL_SUPPORT
>      case OPTION_OUT_DEF:
>        pep_out_def_filename = xstrdup (optarg);
> @@ -1219,6 +1227,7 @@ gld_${EMULATION_NAME}_after_open (void)
>    pe_data (link_info.output_bfd)->pe_opthdr = pep;
>    pe_data (link_info.output_bfd)->dll = init[DLLOFF].value;
>    pe_data (link_info.output_bfd)->real_flags |= real_flags;
> +  pe_data (link_info.output_bfd)->insert_timestamp = insert_timestamp;
>
>    /* At this point we must decide whether to use long section names
>       in the output or not.  If the user hasn't explicitly specified
> diff --git a/ld/ld.texinfo b/ld/ld.texinfo
> index e4788f6..04325c6 100644
> --- a/ld/ld.texinfo
> +++ b/ld/ld.texinfo
> @@ -2657,6 +2657,12 @@ The driver uses the MS Windows Driver Model.
>  @item --tsaware
>  The image is Terminal Server aware.
>
> +@kindex --insert-timestamp
> +@item --insert-timestamp
> +Insert a real timestamp into the image, rather than the default value of zero.
> +This will result in a slightly different results with each invocation, which
> +could be helpful for distributing unique images.
> +
>  @end table
>
>  @c man end
> diff --git a/ld/pe-dll.c b/ld/pe-dll.c
> index bd3195f..843be7a 100644
> --- a/ld/pe-dll.c
> +++ b/ld/pe-dll.c
> @@ -1170,9 +1170,6 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
>    unsigned char *enameptrs;
>    unsigned char *eordinals;
>    char *enamestr;
> -  time_t now;
> -
> -  time (&now);
>
>    edata_d = xmalloc (edata_sz);
>
> @@ -1187,7 +1184,9 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
>                    + edata_s->output_section->vma - image_base)
>
>    memset (edata_d, 0, edata_sz);
> -  bfd_put_32 (abfd, now, edata_d + 4);
> +  if (pe_data (abfd)->insert_timestamp)
> +    H_PUT_32 (abfd, time(0), edata_d + 4);
> +
>    if (pe_def_file->version_major != -1)
>      {
>        bfd_put_16 (abfd, pe_def_file->version_major, edata_d + 8);
> --
> 1.8.1.2
>


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