MSFN is made available via donations, subscriptions and advertising revenue. The use of ad-blocking software hurts the site. Please disable ad-blocking software or set an exception for MSFN. Alternatively, register and become a site sponsor/subscriber and ads will be disabled automatically.

[BETA] Run custom "shutdown" EXE (SHELL32 patcher + source)

Recommended Posts

I know Win9x it's really abandonware nowdays, but I was bored and I wanted to be able to run a custom "shutdown" executable when I clicked the shutdown menu in the Start menu. Somewhere I've read this was possible with another patch, but I can't find it.

So, since this task was not that hard to achieve, I've developed a small patcher that replaces some code in shell32.dll.

The new code (stub) will load another dll -a custom one- which executes a .exe when the user clicks Shutdown in the Start menu. This dll gets unloaded right after that. It's important to note that not only Explorer.exe uses these dialogs, so any application which calls #60 or #54 of shell32.dll will trigger the patch as well!

The custom EXE that will be executed is defined in a .ini file (shellpatch.ini) located in C:\windows\system. There are 2 entries (both are paths to exes), one is for the "Shutdown" menu, and the other one is for "Logoff".

Instructions:

You'll need some kind of executable that mimics the shutdown dialog. For example, the one found in the "Tools9x.exe" installer. I've attached an example "shellpatch.ini" file that points to that shutdown executable.

Open sh_patcher.exe and click "patch".

(Only one time!) Copy the "shellpatch.ini" file to C:\windows\system\

Reboot

If you have another executable you would like to run, edit the shellpatch.ini file and change the paths accordingly.

If you need to revert the changes:

Open sh_patcher.exe and click "revert".

Reboot

Sources and some information:

I've attached the sources of the patcher, the custom dll and the stub.

This patch works by executing a simple stub (which loads the custom dll and calls a function of it) located in SHELL32.dll.

There are two exported functions (#60 and #54) inside SHELL32.dll which displays the Shutdown or Logoff dialog. Both of them calls the same function inside shell32, changing only an argument (0 for Shutdown, 1 for Logoff). This patch modifies the code of this function, since it's possible to distinguish which kind of dialog the user needs. Also, that function is longer than both of the exports, so it allows some room to put the stub.

The patcher loads shell32.dll and obtains its exports and imports. Once it finds the #60 and #54, it looks inside those exports to see where its located the function which both of them calls. After that, it loads the stub.bin file, and replaces some constants with the virtual addresses of the imports of LoadLibrary, GetProcAddress and FreeLibrary. Lastly, it modifies the contents of that function with the new stub.

The stub calls LoadLibraryA, GetProcAddress and FreeLibrary. If the custom dll is found, it calls the default function. In that function, an ini file is readed and based on which kind of dialog the user needs, one or another executable is executed.

sh.dll: Uses Visual C++ 6. Open the .dsp project file, select Release and hit Compile sh.dll. Place the resultant file in C:\windows\system. No reboot is needed.

stub.asm: Uses FASM (1.68). Open the file, and hit Compile. Copy the result file in the same folder as sh_patcher and run it. It's not needed to revert to the original shell32.dll to apply the patch again.

Please try this and tell me if it works or if it has any kind of problem.