diff --git a/GlosSI.sln b/GlosSI.sln index 5b2d049..767b3c5 100644 --- a/GlosSI.sln +++ b/GlosSI.sln @@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GlosSITarget", "GlosSITarge EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GlosSIConfig", "GlosSIConfig\GlosSIConfig.vcxproj", "{4B42920B-3CC6-475F-A5B3-441337968483}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UWPOverlayEnablerDLL", "UWPOverlayEnablerDLL\UWPOverlayEnablerDLL.vcxproj", "{50212575-87E2-40AB-87EE-EAED19C8EBB2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -29,6 +31,14 @@ Global {4B42920B-3CC6-475F-A5B3-441337968483}.Release|x64.ActiveCfg = Release|x64 {4B42920B-3CC6-475F-A5B3-441337968483}.Release|x64.Build.0 = Release|x64 {4B42920B-3CC6-475F-A5B3-441337968483}.Release|x86.ActiveCfg = Release|x64 + {50212575-87E2-40AB-87EE-EAED19C8EBB2}.Debug|x64.ActiveCfg = Debug|x64 + {50212575-87E2-40AB-87EE-EAED19C8EBB2}.Debug|x64.Build.0 = Debug|x64 + {50212575-87E2-40AB-87EE-EAED19C8EBB2}.Debug|x86.ActiveCfg = Debug|Win32 + {50212575-87E2-40AB-87EE-EAED19C8EBB2}.Debug|x86.Build.0 = Debug|Win32 + {50212575-87E2-40AB-87EE-EAED19C8EBB2}.Release|x64.ActiveCfg = Release|x64 + {50212575-87E2-40AB-87EE-EAED19C8EBB2}.Release|x64.Build.0 = Release|x64 + {50212575-87E2-40AB-87EE-EAED19C8EBB2}.Release|x86.ActiveCfg = Release|Win32 + {50212575-87E2-40AB-87EE-EAED19C8EBB2}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/UWPOverlayEnablerDLL/UWPOverlayEnablerDLL.vcxproj b/UWPOverlayEnablerDLL/UWPOverlayEnablerDLL.vcxproj new file mode 100644 index 0000000..887bb14 --- /dev/null +++ b/UWPOverlayEnablerDLL/UWPOverlayEnablerDLL.vcxproj @@ -0,0 +1,165 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {50212575-87e2-40ab-87ee-eaed19c8ebb2} + UWPOverlayEnablerDLL + 10.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + ..\deps\subhook;$(IncludePath) + + + false + ..\deps\subhook;$(IncludePath) + + + + Level3 + true + WIN32;_DEBUG;UWPOVERLAYENABLERDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;UWPOVERLAYENABLERDLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;UWPOVERLAYENABLERDLL_EXPORTS;_WINDOWS;_USRDLL;SUBHOOK_STATIC;%(PreprocessorDefinitions) + true + NotUsing + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + NDEBUG;UWPOVERLAYENABLERDLL_EXPORTS;_WINDOWS;_USRDLL;SUBHOOK_STATIC;%(PreprocessorDefinitions) + true + NotUsing + pch.h + + + Windows + true + true + true + false + + + + + + + + + + + + + \ No newline at end of file diff --git a/UWPOverlayEnablerDLL/UWPOverlayEnablerDLL.vcxproj.filters b/UWPOverlayEnablerDLL/UWPOverlayEnablerDLL.vcxproj.filters new file mode 100644 index 0000000..7ceeb6c --- /dev/null +++ b/UWPOverlayEnablerDLL/UWPOverlayEnablerDLL.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/UWPOverlayEnablerDLL/dllmain.cpp b/UWPOverlayEnablerDLL/dllmain.cpp new file mode 100644 index 0000000..3acf8b8 --- /dev/null +++ b/UWPOverlayEnablerDLL/dllmain.cpp @@ -0,0 +1,128 @@ +/* +Copyright 2021 Peter Repukat - FlatspotSoftware + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* + +There are two (known to me, at time of writing) ways to get a working overlay for UWP Apps +1. Create an accessibility app + Set UIAcces in manifest to true + This however requires that the application is digitally signed + and is run from a trusted directory (Program Files; System32) + At this point UWP overlays are not a technical issue anymore, but a monetary + I have no interest in spending ~100 bucks a year just to provide this functionality to users. + + You could also self-sign the application, but installing a trusted root CA is a security risk + +2. Use undocumented SetWindowBand function + This function however is not freely callable from every process. + Even when injected into explorer.exe, it doesn't seem to work when just calling normally... + So let's hook the original function, and try to do "the magic" then + This seemingly works ¯\_(ツ)_/¯ + + "The magic": + Hook SetWindowBand + One called, find GlosSI Window + Set GlosSI Window to notification ZBID (Doesn't seem to require any special stuff) + Self-Eject + + **PROFIT!** + +*/ + +#define WIN32_LEAN_AND_MEAN +#include + +#define SUBHOOK_STATIC +#include +#include + +enum ZBID +{ + ZBID_DEFAULT = 0, + ZBID_DESKTOP = 1, + ZBID_UIACCESS = 2, + ZBID_IMMERSIVE_IHM = 3, + ZBID_IMMERSIVE_NOTIFICATION = 4, + ZBID_IMMERSIVE_APPCHROME = 5, + ZBID_IMMERSIVE_MOGO = 6, + ZBID_IMMERSIVE_EDGY = 7, + ZBID_IMMERSIVE_INACTIVEMOBODY = 8, + ZBID_IMMERSIVE_INACTIVEDOCK = 9, + ZBID_IMMERSIVE_ACTIVEMOBODY = 10, + ZBID_IMMERSIVE_ACTIVEDOCK = 11, + ZBID_IMMERSIVE_BACKGROUND = 12, + ZBID_IMMERSIVE_SEARCH = 13, + ZBID_GENUINE_WINDOWS = 14, + ZBID_IMMERSIVE_RESTRICTED = 15, + ZBID_SYSTEM_TOOLS = 16, + ZBID_LOCK = 17, + ZBID_ABOVELOCK_UX = 18, +}; +typedef BOOL(WINAPI* fSetWindowBand)(HWND hWnd, HWND hwndInsertAfter, DWORD dwBand); + + +subhook::Hook SetWindowBandHook; +fSetWindowBand SetWindowBand; + +std::atomic allow_exit = false; + +BOOL WINAPI SetGlosSIWindowBand(HWND hWnd, HWND hwndInsertAfter, DWORD dwBand) +{ + subhook::ScopedHookRemove remove(&SetWindowBandHook); + const auto glossi_hwnd = FindWindowA(nullptr, "GlosSITarget"); + if (glossi_hwnd) + { + // Most window bands don't really seem to work. + // However, notification does! + SetWindowBand(glossi_hwnd, nullptr, ZBID_IMMERSIVE_NOTIFICATION); + allow_exit = true; + } + return SetWindowBand(hWnd, hwndInsertAfter, dwBand); +} + +DWORD WINAPI HackThread(HMODULE hModule) +{ + while (!allow_exit) + { + Sleep(10); + } + if (SetWindowBandHook.IsInstalled()) + SetWindowBandHook.Remove(); + FreeLibraryAndExitThread(hModule, 0); +} + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + if (ul_reason_for_call == DLL_PROCESS_ATTACH) + { + const auto hpath = LoadLibrary(L"user32.dll"); + if (hpath) + { + SetWindowBand = reinterpret_cast(GetProcAddress(hpath, "SetWindowBand")); + SetWindowBandHook.Install(GetProcAddress(hpath, "SetWindowBand"), &SetGlosSIWindowBand, subhook::HookFlags::HookFlag64BitOffset); + CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)HackThread, hModule, 0, nullptr)); + } + } + else if (ul_reason_for_call == DLL_PROCESS_DETACH) { + if (SetWindowBandHook.IsInstalled()) + SetWindowBandHook.Remove(); + } + return TRUE; +} +