public inbox for cygwin-apps@cygwin.com
 help / color / mirror / Atom feed
* [PATCH rebase] rebase: Add -c, --checksum option
@ 2023-08-08 10:10 Christian Franke
  2023-08-08 13:25 ` Jon Turney
  2023-08-08 18:17 ` Corinna Vinschen
  0 siblings, 2 replies; 4+ messages in thread
From: Christian Franke @ 2023-08-08 10:10 UTC (permalink / raw)
  To: cygwin-apps

[-- Attachment #1: Type: text/plain, Size: 137 bytes --]

Last patch for now.

Left for later: ReBaseImage64() unconditionally updates the timestamp in 
the file header.

-- 
Regards,
Christian


[-- Attachment #2: 0001-rebase-Add-c-checksum-option.patch --]
[-- Type: text/plain, Size: 5683 bytes --]

From 3973a92cf11056521552d9d3f87efe8e721e8c31 Mon Sep 17 00:00:00 2001
From: Christian Franke <christian.franke@t-online.de>
Date: Tue, 8 Aug 2023 12:04:25 +0200
Subject: [PATCH] rebase: Add -c, --checksum option

If specified, the file checksum in the PE header is updated after
rebasing.

Signed-off-by: Christian Franke <christian.franke@t-online.de>
---
 Makefile.in |  4 ++--
 rebase.c    | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index adb7972..2f061ca 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -74,7 +74,7 @@ override CXX_LDFLAGS+=@EXTRA_CXX_LDFLAG_OVERRIDES@
 
 LIBIMAGEHELPER = imagehelper/libimagehelper.a
 
-REBASE_OBJS = rebase.$(O) rebase-db.$(O) $(LIBOBJS)
+REBASE_OBJS = rebase.$(O) rebase-db.$(O) pechecksum.$(O) $(LIBOBJS)
 REBASE_LIBS = $(LIBIMAGEHELPER)
 
 REBASE_DUMP_OBJS = rebase-dump.$(O) rebase-db.$(O) $(LIBOBJS)
@@ -100,7 +100,7 @@ $(LIBIMAGEHELPER):
 rebase$(EXEEXT): $(REBASE_LIBS) $(REBASE_OBJS)
 	$(CXX) $(CXXFLAGS) $(LDFLAGS) $(CXX_LDFLAGS) -o $@ $(REBASE_OBJS) $(REBASE_LIBS)
 
-rebase.$(O):: rebase.c rebase-db.h Makefile
+rebase.$(O):: rebase.c pechecksum.h rebase-db.h Makefile
 
 rebase-db.$(O):: rebase-db.c rebase-db.h Makefile
 
diff --git a/rebase.c b/rebase.c
index 7417d4d..50cc79f 100644
--- a/rebase.c
+++ b/rebase.c
@@ -39,6 +39,7 @@
 #include <errno.h>
 #include <io.h>
 #include "imagehelper.h"
+#include "pechecksum.h"
 #include "rebase-db.h"
 #include <versionhelpers.h> /* requires <windows.h> */
 
@@ -74,6 +75,7 @@ WORD machine = IMAGE_FILE_MACHINE_I386;
 ULONG64 image_base = 0;
 ULONG64 low_addr;
 BOOL down_flag = FALSE;
+BOOL checksum_flag = FALSE;
 BOOL image_info_flag = FALSE;
 BOOL image_storage_flag = FALSE;
 BOOL image_oblivious_flag = FALSE;
@@ -1188,6 +1190,32 @@ print_overlapped ()
     }
 }
 
+static BOOL
+update_checksum (const char *pathname)
+{
+  int fd, err;
+  unsigned old_checksum, new_checksum;
+
+  if ((fd = open (pathname, O_RDWR | O_BINARY)) == -1)
+    {
+      fprintf (stderr, "%s: failed to reopen for checksum update: %s\n",
+	       pathname, strerror (errno));
+      return FALSE;
+    }
+  new_checksum = pe32_checksum (fd, 1, &old_checksum);
+  err = errno;
+  close(fd);
+  if (!new_checksum)
+    {
+      fprintf (stderr, "%s: checksum update failed: %s\n", pathname,
+	       strerror (err));
+      /* Assume file is unchanged. */
+      return FALSE;
+    }
+
+  return (new_checksum != old_checksum);
+}
+
 BOOL
 rebase (const char *pathname, ULONG64 *new_image_base, BOOL down_flag)
 {
@@ -1279,13 +1307,18 @@ retry:
     }
 #endif
 
+  /* Update checksum, if requested. */
+  status = (checksum_flag ? update_checksum (pathname) : FALSE);
+
   /* Display rebase results, if verbose. */
   if (verbose)
     {
-      printf ("%s: new base = %" PRIx64 ", new size = %x\n",
+      printf ("%s: new base = %" PRIx64 ", new size = %x%s\n",
 	      pathname,
 	      (uint64_t) ((down_flag) ? *new_image_base : prev_new_image_base),
-	      (uint32_t) (new_image_size + offset));
+	      (uint32_t) (new_image_size + offset),
+	      (checksum_flag ? (status ? ", checksum updated" :
+	      ", checksum unchanged") : ""));
     }
 
   /* Calculate next base address, if rebasing up. */
