mirror of
https://github.com/valinet/ExplorerPatcher.git
synced 2026-04-20 01:03:10 +08:00
568 lines
23 KiB
C++
568 lines
23 KiB
C++
#include <windows.ui.xaml.h>
|
|
|
|
#include <wrl/client.h>
|
|
#include <wrl/implements.h>
|
|
#include <wrl/wrappers/corewrappers.h>
|
|
#include <wil/result_macros.h>
|
|
|
|
// ReSharper disable once CppUnusedIncludeDirective
|
|
#include "ClassicWinRtForwardDecl.h"
|
|
#include "def.h"
|
|
#include "hooking.h"
|
|
#include "osutility.h"
|
|
#include "SimpleBoxer.h"
|
|
#include "utility.h"
|
|
#include "valinet/hooking/iatpatch.h"
|
|
|
|
// We don't need logging here
|
|
#include "inc/PushNoWilResultMacrosLogging.h"
|
|
|
|
using namespace Microsoft::WRL;
|
|
|
|
namespace wf = ABI::Windows::Foundation;
|
|
namespace wfc = ABI::Windows::Foundation::Collections;
|
|
namespace wux = ABI::Windows::UI::Xaml;
|
|
|
|
EXTERN_C_START
|
|
|
|
void InjectShellExperienceHostFor22H2OrHigher();
|
|
|
|
void* memmem(void* haystack, size_t haystacklen, void* needle, size_t needlelen);
|
|
|
|
void InjectShellExperienceHost()
|
|
{
|
|
if (!IsWindows11())
|
|
{
|
|
return;
|
|
}
|
|
if (IsWindows11Version22H2OrHigher())
|
|
{
|
|
InjectShellExperienceHostFor22H2OrHigher();
|
|
return;
|
|
}
|
|
|
|
HKEY hKey;
|
|
if (RegOpenKeyW(HKEY_CURRENT_USER, _T(SEH_REGPATH), &hKey) != ERROR_SUCCESS)
|
|
{
|
|
return;
|
|
}
|
|
RegCloseKey(hKey);
|
|
HMODULE hQA = LoadLibraryW(L"Windows.UI.QuickActions.dll");
|
|
if (hQA)
|
|
{
|
|
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hQA;
|
|
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
|
|
{
|
|
PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS64)((u_char*)dosHeader + dosHeader->e_lfanew);
|
|
if (ntHeader->Signature == IMAGE_NT_SIGNATURE)
|
|
{
|
|
PBYTE pSEHPatchArea = nullptr;
|
|
BYTE seh_pattern1[14] =
|
|
{
|
|
// mov al, 1
|
|
0xB0, 0x01,
|
|
// jmp + 2
|
|
0xEB, 0x02,
|
|
// xor al, al
|
|
0x32, 0xC0,
|
|
// add rsp, 0x20
|
|
0x48, 0x83, 0xC4, 0x20,
|
|
// pop rdi
|
|
0x5F,
|
|
// pop rsi
|
|
0x5E,
|
|
// pop rbx
|
|
0x5B,
|
|
// ret
|
|
0xC3
|
|
};
|
|
BYTE seh_off = 12;
|
|
BYTE seh_pattern2[5] =
|
|
{
|
|
// mov r8b, 3
|
|
0x41, 0xB0, 0x03,
|
|
// mov dl, 1
|
|
0xB2, 0x01
|
|
};
|
|
bool bTwice = false;
|
|
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeader);
|
|
for (unsigned int i = 0; i < ntHeader->FileHeader.NumberOfSections; ++i)
|
|
{
|
|
if (section->Characteristics & IMAGE_SCN_CNT_CODE)
|
|
{
|
|
if (section->SizeOfRawData && !bTwice)
|
|
{
|
|
PBYTE pSectionBegin = (PBYTE)hQA + section->VirtualAddress;
|
|
//DWORD dwOldProtect;
|
|
//VirtualProtect(pSectionBegin, section->SizeOfRawData, PAGE_EXECUTE_READWRITE, &dwOldProtect);
|
|
PBYTE pCandidate = nullptr;
|
|
while (true)
|
|
{
|
|
pCandidate = (PBYTE)memmem(
|
|
!pCandidate ? pSectionBegin : pCandidate,
|
|
!pCandidate ? section->SizeOfRawData : (uintptr_t)section->SizeOfRawData - (uintptr_t)(pCandidate - pSectionBegin),
|
|
seh_pattern1,
|
|
sizeof(seh_pattern1)
|
|
);
|
|
if (!pCandidate)
|
|
{
|
|
break;
|
|
}
|
|
PBYTE pCandidate2 = pCandidate - seh_off - sizeof(seh_pattern2);
|
|
if (pCandidate2 > (PBYTE)(UINT_PTR)section->VirtualAddress)
|
|
{
|
|
if (memmem(pCandidate2, sizeof(seh_pattern2), seh_pattern2, sizeof(seh_pattern2)))
|
|
{
|
|
if (!pSEHPatchArea)
|
|
{
|
|
pSEHPatchArea = pCandidate;
|
|
}
|
|
else
|
|
{
|
|
bTwice = true;
|
|
}
|
|
}
|
|
}
|
|
pCandidate += sizeof(seh_pattern1);
|
|
}
|
|
//VirtualProtect(pSectionBegin, section->SizeOfRawData, dwOldProtect, &dwOldProtect);
|
|
}
|
|
}
|
|
section++;
|
|
}
|
|
if (pSEHPatchArea && !bTwice)
|
|
{
|
|
DWORD dwOldProtect;
|
|
VirtualProtect(pSEHPatchArea, sizeof(seh_pattern1), PAGE_EXECUTE_READWRITE, &dwOldProtect);
|
|
pSEHPatchArea[2] = 0x90;
|
|
pSEHPatchArea[3] = 0x90;
|
|
VirtualProtect(pSEHPatchArea, sizeof(seh_pattern1), dwOldProtect, &dwOldProtect);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// On 22H2 builds, the Windows 10 flyouts for network and battery can be enabled
|
|
// by patching either of the following functions in ShellExperienceHost. I didn't
|
|
// see any differences when patching with any of the 3 methods, although
|
|
// `SharedUtilities::IsWindowsLite` seems to be invoked in more places, whereas `GetProductInfo`
|
|
// and `RtlGetDeviceFamilyInfoEnum` are only called in `FlightHelper::CalculateRepaintEnabled`
|
|
// and either seems to get the job done. YMMV
|
|
|
|
/*LSTATUS WINAPI SEH_RegGetValueW(HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
|
|
{
|
|
if (!lstrcmpW(lpValue, L"UseLiteLayout")) { *(DWORD*)pvData = 1; return ERROR_SUCCESS; }
|
|
return RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData);
|
|
}*/
|
|
|
|
/*BOOL WINAPI SEH_RtlGetDeviceFamilyInfoEnum(INT64 u0, PDWORD u1, INT64 u2)
|
|
{
|
|
*u1 = 10;
|
|
return TRUE;
|
|
}*/
|
|
|
|
BOOL WINAPI SEH_GetProductInfo(DWORD dwOSMajorVersion, DWORD dwOSMinorVersion, DWORD dwSpMajorVersion, DWORD dwSpMinorVersion, PDWORD pdwReturnedProductType)
|
|
{
|
|
*pdwReturnedProductType = 119;
|
|
return TRUE;
|
|
}
|
|
|
|
static bool g_bQuickActionControlTemplatesPatched;
|
|
|
|
// Fix battery flyout crashing on 25951+
|
|
void HandleLoadedQuickActions(HMODULE hModule)
|
|
{
|
|
if (!hModule)
|
|
{
|
|
return;
|
|
}
|
|
|
|
static bool bPatched = false;
|
|
if (bPatched)
|
|
{
|
|
return;
|
|
}
|
|
bPatched = true;
|
|
|
|
PBYTE pSearch;
|
|
DWORD cbSearch;
|
|
if (TextSectionBeginAndSize(hModule, &pSearch, &cbSearch))
|
|
{
|
|
#if defined(_M_X64)
|
|
// Note: These patterns will break when the class sizes change!
|
|
|
|
PBYTE pfn = nullptr;
|
|
|
|
// Find source
|
|
// 48 89 45 50 BA 90 00 00 00 8D 4A E8 FF 15 ?? ?? ?? ?? 48 89 45 58 48 8B C8 E8 ?? ?? ?? ?? 48 8B F0
|
|
// ^^^^^^^^^^^^^^^^^^^^^^^ . ^^^^^^^^^^^
|
|
// ref new QuickActions::QuickActionTemplates();
|
|
// Ref: QuickActions::QuickActionTemplates::Instance::get()
|
|
PBYTE matchSource = (PBYTE)FindPattern(
|
|
pSearch, cbSearch,
|
|
"\x48\x89\x45\x50\xBA\x90\x00\x00\x00\x8D\x4A\xE8\xFF\x15\x00\x00\x00\x00\x48\x89\x45\x58\x48\x8B\xC8\xE8\x00\x00\x00\x00\x48\x8B\xF0",
|
|
"xxxxxxxxxxxxxx????xxxxxxxx????xxx"
|
|
);
|
|
if (matchSource)
|
|
{
|
|
pfn = matchSource + 25;
|
|
pfn += 5 + *(int*)(pfn + 1);
|
|
}
|
|
|
|
// Find target
|
|
// 48 8B D0 48 8B CB E8 ?? ?? ?? ?? 90 4D 85 ?? 74 10 49 8B ?? 49 8B ?? 48 8B 40 10 E8 ?? ?? ?? ?? 90 49 8B CC
|
|
// xxxxxxxxxxxxxx nop
|
|
// E8 ?? ?? ?? ?? 48 8B D3 48 8B CE E8 ?? ?? ?? ?? BA B8 00 00 00 8D 4A E8 FF 15 ?? ?? ?? ?? 48 89 45 ??
|
|
// xxxxxxxxxxxxxxxxxxxxxxx mov edx & lea rcx
|
|
// 48 8B C8 E8 ?? ?? ?? ?? 4C 8B
|
|
// . xxxxxxxxxxx ctor call
|
|
// ref new QuickActions::ControlCenter::ControlCenterTemplates();
|
|
// Ref: QuickActions::QuickActionControl::QuickActionControl()
|
|
PBYTE matchTarget = (PBYTE)FindPattern(
|
|
pSearch, cbSearch,
|
|
"\x48\x8B\xD0\x48\x8B\xCB\xE8\x00\x00\x00\x00\x90\x4D\x85\x00\x74\x10\x49\x8B\x00\x49\x8B\x00\x48\x8B\x40\x10\xE8\x00\x00\x00\x00\x90\x49\x8B\xCC"
|
|
"\xE8\x00\x00\x00\x00\x48\x8B\xD3\x48\x8B\xCE\xE8\x00\x00\x00\x00\xBA\xB8\x00\x00\x00\x8D\x4A\xE8\xFF\x15\x00\x00\x00\x00\x48\x89\x45\x00"
|
|
"\x48\x8B\xC8\xE8\x00\x00\x00\x00\x4C\x8B",
|
|
"xxxxxxx????xxx?xxxx?xx?xxxxx????xxxx"
|
|
"x????xxxxxxx????xxxxxxxxxx????xxx?"
|
|
"xxxx????xx"
|
|
);
|
|
|
|
if (matchSource && matchTarget && pfn)
|
|
{
|
|
PBYTE pinsnMovEdxLeaRcxSrc = matchSource + 4;
|
|
|
|
PBYTE pinsnCallLoadComponent = matchTarget + 6;
|
|
PBYTE pinsnMovEdxLeaRcxDst = matchTarget + 52;
|
|
PBYTE pinsnCallCtor = matchTarget + 73;
|
|
|
|
DWORD dwOldProtect;
|
|
if (VirtualProtect(matchTarget, 80, PAGE_EXECUTE_READWRITE, &dwOldProtect))
|
|
{
|
|
memset(pinsnCallLoadComponent, 0x90, 5); // nop
|
|
memcpy(pinsnMovEdxLeaRcxDst, pinsnMovEdxLeaRcxSrc, 8); // change Platform::Details::Heap::Allocate(x, x) args
|
|
*(int*)(pinsnCallCtor + 1) = (int)((INT_PTR)pfn - (INT_PTR)(pinsnCallCtor + 5)); // change ctor call target
|
|
g_bQuickActionControlTemplatesPatched = true;
|
|
VirtualProtect(matchTarget, 80, dwOldProtect, &dwOldProtect);
|
|
}
|
|
}
|
|
#elif defined(_M_ARM64)
|
|
// Note: These patterns will break when the class sizes change!
|
|
|
|
PBYTE pfn = nullptr;
|
|
|
|
// Find source
|
|
// B7 17 00 F9 ?? ?? ?? ?? ?? ?? ?? ?? 01 12 80 D2 00 0F 80 D2 00 01 3F D6 A0 13 00 F9 ?? ?? ?? ?? ?? 03 00 AA
|
|
// ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^
|
|
// ref new QuickActions::QuickActionTemplates();
|
|
// Ref: QuickActions::QuickActionTemplates::Instance::get()
|
|
PBYTE matchSource = (PBYTE)FindPattern_4_(
|
|
pSearch, cbSearch,
|
|
"\xB7\x17\x00\xF9\x00\x00\x00\x00\x00\x00\x00\x00\x01\x12\x80\xD2\x00\x0F\x80\xD2\x00\x01\x3F\xD6\xA0\x13\x00\xF9\x00\x00\x00\x00\x00\x03\x00\xAA",
|
|
"xxxx????????xxxxxxxxxxxxxxxx?????xxx"
|
|
);
|
|
if (matchSource)
|
|
{
|
|
pfn = matchSource + 28;
|
|
pfn = (PBYTE)ARM64_FollowBL((DWORD*)pfn);
|
|
}
|
|
|
|
// Find target
|
|
// E1 03 ?? AA E0 03 ?? AA ?? ?? ?? ?? 1F 20 03 D5 E0 03 ?? AA ?? ?? ?? ?? 1F 20 03 D5 E0 03 ?? AA ?? ?? ?? ??
|
|
// xxxxxxxxxxx nop
|
|
// E1 03 ?? AA E0 03 ?? AA ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 01 17 80 D2 00 14 80 D2 00 01 3F D6 40 03 00 F9
|
|
// xxxxxxxxxxxxxxxxxxxxxxx mov x1 & mov x0
|
|
// ?? ?? ?? ?? ?? 03 00 AA
|
|
// xxxxxxxxxxx ctor call
|
|
// ref new QuickActions::ControlCenter::ControlCenterTemplates();
|
|
// Ref: QuickActions::QuickActionControl::QuickActionControl()
|
|
PBYTE matchTarget = (PBYTE)FindPattern_4_(
|
|
pSearch, cbSearch,
|
|
"\xE1\x03\x00\xAA\xE0\x03\x00\xAA\x00\x00\x00\x00\x1F\x20\x03\xD5\xE0\x03\x00\xAA\x00\x00\x00\x00\x1F\x20\x03\xD5\xE0\x03\x00\xAA\x00\x00\x00\x00"
|
|
"\xE1\x03\x00\xAA\xE0\x03\x00\xAA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x17\x80\xD2\x00\x14\x80\xD2\x00\x01\x3F\xD6\x40\x03\x00\xF9"
|
|
"\x00\x00\x00\x00\x00\x03\x00\xAA",
|
|
"xx?xxx?x????xxxxxx?x????xxxxxx?x????"
|
|
"xx?xxx?x????????????xxxxxxxxxxxxxxxx"
|
|
"?????xxx"
|
|
);
|
|
|
|
if (matchSource && matchTarget && pfn)
|
|
{
|
|
DWORD* pinsnMovX1MovX0Src = (DWORD*)(matchSource + 12);
|
|
|
|
DWORD* pinsnBLLoadComponent = (DWORD*)(matchTarget + 8);
|
|
DWORD* pinsnMovX1MovX0Dst = (DWORD*)(matchTarget + 56);
|
|
DWORD* pinsnBLTemplatesCtor = (DWORD*)(matchTarget + 72);
|
|
|
|
DWORD insnBLNew = ARM64_MakeBL((int)(((UINT_PTR)pfn - (UINT_PTR)pinsnBLTemplatesCtor) / 4));
|
|
|
|
DWORD dwOldProtect;
|
|
if (insnBLNew && VirtualProtect(matchTarget, 80, PAGE_EXECUTE_READWRITE, &dwOldProtect))
|
|
{
|
|
*pinsnBLLoadComponent = 0xD503201F; // nop
|
|
memcpy(pinsnMovX1MovX0Dst, pinsnMovX1MovX0Src, 8); // change Platform::Details::Heap::Allocate(x, x) args
|
|
*pinsnBLTemplatesCtor = insnBLNew; // change ctor call target
|
|
g_bQuickActionControlTemplatesPatched = true;
|
|
VirtualProtect(matchTarget, 80, dwOldProtect, &dwOldProtect);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// Revert network flyout quick actions buttons to Cobalt-Nickel style
|
|
// If we're doing the quick actions patch but not this, they will only appear as non-interactive text blocks.
|
|
HRESULT WINAPI NetworkUX_WindowsCreateStringReference(
|
|
PCWSTR sourceString, UINT32 length, HSTRING_HEADER* hstringHeader, HSTRING* string)
|
|
{
|
|
static constexpr WCHAR c_szToggleButtonWinuiFluentTemplate[] = L"ToggleButtonWinuiFluentTemplate";
|
|
static constexpr WCHAR c_szQuickToggleWinuiFluentTemplate[] = L"QuickToggleWinuiFluentTemplate";
|
|
|
|
switch (length)
|
|
{
|
|
case ARRAYSIZE(c_szToggleButtonWinuiFluentTemplate) - 1:
|
|
if (wcscmp(sourceString, c_szToggleButtonWinuiFluentTemplate) == 0 && g_bQuickActionControlTemplatesPatched)
|
|
{
|
|
sourceString = c_szQuickToggleWinuiFluentTemplate;
|
|
length = ARRAYSIZE(c_szQuickToggleWinuiFluentTemplate) - 1;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return WindowsCreateStringReference(sourceString, length, hstringHeader, string);
|
|
}
|
|
|
|
HRESULT NetworkUX_PatchResourceDictionary()
|
|
{
|
|
SimpleBoxer_WilInitVars();
|
|
ComPtr<IInspectable> spKey, spValue;
|
|
|
|
ComPtr<wfc::IMap<IInspectable*, IInspectable*>> spResourceDictionary_Map; // = wux::Application::Current().Resources();
|
|
{
|
|
ComPtr<wux::IApplicationStatics> spApplicationStatics;
|
|
RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory(
|
|
Wrappers::HStringReference(RuntimeClass_Windows_UI_Xaml_Application).Get(), &spApplicationStatics));
|
|
|
|
ComPtr<wux::IApplication> spApplication;
|
|
RETURN_IF_FAILED(spApplicationStatics->get_Current(&spApplication));
|
|
|
|
ComPtr<wux::IResourceDictionary> spResourceDictionary;
|
|
RETURN_IF_FAILED(spApplication->get_Resources(&spResourceDictionary));
|
|
RETURN_IF_FAILED(spResourceDictionary.As(&spResourceDictionary_Map));
|
|
}
|
|
|
|
ComPtr<IInspectable> spQuickActionPanelMargin; // = spResourceDictionary.Lookup(L"QuickActionPanelMargin");
|
|
ComPtr<wux::IStyle> spQuickActionControlStyle; // = spResourceDictionary.Lookup(L"QuickActionControlStyle").try_as<wux::IStyle>();
|
|
{
|
|
{
|
|
RETURN_IF_FAILED(SimpleBoxer_BoxValue(L"QuickActionPanelMargin", &spKey));
|
|
spResourceDictionary_Map->Lookup(spKey.Get(), &spQuickActionPanelMargin);
|
|
}
|
|
{
|
|
ComPtr<IInspectable> spQuickActionControlStyle_Object;
|
|
RETURN_IF_FAILED(SimpleBoxer_BoxValue(L"QuickActionControlStyle", &spKey));
|
|
if (SUCCEEDED(spResourceDictionary_Map->Lookup(spKey.Get(), &spQuickActionControlStyle_Object)))
|
|
{
|
|
spQuickActionControlStyle_Object.As(&spQuickActionControlStyle);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Old: <Thickness x:Key="QuickActionPanelMargin" Value="12,0,0,12" /> <-- change back to this
|
|
// New: <Thickness x:Key="QuickActionPanelMargin" Value="12,0,24,0" />
|
|
if (spQuickActionPanelMargin.Get())
|
|
{
|
|
boolean bReplaced;
|
|
RETURN_IF_FAILED(SimpleBoxer_BoxValue(L"QuickActionPanelMargin", &spKey));
|
|
RETURN_IF_FAILED(SimpleBoxer_BoxValue(wux::Thickness(12.0, 0.0, 0.0, 12.0), &spValue));
|
|
RETURN_IF_FAILED(spResourceDictionary_Map->Insert(spKey.Get(), spValue.Get(), &bReplaced));
|
|
}
|
|
|
|
// Old: Margin=(4,0,0,4) Width=90 Height=64 <-- change back to this
|
|
// New: Margin=(12,0,0,0) Width=96 Height=90
|
|
if (spQuickActionControlStyle.Get())
|
|
{
|
|
ComPtr<wfc::IVector<wux::SetterBase*>> spSetters_Vector; // = spQuickActionControlStyle.Setters();
|
|
{
|
|
ComPtr<wux::ISetterBaseCollection> spSetters;
|
|
RETURN_IF_FAILED(spQuickActionControlStyle->get_Setters(&spSetters));
|
|
RETURN_IF_FAILED(spSetters.As(&spSetters_Vector));
|
|
}
|
|
|
|
RETURN_IF_FAILED(spSetters_Vector->Clear());
|
|
|
|
ComPtr<wux::ISetterFactory> spSetterFactory;
|
|
RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory(
|
|
Wrappers::HStringReference(RuntimeClass_Windows_UI_Xaml_Setter).Get(), &spSetterFactory));
|
|
|
|
ComPtr<wux::IDependencyProperty> spMarginProperty, spWidthProperty, spHeightProperty;
|
|
{
|
|
ComPtr<wux::IFrameworkElementStatics> spFrameworkElementStatics;
|
|
RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory(
|
|
Wrappers::HStringReference(RuntimeClass_Windows_UI_Xaml_FrameworkElement).Get(), &spFrameworkElementStatics));
|
|
|
|
RETURN_IF_FAILED(spFrameworkElementStatics->get_MarginProperty(&spMarginProperty));
|
|
RETURN_IF_FAILED(spFrameworkElementStatics->get_WidthProperty(&spWidthProperty));
|
|
RETURN_IF_FAILED(spFrameworkElementStatics->get_HeightProperty(&spHeightProperty));
|
|
}
|
|
|
|
struct
|
|
{
|
|
wux::IDependencyProperty* pProperty;
|
|
ComPtr<IInspectable> spValue;
|
|
} rgSettersToAdd[] =
|
|
{
|
|
{ spMarginProperty.Get(), SimpleBoxer_InlineBoxValue(wux::Thickness(4.0, 0.0, 0.0, 4.0)) },
|
|
{ spWidthProperty.Get(), SimpleBoxer_InlineBoxValue(90.0) },
|
|
{ spHeightProperty.Get(), SimpleBoxer_InlineBoxValue(64.0) },
|
|
};
|
|
|
|
for (const auto& entry : rgSettersToAdd)
|
|
{
|
|
RETURN_IF_NULL_ALLOC(entry.spValue);
|
|
|
|
ComPtr<wux::ISetter> spSetter;
|
|
RETURN_IF_FAILED(spSetterFactory->CreateInstance(entry.pProperty, entry.spValue.Get(), &spSetter));
|
|
|
|
ComPtr<wux::ISetterBase> spSetter_Base;
|
|
RETURN_IF_FAILED(spSetter.As(&spSetter_Base));
|
|
RETURN_IF_FAILED(spSetters_Vector->Append(spSetter_Base.Get()));
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
void (*NetworkUX_App_LoadResourceDictionariesFunc)();
|
|
void NetworkUX_App_LoadResourceDictionariesHook()
|
|
{
|
|
NetworkUX_App_LoadResourceDictionariesFunc();
|
|
|
|
if (g_bQuickActionControlTemplatesPatched)
|
|
{
|
|
NetworkUX_PatchResourceDictionary();
|
|
}
|
|
}
|
|
|
|
void HandleLoadedNetworkUX(HMODULE hModule)
|
|
{
|
|
if (!hModule)
|
|
{
|
|
return;
|
|
}
|
|
|
|
static bool bPatched = false;
|
|
if (bPatched)
|
|
{
|
|
return;
|
|
}
|
|
bPatched = true;
|
|
|
|
VnPatchIAT(hModule, (PSTR)"api-ms-win-core-winrt-string-l1-1-0.dll", (PSTR)"WindowsCreateStringReference", (uintptr_t)NetworkUX_WindowsCreateStringReference);
|
|
|
|
PBYTE pSearch;
|
|
DWORD cbSearch;
|
|
if (TextSectionBeginAndSize(hModule, &pSearch, &cbSearch))
|
|
{
|
|
#if defined(_M_X64)
|
|
// NetworkUX::App::LoadResourceDictionaries()
|
|
// 48 8B 40 10 E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 80 3D ?? ?? ?? ?? 00 75 05 E8
|
|
// . ^^^^^^^^^^^
|
|
// Ref: NetworkUX::App::StaticOnLaunched()
|
|
PBYTE match = (PBYTE)FindPattern(
|
|
pSearch, cbSearch,
|
|
"\x48\x8B\x40\x10\xE8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x80\x3D\x00\x00\x00\x00\x00\x75\x05\xE8",
|
|
"xxxxx????x????xx????xxxx"
|
|
);
|
|
if (match)
|
|
{
|
|
match += 9;
|
|
match += 5 + *(int*)(match + 1);
|
|
}
|
|
#elif defined(_M_ARM64)
|
|
// NetworkUX::App::LoadResourceDictionaries()
|
|
// E0 03 ?? AA ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 08 ?? ?? ?? 48 00 00 35
|
|
// ^^^^^^^^^^^
|
|
// Ref: NetworkUX::App::StaticOnLaunched()
|
|
PBYTE match = (PBYTE)FindPattern_4_(
|
|
pSearch, cbSearch,
|
|
"\xE0\x03\x00\xAA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x48\x00\x00\x35",
|
|
"xx?x????????????x???xxxx"
|
|
);
|
|
if (match)
|
|
{
|
|
match += 8;
|
|
match = (PBYTE)ARM64_FollowBL((DWORD*)match);
|
|
}
|
|
#endif
|
|
if (match)
|
|
{
|
|
NetworkUX_App_LoadResourceDictionariesFunc = reinterpret_cast<decltype(NetworkUX_App_LoadResourceDictionariesFunc)>(match);
|
|
funchook_prepare(funchook, (void**)&NetworkUX_App_LoadResourceDictionariesFunc, NetworkUX_App_LoadResourceDictionariesHook);
|
|
}
|
|
}
|
|
}
|
|
|
|
typedef HRESULT (WINAPI* GetActivationFactoryByPCWSTR_t)(PCWSTR activatableClassId, REFIID riid, void** ppv);
|
|
GetActivationFactoryByPCWSTR_t GetActivationFactoryByPCWSTRFunc;
|
|
HRESULT WINAPI SEH_GetActivationFactoryByPCWSTR(PCWSTR activatableClassId, REFIID riid, void** ppv)
|
|
{
|
|
HRESULT hr = GetActivationFactoryByPCWSTRFunc(activatableClassId, riid, ppv);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (wcscmp(activatableClassId, L"QuickActions.quickactions_XamlTypeInfo.XamlMetaDataProvider") == 0)
|
|
{
|
|
HandleLoadedQuickActions(GetModuleHandleW(L"Windows.UI.QuickActions.dll"));
|
|
}
|
|
else if (wcscmp(activatableClassId, L"NetworkUX.networkux_XamlTypeInfo.XamlMetaDataProvider") == 0)
|
|
{
|
|
HandleLoadedNetworkUX(GetModuleHandleW(L"NetworkUX.dll"));
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
void InjectShellExperienceHostFor22H2OrHigher()
|
|
{
|
|
if (!IsWindows11Version22H2Build1413OrHigher())
|
|
{
|
|
HKEY hKey;
|
|
if (RegOpenKeyW(HKEY_CURRENT_USER, _T(SEH_REGPATH), &hKey) == ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hKey);
|
|
HMODULE hQA = LoadLibraryW(L"Windows.UI.QuickActions.dll");
|
|
if (hQA)
|
|
{
|
|
VnPatchIAT(hQA, (PSTR)"api-ms-win-core-sysinfo-l1-2-0.dll", (PSTR)"GetProductInfo", (uintptr_t)SEH_GetProductInfo);
|
|
// VnPatchIAT(hQA, "ntdll.dll", "RtlGetDeviceFamilyInfoEnum", SEH_RtlGetDeviceFamilyInfoEnum);
|
|
// VnPatchIAT(hQA, "api-ms-win-core-registry-l1-1-0.dll", "RegGetValueW", SEH_RegGetValueW);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (global_rovi.dwBuildNumber >= 25951)
|
|
{
|
|
HMODULE hWincorlib = GetModuleHandleW(L"wincorlib.DLL");
|
|
if (hWincorlib)
|
|
{
|
|
GetActivationFactoryByPCWSTRFunc = (GetActivationFactoryByPCWSTR_t)GetProcAddress(hWincorlib, "?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z");
|
|
}
|
|
|
|
HMODULE hSEH = GetModuleHandleW(nullptr);
|
|
if (hSEH)
|
|
{
|
|
if (GetActivationFactoryByPCWSTRFunc)
|
|
{
|
|
VnPatchIAT(hSEH, (PSTR)"wincorlib.DLL", (PSTR)"?GetActivationFactoryByPCWSTR@@YAJPEAXAEAVGuid@Platform@@PEAPEAX@Z", (uintptr_t)SEH_GetActivationFactoryByPCWSTR);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
EXTERN_C_END
|
|
|
|
#include "inc/PopNoWilResultMacrosLogging.h"
|