Summary
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".
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.
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.
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.
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.
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?
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.
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.
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".
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?
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.
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.
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".
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.
The idea is simple: it must :
CREATE_SUSPENDED
parameter (corresponding to the value 0x00000004
).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. 👌
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.
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! 😁