@@ -1299,6 +1332,7 @@ static struct option long_options[] = {
   {"32",	no_argument,	   NULL, '4'},
   {"64",	no_argument,	   NULL, '8'},
   {"base",	required_argument, NULL, 'b'},
+  {"checksum",	no_argument,	   NULL, 'c'},
   {"down",	no_argument,	   NULL, 'd'},
   {"help",	no_argument,	   NULL, 'h'},
   {"usage",	no_argument,	   NULL, 'h'},
@@ -1316,7 +1350,7 @@ static struct option long_options[] = {
   {NULL,	no_argument,	   NULL,  0 }
 };
 
-static const char *short_options = "48b:dhiMno:OqstT:vV";
+static const char *short_options = "48b:cdhiMno:OqstT:vV";
 
 void
 parse_args (int argc, char *argv[])
@@ -1341,6 +1375,9 @@ parse_args (int argc, char *argv[])
 	  image_base = string_to_ulonglong (optarg);
 	  force_rebase_flag = TRUE;
 	  break;
+	case 'c':
+	  checksum_flag = TRUE;
+	  break;
 	case 'd':
 	  down_flag = TRUE;
 	  break;
@@ -1625,6 +1662,10 @@ Rebase PE files, usually DLLs, to a specified address or address range.\n\
   One of the options -b, -s or -i is mandatory.  If no rebase database exists\n\
   yet, -b is required together with -s.\n\
 \n\
+  -c, --checksum          Update the file's checksum in the PE header if the\n\
+                          file has been successfully rebased.  This also bumps\n\
+                          the file's modification time (like -t) if the\n\
+                          checksum has been changed.\n\
   -d, --down              Treat the BaseAddress as upper ceiling and rebase\n\
                           files top-down from there.  Without this option the\n\
                           files are rebased from BaseAddress bottom-up.\n\
@@ -1634,7 +1675,8 @@ Rebase PE files, usually DLLs, to a specified address or address range.\n\
                           when rebasing.  Default is no offset.\n\
   -t, --touch             Use this option to make sure the file's modification\n\
                           time is bumped if it has been successfully rebased.\n\
-                          Usually rebase does not change the file's time.\n\
+                          Usually rebase does not change the file's time unless\n\
+                          the -c flag is also specified.\n\
   -T, --filelist=FILE     Also rebase the files specified in FILE.  The format\n\
                           of FILE is one DLL per line.\n\
   -q, --quiet             Be quiet about non-critical issues.\n\
-- 
2.39.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH rebase] rebase: Add -c, --checksum option
  2023-08-08 10:10 [PATCH rebase] rebase: Add -c, --checksum option Christian Franke
@ 2023-08-08 13:25 ` Jon Turney
  2023-08-08 14:30   ` Christian Franke
  2023-08-08 18:17 ` Corinna Vinschen
  1 sibling, 1 reply; 4+ messages in thread
From: Jon Turney @ 2023-08-08 13:25 UTC (permalink / raw)
  To: Christian Franke, cygwin-apps

On 08/08/2023 11:10, Christian Franke via Cygwin-apps wrote:
> Last patch for now.
> 
> Left for later: ReBaseImage64() unconditionally updates the timestamp in 
> the file header.

Just for clarity: does this mean that rebasing as it is currently 
implemented leaves the PE file with an invalid checksum, and the Windows 
loader is just fine this that?

Or is there something else happening which makes the checksum wrong?


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH rebase] rebase: Add -c, --checksum option
  2023-08-08 13:25 ` Jon Turney
@ 2023-08-08 14:30   ` Christian Franke
  0 siblings, 0 replies; 4+ messages in thread
From: Christian Franke @ 2023-08-08 14:30 UTC (permalink / raw)
  To: Jon Turney, cygwin-apps

Jon Turney wrote:
> On 08/08/2023 11:10, Christian Franke via Cygwin-apps wrote:
>> Last patch for now.
>>
>> Left for later: ReBaseImage64() unconditionally updates the timestamp 
>> in the file header.
>
> Just for clarity: does this mean that rebasing as it is currently 
> implemented leaves the PE file with an invalid checksum, and the 
> Windows loader is just fine this that?
>
> Or is there something else happening which makes the checksum wrong?
>
>

Both rebase and peflags leave the PE file with an invalid checksum.

This is no problem for Cygwin uses cases:
"Checksums are required for kernel-mode drivers and some system DLLs."
https://learn.microsoft.com/en-us/windows/win32/api/imagehlp/nf-imagehlp-mapfileandchecksuma

-- 
Regards,
Christian


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH rebase] rebase: Add -c, --checksum option
  2023-08-08 10:10 [PATCH rebase] rebase: Add -c, --checksum option Christian Franke
  2023-08-08 13:25 ` Jon Turney
@ 2023-08-08 18:17 ` Corinna Vinschen
  1 sibling, 0 replies; 4+ messages in thread
From: Corinna Vinschen @ 2023-08-08 18:17 UTC (permalink / raw)
  To: cygwin-apps

On Aug  8 12:10, Christian Franke via Cygwin-apps wrote:
> Last patch for now.
> 
> Left for later: ReBaseImage64() unconditionally updates the timestamp in the
> file header.
> 
> -- 
> Regards,
> Christian
> 

> From 3973a92cf11056521552d9d3f87efe8e721e8c31 Mon Sep 17 00:00:00 2001
> From: Christian Franke <christian.franke@t-online.de>
> Date: Tue, 8 Aug 2023 12:04:25 +0200
> Subject: [PATCH] rebase: Add -c, --checksum option
> 
> If specified, the file checksum in the PE header is updated after
> rebasing.
> 
> Signed-off-by: Christian Franke <christian.franke@t-online.de>
> ---
>  Makefile.in |  4 ++--
>  rebase.c    | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 48 insertions(+), 6 deletions(-)

Pushed.  Next release gets created right now.


Thanks,
Corinna


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-08-08 18:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-08 10:10 [PATCH rebase] rebase: Add -c, --checksum option Christian Franke
2023-08-08 13:25 ` Jon Turney
2023-08-08 14:30   ` Christian Franke
2023-08-08 18:17 ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).