Repository: bitcoin/bitcoin (language: cpp)

Issue:
Bitcoin Core 0.23 installer incompatible with Windows mandatory ASLR
<!-- Describe the issue -->

Try downloading the current version 0.23 of Bitcoin Core for Windows from the official site : the installer (EXE) is corrupted (won't run, corrupted EXE format)

Only the ZIP file is correct.

Workaround: you can use the 0.22 installer, then download the 0.23 zip and extract the executables from there to overwrite the existing EXE files (qt.exe in the main Program Files\Bitcoin folder, other executables in the ZIP go to the "daemon" subfolder)

So the EXE package was incorrectly built, or was incorrectly transfered/truncated on the download site on bitcoin.org.



Discussion / hints:
Potential truncation is discussed in https://github.com/bitcoin-core/bitcoincore.org/issues/753

I recommend to check the checksum before using the downloaded exe to protect against accidental transmission corruption.
> Try downloading the current version 0.23 of Bitcoin Core for Windows from the official site : the installer (EXE) is corrupted (won't run, corrupted EXE format)

It works for me on Win10. 

> So the EXE package was incorrectly built, or was incorrectly transfered/truncated on the download site on bitcoin.org.

bitcoin.org is a different website and has v22.0 available for download. Couldn't find any option to download v23.0

I downloaded setup file from https://bitcoincore.org/bin/bitcoin-core-23.0/
@verdy-p Where did you download it? bitcoin.org (a site independent from the Bitcoin Core project) does not even have version 23.0.

bitcoincore.org does have version 23.0, and the installer exe works for me. It's always possible your download somehow got interrupted of course. Does the problem persist if you try to download again?

> Workaround: you can use the 0.22 installer, then download the 0.23 zip and extract the executables from there to overwrite the existing EXE files (qt.exe in the main Program Files\Bitcoin folder, other executables in the ZIP go to the "daemon" subfolder)

That shouldn't be necessary; you can directly use the executables from the zip file without needing another installation.
Yes the file is corrupted ALWAYS even after retrying multiple times: they are systematically truncated (without any error signaled in the HTTP status code; it is possible that it is your server that has a problem in some frontend caches or third party caches you may use via a CDN.

Such corruptions never occur even when downloading much larger files (e.g. a Linux distrib or Windows ISO, which are much larger), from anywhre in the world. Even when downloading large files from Taiwan (which is slow from France and may occasionally interrupt a TCP session in the middle, this is detected, and the download is resumable, never truncated silently).

I've also tried using other web browsers on other OSes and machines (including tryuing to download directly with a dedicated service on my web router), and even on alternate Internet providers (e.g. on my mobile phone over a 4G or 5G connection), I get exactly the same early truncation of the EXE file than when using my fiber access. If I look at HTTP headers, there's seems to be an inconsistancy between when is reported as the available byteranges. Notealso that I do not use any external frontend cache using any large local store, so that cannot be the cause, and with whatever method, the final filesizes and recomputed hashes (MD5 + SH256) are always the same on all machines used (so this is not a transient problem).
Note that this is definitely not intermittent. I just ue the dowload link proposed on https://bitcoincore.org/en/download/ (given in the README.md displayed in THIS project.

It goes to https://bitcoincore.org/bin/bitcoin-core-23.0/bitcoin-23.0-win64-setup.exe

And that link is always corrupted, on any PC, any ISP, and even when I try to download it from external servers (hosted e.g. on Amazon, or other ISPs, including outside France): they are identical in size and checksum when I compute the checksums there, but never match the SHA256 displayed on that page, I can redownload from these alternate locations, the file I get locally matches the same length and hashes as computed on the intermediate site.

Using alternate browsers, or wget, or downloading to a smartphone (alsowith another ISP) does not change anything: I get exactly the same non working EXE file, rejected by Windows (I tried to load it with different versions of Windows, I alwatys have the same symptom).

So most likely https://bitcoincore.org/bin/bitcoin-core-23.0/bitcoin-23.0-win64-setup.exe redirects us to some broken mirrors and you were successfuly only from your location where your given mirror was correctly updated.

How do you synchronize your advertized mirrors where your site will bring us? with FTP? (you must never do that for managing ANY web site or updating its contents! use RSYNC or HTTP, and only over SSL; FTP is an extremely unsafe dinosaur (even over SSL!), files can be extremely easily infected in the transfers, and such file is highly sensitive to third party attacks in the middle or your synchronization attempts, corrupting all your mirrors and possibly injecting malwares!).

How many bytes is the file you download, and what is its SHA256 checksum?
I get: "bitcoin-23.0-win64-setup.exe"
Some computed hashes give:

CRC32=1803078E
MD5=031ACEF2F0CD4B785379C91718F329AB
SHA1=EC1AE2D6A653F9489872CD08480228261BAEDB6B
SHA256=4198eba8ac326d8746ab43364a44a5f20c157b6701f8c35b80d639a676df9011
SHA512=258B60D3C9E48F5B8C9853AA8D6565EAF96F336D9934E82B2C9F111024E9E6A897F3D026F882EDAD9AFF8C1DDCAAC4AFEB0934313F5527AF6B98485EA3724155

Filesize is exactly: 22,009,384 bytes

That executable never works (even if it embeds a SHA256 digital signature signed by you and whcih is valid for Windows, that executable is broken internally, certainly because of the tool you used to build the setup agent and pack into into an executable ZIP. Windows reports an error 0xc000007B in a dialog just asking to press OK to terminate.

This is most likely incorrectly linked with the Visual C++ runtime libraries, or assumes that we have exactly the same libraries on Windows (I also tried to locate redistributable VC++ Runtime libraries updates on Microsoft.com site, they said they were not needed because my system was up to date and had all the necessary versions, for all currently supported versions of these runtimes).

It's very liklely that your builder used unsafe version of these libraries, or versions that are not redistributable and noly safe for your local installation or when using statically linked libraries, or that you mixed 32bit and 64bits libraries and the program will run only on 32 bit systems.


The hash and size are exactly right.
If they are right, then these files are still NOT compatible with Windows x64. Do they only work with an English base version of Windows? I tried to run it from an environment using the default EN-US locale, and they fail as well.
On a VM where I installed several US versions of Windows XP, 7, 8, 10, 11 (Home, Pro, Server...), your EXE has the same behavior.

Your setup.exe build is definitely broken (or depends on other DLLs that are not packed inside, or attempts to use an unsupported API of Windows, or attempts to make a call to your debugger, or it was built with a setup construction tool that is not licenced to you for commercial/redistribution use, so it only works on your machine if it performs a licence check or domain name check), only the ZIP file works.

I have also checked the various installed versions of [mfc100u.dll, msvcr100.dll, msvcp100.dll et msvcr100_clr0400.dll], and checked the .net installation, no problem reported at all by their official Microsoft installers. As well "SFC /SCANNOW" reports no error at all about these system components, no reparation necessary, and their hashes also match what is reported for them by Microsoft.
What is the exact error message?
![image](https://user-images.githubusercontent.com/1387035/181889448-926d778d-f74d-4c90-8c0d-77623ac44374.png)

In other words:

> #define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS)0xC000007BL) //from ntstatus.h

Get error text:

> {Bad Image}
> %hs is either not designed to run on Windows or it contains an error. Try installing the program again using the original installation media or contact your system administrator or the software vendor for support. Error status 0x%08lx. as an HRESULT: Severity: FAILURE (1), FACILITY_NULL (0x0), Code 0x7b

Note that your digital signature inside the file properties is correct.
That error messages signals a DLL or other external dependencies that can' be found or can't be loaded for whatever reason, during initialization.
I think you made it as a debug version, but did not provide the debugging support (even if I have also tried to download and install the Windows SDK or Microsoft Dev Studio. It seems to be bound to you local machine for tests but not a true release that is distributable, or your development tool uses some licences that were expired and or allows you to run that app, but not distribute it.
Or you've built it with agressive optimizations for AMD processors, and I have an Intel Core on all my tested machines.
Is it self-built or the downloaded version?
The downloadded version, as stated above from that link.

I have also tried to reinstall the MSVC redistributables (https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-160#visual-studio-2015-2017-2019-and-2022).

But they were already up to date (all versions 2014 to 2022). So it's unlikely caused by these runtimes, but some other external dependencies in your built setup.exe (which are like loaded only when the app is loaded and starts initializing, e.g. with custom program loader; or a failure to get the proper authorization from the system, which blocked an unsafe API call, or illegal/restricted CPU instructions)
Fwiw, the `share/setup.nsi.in` file has only two changes since v22.0:
- https://github.com/bitcoin/bitcoin/commit/b3ccf26df47c70e7559625a0e65205648f64efb7
- https://github.com/bitcoin/bitcoin/commit/a5f67b4ca809666661b9dfc773806523e487ea66
Note that
* And the EXE installer for v0.22 works
* the ZIP file for v0.23 works (I can extract the runtime EXE from it to overwrite those from v0.22)
I have no other disgnistic than the hexadecimal error reported above. No log is generated anywhere, nothing in the Windwos Event Viewer.

If you are enforcing the use of a "CRC check" (https://github.com/bitcoin/bitcoin/commit/b3ccf26df47c70e7559625a0e65205648f64efb7), that part of the installer initialization (embedded in its custom loader initializer) probably is usnig incorrect CRC calculation (possibly working only with some CPUs with unsafe optimizations). You normally don't need it on Windows if your file is authenticated with its embedded digital signatures for Authenticode (that already use a much better SHA256 hash).

Di you try to run on any modern Intel x64 Core i7 CPUs?
> If you are enforcing the use of a "CRC check" (https://github.com/bitcoin/bitcoin/commit/b3ccf26df47c70e7559625a0e65205648f64efb7),

Changing the CRCCheck value to `force`, just means that a user is unable to pass `/NCRC` on the command line when running the installer, and skip the CRC check. Otherwise, the installer has always been performing the CRC check on itself in previous versions of Core.
I found some related but obscure events in the Event Registry:
Apps & Services Logs > Windows > AppId > Operational

The app cannot be authenticatd with the embedded signatures.

- Source: AppId; EventID: 4004
  - AppID service was called to check the signature of \?\C:\Program Files\Bitcoin\bitcoin-qt.exe.
Status Unknown NTSTATUS Error code: 0xfffffffe.

It occurs after several error events like

- Source: AppID; Id: 4008
  - Error calling fonction: AiSvcVerifyFile called AiGetTrustedPublisherName, which could not be returned (Error code: Unknown NTSTATUS Error code: 0xfffffffe).
  - Error calling fonction: AiGetTrustedPublisherName called AipGetFileSignature, which could not be returned (Error code: Unknown NTSTATUS Error code: 0xc0070490).
  - Error calling fonction: AipGetFileSignature called CryptCATAdminEnumCatalogFromHash, which could not be returned (Error code: Unknown NTSTATUS Error code: 0xc0070490).
  - Error calling fonction: AipGetFileSignature called WinVerifyTrust(WTD_CHOICE_FILE), which could not be returned (Error code: Unknown NTSTATUS Error code: 0x800b0100 = MissingSignature). (see https://docs.microsoft.com/en-us/windows/win32/api/wintrust/nf-wintrust-winverifytrust and https://github.com/microsoft/referencesource/blob/master/System.Core/System/Security/Cryptography/SignatureVerificationResult.cs)

So this looks like the embedded Authenticode signatures in the installer.exe fails to be checked, and Windows blocks the execution. There are certificates present, but visibly some upstream PKI is not reachable by me from France (blocked by US export restrictions, or some failing internet links to check its authenticity or a certificate that has been blacklisted? or a root CA certificate missing in Windows for France? I've seen such issues with some SSL websites using some Oracle hosting services for their PKI, notably some which are used by advertizers, but blocked in the US-EU safe harbour agreement from being installed by default). The certicate chain in your EXE does not validate up to its trusted root, or there's a missing counterpart signature.

But more likely your developer certificate for trust (used for Authenticode) is expired (or has been revoked) and has not been renewed. Did you forget to pay a yearly billing to renew it before building it in May? Did you install the renewed certificate in your building environment? Did you forget to request some authorizations before signing your request and asking to your PKI provider to authenticate your signature? Did you update your "mingw" installation to get such certificate (if not, you can just self-sign your app for use on your own machine and it works because you have the private keys, but cannot distribute it so that it validates on other machines or in other countries than yours)?

So for now, the prebuilt installer.exe for v0.23 won't work. The only work around is to use the installer.exe from v0.22, then overwrite EXE files that are currently in the downloadable ZIP for v0.23 (when extracting them from the ZIP, Windows requests user permission as the signature does not seem trustable; probably the v0.23 installer.exe does the same, but does not have the builtin capability to ask permission to the user with a GUI dialog, and just fails instantly to extract and install anything; apparently it can just perform a basic CRC check but the Authenticode verifications for the extracted files are enforced now by Windows and such CRC check is just insufficient and unnecessary, even if it passes); or build them ourself using the sources and installing the mingw building environment (installing WSL if needed; note that I have WSL installed) to compile it for our own host (but not signing them publicly, or just self-signing them for our own local use no our machines with our personal certificates generated locally) not for redistribution on the Net.

For now your v0.23 installer.exe contains only a single self-signed signature, authenticating only a date/timestamp, not the authenticity of code; yes you publish an external SHA256 hash for the whole file (different from the embedded SHA256 hash used only to sign your timestamp, countersigned by your PKI provider), but it seems to be insufficient (for the code you just perform the basic check on CRC, but the intaller engine you use wants more and probably refuses to install any extracted EXE files without any kind of authentication when your signed timestamp comes after some timestamp limit that expired or was revoked for any use after some authenticated limit.
Also I tried to compare PE/EXE headers (with "dumpbin.exe filename" from a command line prompt)  between the v0.22 and v0.23 EXE installers.

They show some differences:

- The .text section is now shorter (size of raw data: 9000 hex in v0.22 vs. 8000 in v0.23)
- All sections (.text, .data, .rdata, .xdata, .pdata, .bss, .idata, .ndata, .rsrc) have less flags (e.g. for ".text", we got 60000020 hex, including two additional "RESERVED - UNKNOWN" flags in v0.22, where as v0.23 just has flags 60000020 hex, for "Code", and "Execute Read")
- The virtual address of that section grows from 0000000000401000 to 000000000040908F in v.022, to 0000000140001000 to 0000000140008F9F in v0.23, by being offseted by 000000010000000

And of course the size of the "Certificates directory" has grown (this is where you append the archived files to extract, in the padding left after your basic timestamp signature. Using such huge padding area without certifying with their own signatures is not really supported by Microsoft, and can cause the Authenticode loader of Windows to fail if it exhausts some internal limits; that padding area is only supported if it contains only zeroes. This may have worked with legacy installers, but not for such installer package that is now too big; it's likely that Authenticate expects to find a reasonable end of this padding area (which is not secured at all... that's why you need your custom CRC check for the whole file in the loader), or it may now exhaust the workign area permitted for custome loaders (and given that you'e reduced the .text area, the loader may not have enough virtual space allocated in memory to process the archived contents stored in the certificates directory, notably if it wants to decompress it, or you may need to increase the declared sizes for the BSS, stack reserve, or heap reserve, or their initial committed sizes that are quite small (4KB), notably if the new files require larger lookup window size for some LempelZiv-like or deflate decompression.

Some other changes are also related to the build tool change (notably the linker version from 2.34 to 2.37, installed with the Windows SDK or updated by Windows update for recent builds). In the installer EXE v20.22 there was an additional characteristic in the main header, indicating that relocations were stripped (no longer the case, so addresse randomization may no longer work, and Windows now no longer wants to execute programs with non randomized virtual addresses).

If you upgraded your build chain (may be not mingw itself, used to compile the provided BT tools, but the chain used to build the installer), you may need to add additional flags for using the new linker.

And may be your existing install engine tool (NSIS?) you used no longer works with updated linkers from the Windows SDK, or needs to be updated too to support new restrictions applied with this newer linker.
> In v20.22 there was an additional characteristic in the main header, indicating that relocations were stripped (no longer the case, so addresse randomization may no longer work, and Windows now no longer wants to execute programs with non randomized virtual addresses).

Your assumption is backwards. The relocation stripping would have been a cause of ASLR not working correctly, as a reloc section is required by Windows for working ASLR. This is something we fixed explictly, see #18702, and related discussion in https://sourceware.org/bugzilla/show_bug.cgi?id=19011 etc.
Not sure what to do here. It's at least clear that the binaries being downloaded aren't corrupted, they just aren't running correctly. This doesn't seem to be related to any recent changes in our code / build system, and is going to be hard to debug without the environment that the issue is occuring in.

I think the content in this comment, https://github.com/bitcoin/bitcoin/issues/25726#issuecomment-1200132034, is the most informative, and points to some sort of local networking / user configuration issue:
> So this looks like the embedded Authenticode signatures in the installer.exe fails to be checked, and Windows blocks the execution. There are certificates present, but visibly some upstream PKI is not reachable by me from France (blocked by US export restrictions, or some failing internet links to check its authenticity or a certificate that has been blacklisted? or a root CA certificate missing in Windows for France? I've seen such issues with some SSL websites using some Oracle hosting services for their PKI, notably some which are used by advertizers, but blocked in the US-EU safe harbour agreement from being installed by default). The certicate chain in your EXE does not validate up to its trusted root, or there's a missing counterpart signature.


However searching hasn't seemed to turn up any obvious solutions / references to anything similar.
Does Windows even connect to the internet when checking a signature? Seems unlikely given that one might be offline to install software?
Of course Windows can connect on the Internet (and I'm writing here from the same machine with the same OS, Windows 11).
If something fails, that's most probably because the new installer.EXE file was effectively built using a different linker version, and Windows 11 may assume that with this version it enforces new security restrictions (notably for Authenticode checks).
(and this is independant of how the EXE files appended and archives at end of the initial part of the installer EXE are built themselves. As the new embedded EXE files archived there, in the area normally reserved only for adding signatures, have grown in size, it seems that the new linker version used in the premiary part has reached an upper limit on ho far it can process that area, so it most likely cannot even make its own CRC compaution of that area, which is not signed by itself.
In 2013, Microsoft instructed developers to NOT use that area except for storing signatures, and so most probably the new linker used in the main part of that file makes such assumption. As a result the problem cannot load at all (and I've tried to load it on various versions of Windows, it lever loads).

You probably need to check again the NSIS or script that you used to build that installer EXE file. Something has changed in your buildchain (but it is not visible in the sources we can see here).

For now the only workaround is to use the former installer for v0.22 (to setup some registry value or icons in start menus), then overwrite all the installed directory (created in "C:\Program Files\Bitcoin") to replace it with those coming in the new v0.23 ZIP file. But the v0.23 installer EXE does not run at all (except possibly on the machine where it was built, due to some local developer tweaks, or because of its local Internet setttings, such as for DNS, or firewalls, or local caches in their local routers, or there's a dependency to have an authorized link to some PKI provider that is not reachable/not routable from elsewhere).

Note that I use other softwares that are using installers also based on the NSIS installer engine, they have no problem.
But even trying to load that installer EXE v0.23 with a debugger fails: we get the error message above before we can attach the debugger to the loaded image (and that loading program failure is reported to Microsoft vis its own telemetry systems, but we get no diagnostic at all and no return from Microsoft, most probably because this installer in just incompatible with Windows requirements; it's not a valid EXE image).

So you probably need to check how your NSIS building tools are installed (if it was upgraded, the current "share/setup.nsi.in"  script may need other tunings to make it work with the new version, notably those related to security, or minimal section sizes needed to run your very basic CRC check in the embedded custom loader function: I see that one section ni your new v0.23 installer is smaller than the previous version, it has been reduced by 4KiB and the Windows linker used has changed as well). Anyway this CRC check (now enforced by https://github.com/bitcoin/bitcoin/commit/b3ccf26df47c70e7559625a0e65205648f64efb7) is really too basic, in fact completely futile, to be really useful against malware injections in the archive part appended in the padding area at end of the EXE. It should better use SHA256.

With CRC32, you can still inject arbitrary files, plus a dummy file with 4 null bytes, compute the new CRC, and complement the result to set these 4 bytes and it will pass this check; this requires jsut a few nanoseconds; it will be much more difficult if you use a strong hash like SHA256 because it requires finding a collision by some brute force, even if there are some accelerations. For example the new tools now use an extra DLL (bitcoin tools are no longer completely staticalyl linked), which is located on another directory, but which may be easily defeated by injecting another DLL (with the same name) which will be placed in the "bin/" subdirectory: run the unmodified tools, and that injected malware DLL will be loaded when the tools will start running (those tools as well do not perform any self-consistancy check in their own loaders, given that they are also not securely signed individually as well!).

And that area should not just contain an archive of EXE files to install, but also a signed catalog listing files to be extracted, instead of blindly installing every file that may be appended in that padding area (meaning that this installer is still not safe at all, so that I don't think that this is a Windows bug but a very useful feature if Windows refuses to load it).

Or may be it will only run if we change advanced security settigns in Windows (such as "image randomization" or the "real-time protection", or "cloud-based security", or "virtual-based security": did you turn them off and did not used their default settings for Windows?) Note that Microsoft is constantly adjusting its own "Windows Defender" settings, and I'm running also n a machine where "Advanced Windows Defender" is on (and I cannot disable it at all), and there are a few other security settings enforced by MDM and Intune management, against the injection of malwares.

For this reason I would urge you to instruct users to NEVER use your advertized "upgrade", notably those that have a local installation with their personal wallets (all currency contents could be stolen instantly by the injected malware, or the malware could severely impact the P2P Bitcoin network by performing DDoS attacks, to facilitate attacks against large wallet holders or Bitcoin currency exchanges, or to take control of that network, by injecting large falsified chains and taking control of it, ruining many Bitcoin currency holders, if there are enough corrupted installations of Bitcoin tools acting together to gain the consensus; note that the new DLL in v0.23 is exactly made for that: controling the consensus!).

So for now I consider v0.23 really unsafe (with its DLL); only v0.22 is (moderately) safe (but it can still be easily compromized to steal local wallets, if they are not managed by a trusted external wallet service so that local wallets contain only 0.00BTC all the time, or are left completely unused).

Using the "CRCCheck" feature of NSIS is not a security measure; it's just a basic consistancy check. It cannot replace a proper "Authenticode" signature, but if you use the latter, then "CRCCheck=force" is futile, and should even be "CRCCheck=off"!

Given the amount of BTC money that a Bitcoin Core can control, I don't think it is reasonable to not securely sign it (on Windows with authenticode, or on Linux with catalogs in safe repositories, but always with cryptographically string signatures, at least SHA2-256, but now SHA2-512, or maybe SHA3-256...SHA3-512 if the target system supports the SHA3 algorithms and you don't provide an installable implementation); taking some small time to compute a strong hsh on any program installation is a requirement, independantly of what that program will then do; that time occurs only once during the installation or upgrade. As well, the installer can create a self-signature without modifying the file if that signature is stored in a separate catalog, or inserted in a "stream" (when the EXE file is stored on a NTFS or ReFS volume).
> Given the amount of BTC money that a Bitcoin Core can control, I don't think it is reasonable to not securely sign it (on Windows with authenticode,

The Bitcoin Core installer is authenticode signed, with an actual certificate (not a self-signed one), and I haven't heard of anyone else having problems with it.

In addition, the build process is deterministic and reproducible, and attestations for the build results being correct can be created by anyone, allowing you to choose who to trust besides the one maintainer who happens to have the signing key: https://github.com/bitcoin-core/guix.sigs/tree/main/23.0

> Using the "CRCCheck" feature of NSIS is not a security measure; it's just a basic consistancy check. 

Obviously.

> For this reason I would urge you to instruct users to NEVER use your advertized "upgrade", notably those that have a local installation with their personal wallets

Bitcoin Core deliberately has no auto-upgrade feature for precisely this reason: users should be in control of what version they run. That said, never upgrading will eventually also run you into trouble, as bugs in old versions get discovered and fixed.

---

At this point, I'm afraid a way to reproduce this problem in order will be needed in order to debug it.
My "never" word is overinterpreted, I jsut mean this version 0.23 of the installer EXE for Windows, that I've found not working on ANY tested Windows machine (various versions), not even the first time on a fresh installation of Windows, with variable CPU models, cores, memory, storage and variable OS versions.

I have the same failure when trying to run it from a test VM hosted on Azure (Europe).

IF there's some limiation in your PKI infrastructure (or one of its DNS providers from your local installation), may be you could reproduce it by running your version from a VM whose Internet connection goes though a VPN hosted in France (may be this also affects other European countries).

If you suspect your internet connection, could you please try a different connection (a friend's connection, a public wifi, mobile hotspot, VPN ...)? While it is possible, I'd be surprised that this is the reason or that all connections in your country lead to this issue. I am pretty sure we have users in France, who have never run into this issue.
I have not observed any issues with a 23.0 installation on a Windows 10 machine using an AMD CPU, with and without and internet connection, and with and without a VPN to France. It is possible that WIndows 11 has changed something that breaks it. It is also possible that modern Intel CPUs with their big-little architecture is causing this issue (as this is known to have caused some problems with other programs), but I don't currently have access to either of those things to test it out.

Can you say exactly what OS version and hardware you are using?
I don't have any CPU with "big-little" capability. It's a classic Core i7 (locally; on Azure VMs, I don't know eactly how they run internally). And I've tried multiple machines, all x64 (but did not test with any AMD). I've tested that on Windwos 7 (Ultimate) Windows 10 and Windows 11 (Home, Pro, Enterprise). In none of them the installer EXE loads, I always get the dialog above, I can't even load it in any debugger; it's blocked internally by the Windows loader API but I don't know why.
The Windows Event Viewer does not provide any helpful hint (but I always get the same errors within "Apps & Services Logs > Windows > AppId > Operational" with Appid Errors 4008 followed by 4004 (detailed already above), and I'm convinced that this comes from Authenticode validation (may be this is a bug inside the Microsoft's own cloud or its peerings used for France to make Authenticode work, such as a non-propagated certificate or a broken route; there's nothing I can do, I see no way to even try bypassing it).
So what can I do that would help diagnose it?
If you can reproduce on Azure VMs, that would likely be easiest to reproduce, if you provide exact steps to reproduce.
Are there some required CPU feature flags (CPUID related) specific for Intel (e.g. my CPUS are x64 supporting the EES, AVX, AVX2, SSE 4.2 instruction set, but NOT the SHA1 extension) and a bad assumption about processor features, and so even the slower fallback implementation by software does not run in the new generated NSIS package?
Note that this does NOT affect the individual EXE that are found in the ZIP file, ONLY the new NSIS installer which was linked differently.

For Azure VM, just use any free trial VM (choose a location in Europe), try installnig Windows 10 or Windows 11 from the proposed packages (you don't need to install a licence as it will run for enough time, you don't need many cores, RAM, storage or Internet bandwidth, or any paid support services, or any dedicated machine, the basic free option should be enough for such test). Then download your v0.23 installer EXE and try running it (using the v0.22 installer.exe works without any problem). Such VM (in a shared machine) will also allow testing it in the most security-restricted situations (however these VM are known to run on the best and latest CPU models; you may have to choose which kind of CPU you'll get, I always used an Intel Core x64, and did not test with AMD).

You could do that as well on other VM hosting providers which allow installing Windows desktop OSes, and using it with some RDP client.
> For Azure VM, just use any free trial VM (choose a location in Europe), try installnig Windows 10 or Windows 11

Please provide the exact and unique steps that reproduced for you, ideally steps to reproduce by someone with little knowledge of Windows. There are too many combinations for us to try them all.


Isn't what I explained simple? Every user of Azure will know how to install a supported 64bit version of Windows, it is fast and Microsoft guides them. Just make sure you select a hosting location in Europe (even if this means that your RDP session may be a bit less responsive in its UI.

Once the desktop is ready, connect to it with the any "remote desktop" client, authenticate to Azure to get the standard logon screen, terminates the installation wizard if needed, until you get to the desktop

To minimize the "lagging" impact of the UI (if it ever happens when doing that from Western US or Asia), just make sure you disable unnecessary desktop custimization, e.g. use a flat black desktop background, or reduce the resolution fo the virtual screen, you don't need 4K, or ClearType, disable visual effects or animations; that's something that Microsoft Support does routinely for all users, on which they connect with a remote desktop session, unless there's a real need to test graphics).

then download inside your VM session (you can use Microsoft Edge which is builtin, jsut like any basic user would do, and just try launch it: if you see the NSIS setup dialog, the test is OK. If you see the error dialog above, you see the problem: Windows does not accept it as a valid executable.

But now you'll need to use Windows debuggers: your VM may need to have developer tools installed, including Mingw running  a VM inside a VM to compile it, so your basic test VM may require some additional storage; but you should be able to use developer tools on your own PC, and use "remote debugging" to deploy and test the installer inside the Azure VM (this requires Windows development skills and knowledge about how to use NSIS, so that a basic user will not know how to do that; and your Azure VM must then be at least running Windows 7, but likely Windows 10, as Windows 7 and Windows 8/8.1 are in end of life and may not run in free test VMs on shared Azure machines).

> Isn't what I explained simple? Every user of Azure

I don't use Azure, I signed up today. I can't reproduce with your steps. See also https://www.chiark.greenend.org.uk/~sgtatham/bugs.html 

What I used:

* France Central
* Windows (Windows 10 Pro)
* Standard DS1 v2 (1 vcpu, 3.5 GiB memory)

![Screenshot from 2022-08-02 20-42-38](https://user-images.githubusercontent.com/6399679/182449912-f1fb898e-b542-4ba1-a93f-ae0a5c931d7c.png)


Also cannot reproduce. Created a Standard B1s VM on Azure with Windows 11. Downloaded the installer and it runs fine. The installation runs as expected too.
> ![image](https://user-images.githubusercontent.com/1387035/181889448-926d778d-f74d-4c90-8c0d-77623ac44374.png)

> Windows reports an error 0xc000007B in a dialog just asking to press OK to terminate.

I was reading different threads on stackoverflow, microsoft answers etc. with this error `0xc000007B` and was able to almost reproduce the issue. This can be tried irrespective of country, network etc. I do not get this error but  v23.0 exe file doesn't work whereas v22.0 works:

1. Go to: Windows Security -> App & Browser Control -> Exploit protection -> System Settings -> Force randomization for images should be ON

2. Restart machine

3. Download v23.0, v22.0 for bitcoin core and try to run both

This was based on a stackoverflow answer in which Android Studio was not working and there was same error: https://stackoverflow.com/questions/56536708/android-studio-opening-error-unable-to-start-correctly-0xc000007b/

I am not sure if this is an issue with bitcoin core or the way Windows works in different environments. Windows updates also matter in trying to reproduce the issue as one recent update had stopped wireless networks on one of my laptop.
> I was reading different threads on stackoverflow, microsoft answers etc. with this error `0xc000007B` and was able to almost reproduce the issue. This can be tried irrespective of country, network etc. I do not get this error but v23.0 exe file doesn't work whereas v22.0 works:
> 
>     1. Go to: Windows Security -> App & Browser Control -> Exploit protection -> System Settings -> Force randomization for images should be ON
> 
>     2. Restart machine
> 
>     3. Download v23.0, v22.0 for bitcoin core and try to run both

I believe this replicates the issue. I also do not see an error dialog, but in the event viewer under Windows Logs > System, I do see an event for the binary with the expected error message. The issue also occurs with the unsigned installer, so this is not an issue with the signature, but probably with NSIS.
So this finally confirms what I had: this is an issue which is probably caused by ASLR, and the fact that the new version of NSIS reduced the size of a segment.

ASLR need some memory to create the remapping table for some segments, by allocating it at end of the ".text" segment before turning it readonly, this is where it will place "the jump table" for redirecting thunks. The sizes of segments that have been set with the new linker settings used by NSIS seem to be too restrictive (you can look at the PE EXE header: one segment has been shrunk by 4KB, it's possibly that ASLR can no longer work in this too tiny environment).
Also all PE sections had two extra flags, see what I wrote above.

When I was replied that nothing was changed in sources, it's possible with the sources published here (i.e. the "nsis.in" script)... except that you've upgraded your installation of NSIS in your build environment and changed the linker, probably by upgrading mingw or the GCC build chains, including its linker (this is visible in the version of the linker included to the PE EXE header of the installer).

Note: I CANNOT turn off the randomization in "Security > System settings" not even by inserting an exception. This is ON by default per policy (the same occurs also in my Azure account for the test VM I used, and all the PC's I've tried on Windwos; it is enforced with my licences and microsoft account synchronization, by various Microsoft management tools like MDM, Intune, Windows Defender, Credit Guard...).

Also note that ALL executables are marked to prevent execution of data (see System properties > Performance options > Enable prevention of execution of data for all programs and services, except those listed; it may not be activated there, whereas the default in Windows is to enable it only for Windows programs and services; but a group policy may still enforce it; note also that my list of exceptions there is also empty, but anyway it is not used, because "NX" is enforced everywhere for all data segments, meaning that you cannot place executable dynamic thunks in data segments, but place them in a readonly segment; ASLR updates them at load time, updates the relocations then changes the segment settings to executable).

All this is done by the system user and not the current user; if a program wants to use a cosutm loader, it needs some extra flags, plus some security tokens and signed certificates; all this occurs before any instruction of the loaded program is executed, and not even a debugger can to attach the image, except possibly a kernel debugger and only when loading Windows in debug mode; the only debugger that gets attached to that image is the one used inside Windows Defender or system crash handler, that's why your installer has a crash dump submitted to Microsoft which did not publish a shim for the new version of NSIS to mitigate a restriction). You should read the release not of the new version of NSIS that you've used if this requires adjustments to you NSIS script or to the NSIS building tools and its environment.

And may be the previous version of NSIS did not need relocations and thunks, if it was statically built to use only PIC code. But now it may have relocation tables, that the program loader needs to fix for ASLR by adding thunks, but the segment size settings in your NSIS builder does not allocate that extra space in the generated EXE image (and this cannot be changed later if you've already "signed" the image and computed the SHA256 checksum that you ask us to verify.
nsis was changed in commit 711ce2e5333bd6717f9b114abe7ec1d1994afbc4 maybe?
This is unlikely to be fixed in the meantime, but could you also try an unsigned master build? (Warning: The exe hasn't been checked for reproducibility, malware and bitflips, so use at your own risk on test-only VMs)

https://drahtbot.space/guix/bitcoin/bitcoin/207a22877330709e4462e6092c265ab55c8653ac/bitcoin-207a22877330-win64-setup-unsigned.exe
> new version of NSIS

> nsis was changed in commit https://github.com/bitcoin/bitcoin/commit/711ce2e5333bd6717f9b114abe7ec1d1994afbc4 maybe?

The version of NSIS used to produce both the 22.x and 23.x release binaries was version 3.05. It is still version 3.05 in the time-machine we are currently using in master.
With your unsigned installer, this does not work (first I get a dialog askingfor permission because it is not signed and comes from the Internet (the file is saved with an extra "stream" marking it as possibly unsafe). I can click OK.

But then nothing else happens; I do not even get the error dialog above; the program does not load and I jsut see the eventIDs 4004 and 4008 in the Event Handler, plus the program being reported to Microsoft with a "minidump".

So This is most likely a bug of your new version of NSIS or in one of its toolchain, no longer working with programs compiled with MINGW and the gcc chaintool, possibly a bug in its new version for the linker, or a missing configuration for the ".text" segment or some segment attributes, or incorrect memory alignment settings or security settings for some segments. Or yu've linked it with the incorrect "sinit.obj" for the C runtime library, forgetting to prepare some extra segments needed for ASLR, or not correctly detecting that ASLR is used by the loader. And may be the stack segment allocated is just too small for the new NSIS engine if you also call a custom function for your CRC check; or you need to allocate some more space for the heap if the you NSIS loader needs more. Sies indicated in the PE EXE header are ridiculous small, even smaller than ni v0.22 (may be because your new NSIS is not aware that you use a custom function needing extra space for its own temporary buffers, because the new version needs now less space for decompressing files from the appended archive part of the file; NSIS probably has some performance tuning parameters for those buffers but you've still used its default minimum settings)!
Note also that the CRCCheck feature of NSIS is legacy . Its purpose is only to provide minimal protection for very old versions of Windows that did not have "authenticode" built in the program loader (Windows 9x?). If you use Authenticode, you'll never need it, as it can protect not just the generated program but also the extra sections that you append to it for packing an archive; the program signatures will be appended after that (not before!).

You should never append anything else to a signed exe file except possibly additional (and valid) certificates, or just some non significant padding zeroes (that may be needed only if you process the padding area by using buffered /O with multiple of some buffer size, but there should alway be less than 4KB of zeroes. Using the padding area of EXE files for storing a custom archive (notably after certicates) is unsupported (there's not even the warranty that the Windows loader will place that area into memory, it may just "prefetch" it only the filesystem cache, but not map it at all in the virtual memory of the module being loaded (for a process creation of for dynamic linking).
Note: I also tried to create a copy of your unsigned EXE, by using "file properties" in Explorer, and then asking to drop private metadata (it seems there are metadata attached to it and tracking you!).
THe file Explorer creates a copy and strips this data, so it gets a bit smaller. But when I run it, I no longer have the permission request from Windows (the extra "stream" indicating that the file was downloaded from the net and tracking its original web source is also dropped; that stream however is not visible in File Explorer and is not counted as the filesize; but the personal metadata inside the EXE is present).

So now if I run it, i get again the error dialog "0xc000007B" and the EventID's 4004 and 4008 in the Events Viewer, and the program reported to Microsoft with a minidump. So really this EXE image is still invalid, it cannot be safely loaded; linker options or too small segment sizes are most probably the cause.

Can you build an image without the legacy "CRCcheck" option in your NSIS input script? If this works now, this is likely caused by that: the new NSIS does not correctly compute the memory requirements for that function to work correctly and the Wnidows laoder did not provide it enough memory space (in the stack or in some BSS or heap segments to place the needed buffers allowing it to perform I/O on the whole EXE file and not just on the image partially loaded by Windows).
Note that for most Windows programs that can be loaded for Windows a a single EXE file, they are generated using a "SFX" packer (like Winzip, or PKARC, for which you need a paid licence, but whose packed engine is also securely signed by Microsoft nd that also appends safe certificated at end of the image, after the ZIP or ARC part. This allows them to extract a first ZIP or MSI archive and a separate static "setup.exe" program to process it; that extra static program is also securely signed.

But here it seems that the format you use is now blocked by default (too suspect for Windows). The padding area of PE EXE files is not meant to contain any data other than valid certicates (for Authenticode or other signature systems) or zeroes.
Also I treid to call the "LoadModule()" API of win32 in powershell, passing it the path of you v0.23 installer, it also fails with the same error 0xC0000007B error status, so this is not a problem of execution as I did not attempt to execute it. And as well this reports the EventIDs 4004 and 4008 in the "Appid" section of the EventViewer; we are clearly in a case of an attempt to use a case unsupported by Windows, but now Windows detects such case and blocks the program loading, instead of silently ignoring it and let the module continue being loaded as if it as valid. May be this is caused by stricted rules applied by Windwos Defender or in the new patched kernels, or added as countermeasures against some wellknown attacks.

(I've not tried disabling Windows Defender and not tried other antimalwaers which Microsoft authorize as replacement for some features of Windows Defender, may be there's one antimalware that accepts that image format)
I guess the best bet would be to create guix binaries for commit https://github.com/bitcoin/bitcoin/commit/711ce2e5333bd6717f9b114abe7ec1d1994afbc4 and the previous commit and then see if either of them passes
Confirming that setting "_Force randomization for images (Mandatory ASLR)_" to "_On by default_" makes [`bitcoin-23.0-win64-setup.exe`](https://bitcoincore.org/bin/bitcoin-core-23.0/bitcoin-23.0-win64-setup.exe) unusable. [`bitcoin-22.0-win64-setup.exe`](https://bitcoincore.org/bin/bitcoin-core-22.0/bitcoin-22.0-win64-setup.exe) remains unaffected.

Tested on Windows 11 Pro 21H2.
I also found that the EXE file contains MORE relocation entries than those indicated in the PE EXE header for one section.

This is confirmed with "DUMPBIN.EXE" (from MS Visual Studio 2022), which signals it in the ".pdata" section. I get this message (in French because VS Studio 2022 is installed and running on the French system locale) when dumping the relocation entries:

> LINK : fatal error LNK1337: le binaire contient plus de réadressages de base que ce que son répertoire de réadressages de base indique

This does not occur with the v0.22 installer.

So this is a bug in the linker used with your mingw suite (the EXE contains signatures from "GCC: (GNU) 10.3.0".)
I think this is a bug of its PE EXE linker (linker version v2.37 reported now in the PE EXE header, it was linker version 2.34 in the v0.22 installer, which was compiled with "GCC: (GNU) 7.5.0"). Or you need a bugfix upgrade for your version of NSIS; alternatively you may attempt to revert your mingw/GCC environment to use GCC 7.5.0 to build the NSIS installer (nothing to change for building the Bitcoin*.exe tools for now). NSIS requires LOT of relocation and it does not compile correctly the Windows installer with GCC 10.3.0.

See also
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95620

ASLR cannot work if it can't allocate the correct number of redirecting thunks as indicated in the PE EXE header. But without ASLR, no dynamic relation updates has to be performed, the sections can be directly mapped to memory at the indicated virtual adresses of the process, provided that it is large enough, as no redirecting thnk is needed and no patch is needed in the relocation entries that are completely unused in this case.

Other projects have had serious problems when upgrading GCC 7/8 to GCC 10. But here we find a case where it generates bad code that cannot be safely linked (some table limit exhausted), or that this is a bug in its "ld" linker, not properly building the PE EXE header (possibly assuming that some relocations were optimized and removed, when they were not; may be this could be solved by compiling the NSIS installer as PIC; the code may be a bit slower and the generated code a bit larger, but it's not dramatic for an installer).
> I guess the best bet would be to create guix binaries for commit [711ce2e](https://github.com/bitcoin/bitcoin/commit/711ce2e5333bd6717f9b114abe7ec1d1994afbc4) and the previous commit and then see if either of them passes

The commit prior works, however 711ce2e itself cannot be tested because the guix commit it uses is no longer in guix's commit history (they force pushed and overrode it at some point).
The commit might still be cached by GitHub at https://github.com/guix-mirror/guix/commit/fa17abf1af09570708daa28dd40ffbc932ebe25c
To quickly summarise. On a Windows System with the `Force randomization for images (Mandatory ASLR)` option enabled:
Our [`bitcoin-22.0-win64-setup.exe`](https://bitcoincore.org/bin/bitcoin-core-22.0/bitcoin-22.0-win64-setup.exe)  installer works, while [`bitcoin-23.0-win64-setup.exe`](https://bitcoincore.org/bin/bitcoin-core-23.0/bitcoin-23.0-win64-setup.exe)does not.

Our [`bitcoin-22.0-win64.zip`](https://bitcoincore.org/bin/bitcoin-core-22.0/bitcoin-22.0-win64.zip) and [`bitcoin-23.0-win64.zip`](https://bitcoincore.org/bin/bitcoin-core-23.0/bitcoin-23.0-win64.zip) binaries, when unzipped, all work fine on the same system.

`bitcoin-22.0-win64-setup.exe` and `bitcoin-23.0-win64-setup.exe` were produced using the same version of NSIS: 3.05.

If anyone wants to test, I've pushed up a branch, based on master, that will use NSIS 3.08 to produce the installers in the Windows Guix build: https://github.com/fanquake/bitcoin/tree/nsis_3_08, to see if that makes any difference.
```bash
c03ddef8fcfcde9aa71a26a0f5fb7bcda92b2c6646a88e2a48ceaa729ff7d3c2  guix-build-ef89806e8c2f/output/dist-archive/bitcoin-ef89806e8c2f.tar.gz
fe8cc7a8d898155dd41ad01d4aaa3897cd713b02d4ea154b0366d58242554632  guix-build-ef89806e8c2f/output/x86_64-w64-mingw32/SHA256SUMS.part
469a358e9464f9af4a1152b14101ad5d93da50a42c4288a6c80fdc5f53bf3e13  guix-build-ef89806e8c2f/output/x86_64-w64-mingw32/bitcoin-ef89806e8c2f-win64-debug.zip
5de14da387ea12583c96ed3d202b6a0b7bc03c53623c9c9f6e36be7bb7fdaef3  guix-build-ef89806e8c2f/output/x86_64-w64-mingw32/bitcoin-ef89806e8c2f-win64-setup-unsigned.exe
a4e7e531fb871280c1a7dadbbc0f2fcc17f251cd7c77a6907a2247f9f64837f0  guix-build-ef89806e8c2f/output/x86_64-w64-mingw32/bitcoin-ef89806e8c2f-win64-unsigned.tar.gz
e4178dd4845fb9d1e7cd47534ff943dce97d7f7e00f0b797110a444bdb70b97b  guix-build-ef89806e8c2f/output/x86_64-w64-mingw32/bitcoin-ef89806e8c2f-win64.zip
```
> If anyone wants to test, I've pushed up a branch, based on master, that will use NSIS 3.08 to produce the installers in the Windows Guix build: https://github.com/fanquake/bitcoin/tree/nsis_3_08, to see if that makes any difference.

Tested, doesn't work. 
I've taken the liberty to update the issue title with the current understanding. Feel free to revert if you feel this is inaccurate.
> Fwiw, the `share/setup.nsi.in` file has only two changes since v22.0:
> 
>     * [b3ccf26](https://github.com/bitcoin/bitcoin/commit/b3ccf26df47c70e7559625a0e65205648f64efb7)
> 
>     * [a5f67b4](https://github.com/bitcoin/bitcoin/commit/a5f67b4ca809666661b9dfc773806523e487ea66)

Just tested that the reversion of these commits does not help.
Fwiw, I've verified installers with [PESecurity PowerShell script](https://github.com/NetSPI/PESecurity):

```
PS C:\Users\hebasto\Downloads> Get-PESecurity -file .\bitcoin-22.0-win64-setup.exe


FileName         : C:\Users\hebasto\Downloads\bitcoin-22.0-win64-setup.exe
ARCH             : AMD64
DotNET           : False
ASLR             : True
DEP              : True
Authenticode     : True
StrongNaming     : N/A
SafeSEH          : N/A
ControlFlowGuard : False
HighentropyVA    : True



PS C:\Users\hebasto\Downloads> Get-PESecurity -file .\bitcoin-23.0-win64-setup.exe


FileName         : C:\Users\hebasto\Downloads\bitcoin-23.0-win64-setup.exe
ARCH             : AMD64
DotNET           : False
ASLR             : True
DEP              : True
Authenticode     : True
StrongNaming     : N/A
SafeSEH          : N/A
ControlFlowGuard : False
HighentropyVA    : True



```
Just consider using DUMPBIN (the free tool provided by Visual Studio 2022).
- Try running: DUMPBIN /ALL 'bitcoin-(version)-win64-setup.exe' >log
- look at the "LINK : fatal error LNK1337" occuring while dumping the ".pdata" section.
- look at "Relocations stripped" info displayed in the header for v0.22, but not for v0.23.
- You can detect the GCC version used by looking at the end of the dumped ".text" section in the log file. It is different even if you (supposedly) used the same version of NSIS (IMHO it's not the case, the ".text" code section is larger now).
- You can detect the linker version in the headers at top of file. It is different even if you used the same version of NSIS.

There may be equivalent dump tools for the GCC suite (but they make different assumptions, possibly based on Linux capabilities) to inspect the relocation entries, and see by yourself that their effective number don't match what is catalogued in the PE headers. Who's wrong? GCC generating fake/duplicate relocation entries, or the linker not properly updating the EXE header when it terminates its job, or NSIS using GCC or LD with incorrect options? Or your build environment that selects the incorrect version of GCC/LD, if multiple versions are installed in the system (check the paths, symbolic links, "alternatives" in Linux)? Is is even possible that you mixed tools/library/data/config paths between x64 and arm64, or between Windows and Linux, using different formats, models or different constraints for the same x64 architecture, assuming that the EXE will run in a Cygwin environment for example which uses a different binary image loader and not the native Windows image loader)

Such bug won't be resolved (or checked) by signing tools you use to append the signatures (so signatures may look valid for Get-PESecurity in Powershell).

Note also that Mingw is a thin layer allowing to use GCC or related tools, as if they were running on Linux; but it uses the Windows build tools, notably its linker ("ld" is an emulation; "gcc" may generate correct COFF files for Win32, but it supports other models, such as Cygwin; there are other tools if you run them in WSL, which use a thick layer running a true Linux VM inside Hyper-V, and so it doesnot use the Win32 API directly). Here we are not running the EXE installer for Windows in Cygwin or WSL; but your NSIS installation may have been confused to run with tools compiled for Cygwin emulation layer instead of the Mingw64 thin layer. Some GCC options that work in Linux/WSL or in Cygwin won't run in a native Wni32 environment or in Mingw.

I don't know which version of NSIS you used, and unfortunately there's NO build actual script that checks the NSIS installation and runs it. All we have a a basic script file, indicatign nothing about the envuironmetn where it will be processed. May be you need to contact NSIS experts on their support forum and see how they have setup a clean environment (that you could also host in the same mingw64 environment you use to produce the individual compiled tools.

So you should integrate the NSIS construction rules inside your makefile. Or you may look at https://nsis.sourceforge.io/Category:Development_Environments
(such as https://nsis.sourceforge.io/Visual_Studio_Code which installs the NSIS plugin for Visual Studio Code from the CLI environment of Visual Studio Code)

But how to be sure about version stability of all this? May be you can add environment checks inside the NSIS script itself to assert that it will run properly (it can check paths, versions, registry entries, required external tools, and guide the user if it needs something else; as well it can perfectly make validation checks after building the EXE even if it does not proceed to the next step, i.e. authenticode signatures, or just produces a self-signed executable that will run on your local machine where the personal certificate is installed; that self-siganture can then be replaced by an authentic one for distribution, generated in a safe environment by some of your trusted admins...)

Fix patch:
diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm
index a2b1fe1f24b92..7c45a5b86608e 100644
--- a/contrib/guix/manifest.scm
+++ b/contrib/guix/manifest.scm
@@ -194,7 +194,8 @@ chain for " target " development."))
 
 (define (make-nsis-for-gcc-10 base-nsis)
   (package-with-extra-patches base-nsis
-    (search-our-patches "nsis-gcc-10-memmove.patch")))
+    (search-our-patches "nsis-gcc-10-memmove.patch"
+                        "nsis-disable-installer-reloc.patch")))
 
 (define (fix-ppc64-nx-default lief)
   (package-with-extra-patches lief
diff --git a/contrib/guix/patches/nsis-disable-installer-reloc.patch b/contrib/guix/patches/nsis-disable-installer-reloc.patch
new file mode 100644
index 0000000000000..4914527e56beb
--- /dev/null
+++ b/contrib/guix/patches/nsis-disable-installer-reloc.patch
@@ -0,0 +1,30 @@
+Patch NSIS so that it's installer stubs, produced at NSIS build time,
+do not contain .reloc sections, which will exist by default when using
+binutils/ld 2.36+.
+
+This ultimately fixes an issue when running the installer with the
+"Force randomization for images (Mandatory ASLR)" setting active.
+
+This patch has not yet been sent upstream, because it's not clear if this
+is the best fix, for the underlying issue, which seems to be that makensis
+doesn't account for .reloc sections when it builds installers.
+
+The existence of a reloc section shouldn't be a problem, and, if anything,
+is actually a requirement for working ASLR. All other Windows binaries we
+produce contain them, and function correctly when under the same
+"Force randomization for images (Mandatory ASLR)" setting.
+
+See:
+https://github.com/bitcoin/bitcoin/issues/25726
+https://sourceforge.net/p/nsis/bugs/1131/
+
+--- a/SCons/Config/gnu
++++ b/SCons/Config/gnu
+@@ -102,6 +102,7 @@ stub_env.Append(LINKFLAGS = ['-mwindows'])          # build windows executables
+ stub_env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG'])    # no standard libraries
+ stub_env.Append(LINKFLAGS = ['$ALIGN_FLAG'])        # 512 bytes align
+ stub_env.Append(LINKFLAGS = ['$MAP_FLAG'])          # generate map file
++stub_env.Append(LINKFLAGS = ['-Wl,--disable-reloc-section'])
+ 
+ conf = FlagsConfigure(stub_env)
+ conf.CheckCompileFlag('-fno-tree-loop-distribute-patterns')  # GCC 10: Don't generate msvcrt!memmove calls (bug #1248)


Test patch: