Ludovic Frank - Freelance developer

Windows: how to alter the operation of a process by injecting code? In our case, explorer.exe

ionicons-v5-k Ludovic Frank Mar 2, 2025
56 reads Level: Expert

Hello little wolves 😊.

Thank you for clicking on this article. As always, I hope you enjoy it 😁.

Today, we're going to get into the hard stuff. Recently, I had the opportunity to experiment with some things that reminded me of my teenage years, so I decided to write about them.

Warning: the content of this article is to be used for educational purposes only. Don't do anything illegal.

The aim here is to learn how it works, and I find that fascinating. By the way, I'm going to omit some details on purpose... So this won't be a turnkey solution, but rather a way of seeing "globally how it works".

Back to Windows...

Ten years is the time between now and the last time Windows was my main operating system.

In the meantime, I switched to Linux, then macOS, which gave me access to a Unix terminal as well as commercial software (Adobe, Microsoft Office, etc.).

But then, after four years of full-time freelancing, I realized that there's a "problem" with running macOS as my main system.

Why spend time on Windows again?

Simply put: the business world.

Microsoft (and Windows) is omnipresent in the corporate world, it's all there is.

In my various projects, I've often had to deal with the Microsoft environment...
For example: deploying a PHP / Symfony development environment on Windows with WSL2, managing an Active Directory in the cloud with Entra ID, etc.

By the way, I'll soon have to write an article on the best environment for developing with Symfony on Windows... That was originally planned for this week, but it'll come back later.

There should be a few articles on Windows soon.

What are we going to do?

If, in Task Manager, you terminate the "explorer.exe" process, you'll find that in addition to the taskbar, the wallpaper also disappears...

This means that when explorer.exe is loaded, that's when the wallpaper is set.

Let's change that... We're going to prevent explorer.exe from loading the wallpaper.

How does explorer.exe load the wallpaper?

First of all, we need to understand what's going on. When launched, explorer.exe uses a Windows API to set the background...

The API in question is "SystemParametersInfoW", found in the "user32.dll" file.

It is called with the parameter "SPI_SETDESKWALLPAPER", which corresponds to the value "0x0014".

A quick aside: on Windows, APIs often end in "A" or "W": "A" for ASCII and "W" for WideChar.

Historically, Windows was based on ANSI encoding (Windows 95, 98, ME), where characters were stored on 1 byte(char). However, with the arrival of Windows NT and its native support for Unicode (UTF-16), Microsoft introduced Unicode versions of API functions.

All that's left to do is...

Now that we know how explorer.exe sets the background, all we have to do is replace the function and respond to explorer.exe instead of the Windows API when it calls it.

How easy is that?

Windows Defender

Bah yes... 😛.

Since I've been talking about injecting code into explorer.exe, it's bound to disagree.

To sum up, it's very simple: if you create an .exe that "kills" explorer.exe, then recreate it to inject code before it calls the API, Windows Defender will block the .exe file as malicious.

And at the same time... he's right.

Give me your certificate, I'll tell you who you are

And yes... Windows Defender looks less carefully when the .exe file is digitally signed with a recognized certificate.

After all, I didn't go so far as to buy a 300-euro certificate just for the experience.

DLLs

For the same code, in an .exe file and in a .dll, Windows Defender won't detect the .dll file, even if it contains exactly the same code as in the .exe.

Realizing this, I came up with a lot of ideas. For example: rather than writing code in C++ that will be compiled into a binary, try coding an "injector" written in C# (so in .NET) that will inject code into explorer.exe.

The idea is that an .exe written in .NET is not a real binary, but code interpreted by the .NET framework, and therefore less suspect.

However, this wasn't the solution I chose. I found something more fun and "safer".

The entry point

As I said earlier, if an .exe is signed with a clean and valid certificate, then Windows Defender is less fussy.

What if our code wasn't executed by a .exe of our own, but by a .exe that is "trusted" by Windows Defender? Wouldn't that be crazy?

DLL hijacking

Yes, what I just said is possible 😁.

By default, when an .exe needs a DLL, it first searches its own folder. If the library isn't found, then it will look for it in the $PATH (usually System32).

But many applications are coded in such a way as to check that the DLL loaded is a legitimate one...

"Many" does not mean "all"...

A quick look on the net reveals a list of applications vulnerable to DLL hijacking.

For example, some versions of Notepad++ are vulnerable to DLL hijacking.

When a text editor executes code

Yes, for this part, I do have working code that exploits Notepad++. However, I won't put it here, and we'll stay very theoretical.

It's signed

If you download Notepad++, one of the versions affected by the vulnerability, you'll see that it has been signed with a valid certificate and that, for Windows, everything is OK.

To see this, right-click on the .exe, then "Properties", then "Digital signature".

Loading UxTheme.dll

One of the first things Notepad++ does is load the "UxTheme.dll" library.

So, if in the executable folder, we put a "UxTheme.dll" file that exports the same functions as the original DLL, then Notepad++ will execute this code and stay under Windows Defender's radar (because the .exe is signed).

So that's what you'll need to do: create a DLL that exports the same functions as UxTheme.dll .

The functions don't really need to be reimplemented. In fact, one of them, "OpenThemeData" for example, could contain our "special" code.

Afterwards, the code could also be called in the function executed when the DLL is loaded:

The choice of one or the other doesn't really make much difference. Just bear in mind that you're in the Notepad++ process and that it too has tasks to perform.

It may therefore be a good idea to terminate the Notepad++ process once the task has been completed.

What does our DLL do?

The idea is simple: it must :

  • Stop the explorer.exe process and wait a while, just to make sure it's stopped.
  • Relaunch explorer.exe and freeze it immediately. You can do this using the "CreateProcessA" (or "W") API, by sending it the CREATE_SUSPENDED parameter (corresponding to the value 0x00000004).
  • Once the process is frozen, we inject another DLL of our own design (we'll come back to this later) into the process.
  • Resume execution of the explorer.exe process.
  • End the Notepad++.exe process. The executable follows its own life cycle, so it's best to terminate it.

At this point, we have an explorer.exe process that has loaded our DLL and is executing our code.

Welcome to explorer.exe, make yourself at home. 👌

The code that runs in explorer.exe

To begin with, unlike in the previous chapter, I'm going to give you all the code for this DLL straight away.

The code itself is self-explanatory.

We use MiniHook to replace the "SystemParametersInfoW" function with our own function.

We initialize MiniHook, indicate which function we're targeting, and keep a pointer to the original function so that we can pass on to it any calls we don't wish to filter.

As a reminder, we only want to filter calls that change the background. We don't know if explorer.exe uses this function to do anything else, so if in doubt, we'll let the rest go through, thus avoiding any instabilities.

Our hooked function is super-simple: we check whether explorer.exe passes the "SPI_SETDESKWALLPAPER" parameter (0x0014). If so, we just return "true" and do nothing.

(Plus, it's ultra-lightweight, reducing the number of instructions executed 😂)

When explorer.exe calls this API, it's us who responds.

Conclusion

And that's it, we've seen how to modify a process in memory on Windows.

Oh, and... would you like to see how it works?

The part about the DLL loaded by a signed executable is deliberately very theoretical, without code, because I don't want this to be used for malicious purposes.

Incidentally, I won't be answering questions (usually by e-mail) on this subject 😊.

Have a great day and see you next time! 😁