BasicThemer2
BasicThemer2 copied to clipboard
Possibly use detours to prevent DWM APIs from interfering?
Just figured I'd mention that Microsoft's Detours library ( https://github.com/microsoft/Detours ) could potentially be used to prevent DWM APIs from being called as needed. It could likely also be used to redirect attempts to retrieve DWM Visual Style parts to their Basic counterparts, e.g. for the Taskbar, File Explorer navigation bar, etc. It takes some knowledge of C++ to use though, unfortunately, and if my understanding is correct, the resulting DLLs would need to be compiled separately for 32-bit and 64-bit applications.
Thanks, I will look at it.
Finally got around to giving this a shot...
There are still a ton of problems to sort out, and there's no telling whether I have it in me to do so, but I'm...cautiously optimistic about where this is going...
Nice, is it similar to the dwmapi.dll method?
Update: https://github.com/Splitwirez/BasicThemer2/tree/detours
It works well! I think it needs a better UI, but this is still nice to have a program to universally prevent extending Glass other than manually placing files and patching executables.
@Ingan121 The current pop-up is just for testing. I completely agree this needs better UI...though, were you referring solely to the UI for injecting detour DLLs, or to the BasicThemer2 UI as a whole...?
Also, iit occured to to me that we might be better off moving the actual Basic theme frame-y stuff into the C++ component. Not sure so far. Struggling with my limited knowledge of C++ a lot on this tbh
How can I obtain the binary of BasicThemer64.dll? Visual studio 2010, 2017 does not work, when I compile it on Visual Studio 2022, I only get BasicThemer32.dll and setting the target to x64 does not work. ( @Splitwirez )
Update: https://github.com/Splitwirez/BasicThemer2/tree/detours
( @Ingan121 ) 그럼 Splitwirez가 위에서 언급한 방법으로 프로그램 업데이트 예정입니까?
How can I obtain the binary of BasicThemer64.dll? Visual studio 2010, 2017 does not work, when I compile it on Visual Studio 2022, I only get BasicThemer32.dll and setting the target to x64 does not work. ( @Splitwirez )
Update: https://github.com/Splitwirez/BasicThemer2/tree/detours
Uh...clean and Rebuild Solution for x64 first, then switch to AnyCPU and build+run the actual program (along with everything else), I guess. I've mainly been working in VS2019, though I just tried with 2022 and needed a weird workaround to even get the .NET Framework 4.0 stuff to build. It did work after that though...let me know if you still run into trouble.
@Ingan121 Maybe we shouldn't have dropped the .NET Framework requirement to 4.0 after all... :(
Also, aforementioned .NET Framework 4.0 workaround: instructions from https://thomaslevesque.com/2021/11/12/building-a-project-that-target-net-45-in-visual-studio-2022/ but with https://www.nuget.org/packages/microsoft.netframework.referenceassemblies.net40 and the v4.0
folder
It works.
However, how can I edit the code to hide the DOS window for every application I run?
I found the solution, I changed as bool _showConsole = false;
Also, currently this breaks console applications (cmd, nodejs, etc...)
I temporarily fixed it by whitelisting the exe filenames to inject.
if (lpApplicationName.ToLower().EndsWith("\\explorer.exe") || lpApplicationName.ToLower().EndsWith("\\iexplore.exe") || lpApplicationName.ToLower().EndsWith("\\mspaint.exe") || lpApplicationName.ToLower().EndsWith("\\wordpad.exe") || lpApplicationName.ToLower().EndsWith("\\chrome.exe") || lpApplicationName.ToLower().EndsWith("\\firefox.exe") || lpApplicationName.ToLower().EndsWith("\\palemoon.exe") || lpApplicationName.ToLower().EndsWith("\\mypal.exe") || lpApplicationName.ToLower().EndsWith("\\centaury.exe") || lpApplicationName.ToLower().EndsWith("\\basilisk.exe") || lpApplicationName.ToLower().EndsWith("\\moviemaker.exe") || lpApplicationName.ToLower().EndsWith("\\photogallery.exe"))
{
string dllPath = @"C:\BasicThemer2\DetourDLLs\BasicThemer" + (is64bit ? "64" : "32") + ".dll";
InjectDLL(processInfo, dllPath);
}
Also, currently this breaks console applications (cmd, nodejs, etc...)
It also breaks Windows Live Movie Maker, Photo Gallery, Mail. (End of Support does not matter)
@Ingan121 The current pop-up is just for testing. I completely agree this needs better UI...though, were you referring solely to the UI for injecting detour DLLs, or to the BasicThemer2 UI as a whole...?
I only meant the injection UI. I'm thinking of placing a checkbox or button in the main UI for the injection. Also, I think the requirement of running in non-admin mode is not necessary for Windows 10 and later, as Explorer automatically de-elevates itself there. Windows 7 doesn't do this so it would be better to keep this only for 7 and below. (not sure about 8)
It works. image
How did you enable the Win7 ribbons? It looks pretty good.
Uh...clean and Rebuild Solution for x64 first, then switch to AnyCPU and build+run the actual program (along with everything else), I guess. I've mainly been working in VS2019, though I just tried with 2022 and needed a weird workaround to even get the .NET Framework 4.0 stuff to build. It did work after that though...let me know if you still run into trouble.
@Ingan121 Maybe we shouldn't have dropped the .NET Framework requirement to 4.0 after all... :(
Also, aforementioned .NET Framework 4.0 workaround: instructions from https://thomaslevesque.com/2021/11/12/building-a-project-that-target-net-45-in-visual-studio-2022/ but with https://www.nuget.org/packages/microsoft.netframework.referenceassemblies.net40 and the
v4.0
folder
Thanks, I will look at that when I install vs2022. (Actually, I currently even have uninstalled vs2019 for some disk space to update to W11 beta.)
Also, currently this breaks console applications (cmd, nodejs, etc...)
Does this still happen even if _showConsole
is set to false
?
I temporarily fixed it by whitelisting the exe filenames to inject.
if (lpApplicationName.ToLower().EndsWith("\\explorer.exe") || lpApplicationName.ToLower().EndsWith("\\iexplore.exe") || lpApplicationName.ToLower().EndsWith("\\mspaint.exe") || lpApplicationName.ToLower().EndsWith("\\wordpad.exe") || lpApplicationName.ToLower().EndsWith("\\chrome.exe") || lpApplicationName.ToLower().EndsWith("\\firefox.exe") || lpApplicationName.ToLower().EndsWith("\\palemoon.exe") || lpApplicationName.ToLower().EndsWith("\\mypal.exe") || lpApplicationName.ToLower().EndsWith("\\centaury.exe") || lpApplicationName.ToLower().EndsWith("\\basilisk.exe") || lpApplicationName.ToLower().EndsWith("\\moviemaker.exe") || lpApplicationName.ToLower().EndsWith("\\photogallery.exe")) { string dllPath = @"C:\BasicThemer2\DetourDLLs\BasicThemer" + (is64bit ? "64" : "32") + ".dll"; InjectDLL(processInfo, dllPath); }
Where did you do this? And what does it fix?
It also breaks Windows Live Movie Maker, Photo Gallery, Mail. (End of Support does not matter)
Breaks them...how, exactly?
Breaks them...how, exactly?
Windows Live Movie Maker shows error - %1 is not a valid Win32 application. Windows Live Photo Gallery shows error - 0x80040154 (no description) Windows Live Mail just crashes while loading without error messages.
Where did you do this? And what does it fix?
In function public static uint CreateProcessWithBasicThemeDLLs
. After if (!NativeMethodsInj.CreateProcess ...
. It just not injects the DLL for those executables. Not a fundamental solution.
Does this still happen even if _showConsole is set to false?
Oh it fixed it.
How did you enable the Win7 ribbons? It looks pretty good.
@Ingan121 C:\Windows\system32 및 syswow64의 UIRibbon.dll, UIRibbonRes.dll, en-us/UIRibbon.dll.mui를 윈도우 8 빌드 8014에 내장된 것으로 교체하시면 됩니다(윈도우 7의 것으로 해도 작동하지만 안정성 문제가 나타나는 것 같습니다). 32비트 윈도우를 사용 중인 경우 system32에서 앞서 말한 세 파일을 윈도우 8 빌드 8008(32비트)의 것으로 교체하면 됩니다. 필요하시면 파일을 보내드릴 수 있습니다.
@Splitwirez ) - WIll it be possible to make a patchable dwmapi.dll in system32? just injecting basicthemerXX.dll doesn't be a good way since if explorer.exe restarts for some reason it will stop working.
@Splitwirez ) - WIll it be possible to make a patchable dwmapi.dll in system32? just injecting basicthemerXX.dll doesn't be a good way since if explorer.exe restarts for some reason it will stop working.
Actually, my entire motive for trying to do this all via DLL injection was to avoid patching system files.
If we want BasicThemer2 to have any hope of ever amounting to anything more than a toy, it must not jeopardize the user's ability to use their computer - not in the present, nor the unforeseeable future.
Patching system files ensures that our changes will either break, or be broken by, a Windows update eventually. There's no telling what that will look like when it happens, but interfering with the user's ability to use their computer is a very real possibility. This is problem has only been exacerbated by WaaS. Furthermore, any attempt to write code to "un-patch" the system files is at the mercy of whether or not Windows can start up, log in, etc., far enough to run said code successfully. Not likely if the user can't even log in because DWM is toast.
Conversely, DLL injection has to be repeated every time explorer starts...which, critically, includes every time the user logs in. This means Windows starts without our changes affecting it, and allows an opportunity to abort injection if things go south, e.g. perhaps due to unforeseen changes made by a Windows update.
Not only this, but patching system DLLs requires ongoing upkeep, for the event in which the DLLs are updated. DLL injection opens up an opportunity to lessen this pain as well - as long as we only detour documented APIs, any changes Microsoft makes to the DLLs in question outside of those particular APIs have a very real possibility of having no effect on us, meaning our changes may very well continue to work as they did previously. Any changes Microsoft makes to the DLLs in question which do affect the APIs we're concerned with...are highly unlikely to occur - I'm sure you know how Microsoft is about backwards-compatibility. We can use that to our advantage by using DLL injection, to achieve greater sustainability...and if you ask me, every shred counts these days, given how hard it's gotten to achieve any degree of sustainability.
You're not wrong that we don't have a solution for the explorer restart scenario, but I'd argue we'd be fools to turn away from code injection because of that alone, especially without trying everything we can to address the explorer restart scenario as best we can.
Admittedly, I do fear that we've veered too close to the present limits of my knowledge of C++ for my comfort, but I do intend to resume my research sooner or later, if nothing else.