PE format conformance issues in rebase.exe results incompatibility with LLVM-lld

Kashiwada Tomohiro kikairoya@gmail.com
Mon Jul 21 12:31:05 GMT 2025


I just found this in my spam folder -- along with two other emails you
CCed me on earlier. I'm really sorry for the delay.
Apparently, Google thinks, "You can't speak English, so any English
emails to you must be spam."
2025年7月18日(金) 9:36 Jeremy Drake <cygwin@jdrake.com>:
>> On Sat, 7 Jun 2025, kikairoya via Cygwin wrote:
>> > Dear Cygwin team,
> >
> > I’ve found that rebase.exe makes certain assumptions that do not conform
> > to the PE specification.
> >
> > 1. Incorrect handling of COFF File Header position
> > When checking the 'Characteristics' field in the COFF File Header,
> > rebase.exe assumes this field is always at a fixed offset. However, the
> > PE specification states that the COFF File Header is located immediately
> > after the PE signature in the image file.
> >
> > https://cygwin.com/cgit/cygwin-apps/rebase/tree/rebase.c#n1739
> > At this point, the code should perform a relative seek of 18 bytes, not
> > an absolute seek with SEEK_SET.
> >
> > This causes incompatibility with DLLs linked using LLVM's lld, which
> > uses a PE stub of a different size. As a result, such DLLs cannot be
> > rebased.
> >
> >
> > 2. Limiting file size too conservatively
> > https://cygwin.com/cgit/cygwin-apps/rebase/tree/pechecksum.c#n81
> >
> > Here, the image size is limited to 1 GiB, while the PE specification
> > allows for up to 2 GiB. Large DLLs with debug information (e.g.,
> > `cygLLVM*.dll`, `cygclang-cpp*.dll`, etc.) can easily exceed the 1 GiB
> > limit.
> >
> >
> > I hope these issues can be addressed to improve compatibility with
> > LLVM-based toolchains and enhance the robustness of development
> > workflows.
>>> Would you like to make a patch for these? There may be another issue
> because peflags says "checksum update failed" on a small lld-created exe
> even when not modifying the binary.
>
Sure, I have made a patch.
I didn't see about peflags but it should have similar logic, I can take a look
about that -- after bisecting clang.
diff --git a/pechecksum.c b/pechecksum.c
index 8695138..d9fe544 100644
--- a/pechecksum.c
+++ b/pechecksum.c
@@ -77,8 +77,8 @@ unsigned pe32_checksum(int fd, int set, unsigned *
old_checksum)
 sum += get_word(buf + i);
 sum = (sum + (sum >> 16)) & 0xffff;
- if ((size += 2) >= 0x40000000) {
- // 1GiB, assume something is wrong.
+ if ((size += 2) >= 0x80000000) {
+ // >=2GiB, assume something is wrong.
 errno = EINVAL;
 return 0;
 }
diff --git a/rebase.c b/rebase.c
index 6a531d0..07e8016 100644
--- a/rebase.c
+++ b/rebase.c
@@ -1704,7 +1704,7 @@ BOOL
 is_rebaseable (const char *pathname)
 {
 const int pe_signature_offset_offset = 0x3c;
- const int pe_characteristics_offset = 150;
+ const int pe_characteristics_offset = 18;
 short int pe_signature_offset = 0;
 BOOL status = FALSE;
 int fd, size;
@@ -1736,7 +1736,6 @@ is_rebaseable (const char *pathname)
 if (pe_sig != IMAGE_NT_SIGNATURE)
 goto done;
- lseek (fd, 0, SEEK_SET);
 offset = lseek (fd, pe_characteristics_offset, SEEK_CUR);
 if (offset == -1)
 goto done;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-fix-handling-of-PE-header-and-size-limit.patch
Type: application/octet-stream
Size: 1414 bytes
Desc: not available
URL: <https://cygwin.com/pipermail/cygwin/attachments/20250721/6834c578/attachment.obj>


More information about the Cygwin mailing list

AltStyle によって変換されたページ (->オリジナル) /