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