Active references seem ignored by ld, for MinGW delay-loaded import libraries
Pete Batard
pete@akeo.ie
Fri Jul 19 11:11:53 GMT 2024
Apologies for having reported this to the wrong mailing list.
For reference, this appears to be a 12 year old bug, that has yet to see
a fix:
https://sourceware.org/bugzilla/show_bug.cgi?id=14339
Regards,
/Pete
On 2024.07.16 17:42, Pete Batard wrote:
> Hi,
>
> # Description
>
> This whole issue is better illustrated (and replicated) with the MinGW
> sample code provided at [1] and, since it pertains to delay loading of
> Windows DLL with MinGW, we first reported it to the MinGW mailing list
> [2], before people there suggested that it ultimately looks like a
> binutils bug, and would be better submitted to this list.
>
> The gist of the issue is that, because of the longstanding issue of
> sideloading vulnerabilities with Windows DLLs, Windows applications
> compiled with MinGW may want to delay-load vulnerable DLLs by using
> dlltool with the '--output-delaylib' option, in order to create an
> import library, that takes care of the delay-loading, and can be linked
> with the final executable, per the method described at [3].
>
> This appears works fine with some DLLs, but for quite a few others, such
> as wininet.dll, this results in an application crash whenever a
> delay-loaded function call is invoked, on account that the thunk, that
> is meant to perform the actual loading, contains a NULL dereference.
> Currently, we are assuming that this is due to ld.bfd erroneously
> thinking that the code is not referenced at all, and not including it.
>
> This seems further evidenced by the fact that, in our test sample, if we
> force an explicit reference to __imp__InternetCrackUrlA@16 (which is one
> of the internal calls that is exposed by the import library) then the
> problem goes away.
>
> So it does seem to us like, in some circumstances, ld is dismissing what
> should be an active reference, as an unused one.
>
>
> # Steps to replicate
>
> Note that the issue only manifests itself when using the 32-bit version
> of MinGW and not the 64-bit version (which we assume has to do with the
> fact that the calling convention/decorations appears to play a role, as
> another workaround we found was to switch the delay-loaded API calls
> from '__declspec(dllimport)' to '__attribute__((visibility("hidden")))')
>
> 1. Clone https://github.com/pbatard/delayload.git
> 2. From a MinGW32 (32-bit) prompt issue 'make'
> 3. Run ./delayload.exe and observe the crash.
> 4. To test the "hidden" visibility or explicit reference workarounds,
> you can issue 'make clean' and then 'make WORKAROUND1' or 'make
> WORKAROUND2' respectively.
>
>
> Because none of the "workarounds" we have found are satisfactory for our
> usage, we would really appreciate if this issue could be investigated
> and, if it does turn out to be a binutils bug, remediated.
>
> Regards,
>
> /Pete
>
>
> [1] https://github.com/pbatard/delayload
> [2]
> https://sourceforge.net/p/mingw-w64/mailman/mingw-w64-public/thread/ea87573f-65ea-44a2-b4bb-ca96c0a136ab%40akeo.ie/#msg58793876
> [3] https://stackoverflow.com/a/70416894/1069307
More information about the Binutils
mailing list