From c286ab5610458007e1a23848fe9637cf79cc251c Mon Sep 17 00:00:00 2001 From: Amrsatrio Date: Sun, 31 Mar 2024 22:23:46 +0700 Subject: [PATCH] Start10: Tweaked the method for restoring the old start menu's animations to work with 226xx.3420+ and 24H2 (#3066) --- ExplorerPatcher/dllmain.c | 456 +++++++++++++++++++------------------- 1 file changed, 233 insertions(+), 223 deletions(-) diff --git a/ExplorerPatcher/dllmain.c b/ExplorerPatcher/dllmain.c index 13dbdfe..51cbb44 100644 --- a/ExplorerPatcher/dllmain.c +++ b/ExplorerPatcher/dllmain.c @@ -11028,20 +11028,22 @@ static void PatchStartTileData() #ifdef _WIN64 static struct { + int startExperienceManager_IStartExperienceManager; + int startExperienceManager_SingleViewShellExperienceEventHandler; int startExperienceManager_singleViewShellExperience; - int startExperienceManager_singleViewShellExperienceEventHandler; int startExperienceManager_openingAnimation; int startExperienceManager_closingAnimation; - int startExperienceManager_bMaybeFullScreenMode; + int startExperienceManager_bTransitioningToCortana; } g_SMAnimationPatchOffsets; -// Names are custom +// Names taken from 19041.844 twinui.pdb enum EDGEUI_TRAYSTUCKPLACE { - TSP_LEFT, - TSP_TOP, - TSP_RIGHT, - TSP_BOTTOM, + EUITSP_UNKNOWN = -1, + EUITSP_LEFT = 0, + EUITSP_TOP, + EUITSP_RIGHT, + EUITSP_BOTTOM, }; // Names taken from Windows.UI.Xaml.pdb, only defining the used ones @@ -11055,85 +11057,99 @@ enum DWMTRANSITION_TARGET DWMTARGET_LAUNCHERFULLSCREEN = 0x52, }; -HRESULT(*CStartExperienceManager_GetMonitorInformationFunc)(void* _this, void* experience, RECT* a3, enum EDGEUI_TRAYSTUCKPLACE* pTsp, bool* a5, RECT* a6, HMONITOR* a7); +HRESULT(*CStartExperienceManager_GetMonitorInformationFunc)(void* _this, void* experience, RECT* a3, enum EDGEUI_TRAYSTUCKPLACE* pTsp, bool* a5, HMONITOR* a7); HRESULT(*CExperienceManagerAnimationHelper_BeginFunc)(void* _this, void*, enum DWMTRANSITION_TARGET, const RECT*, const RECT*, const RECT*, const RECT*, const RECT*); HRESULT(*CExperienceManagerAnimationHelper_EndFunc)(void* _this); -HRESULT(*OnViewCloakingFunc)(void* eventHandler, void* experience); -HRESULT OnViewCloakingHook(void* eventHandler, void* experience) +HRESULT(*OnViewUncloakingFunc)(void* eventHandler, void* pSender); +HRESULT OnViewUncloakingHook(void* eventHandler, void* pSender) { - PBYTE _this = (PBYTE)eventHandler - g_SMAnimationPatchOffsets.startExperienceManager_singleViewShellExperienceEventHandler; - bool bMaybeFullScreenMode = *(_this + g_SMAnimationPatchOffsets.startExperienceManager_bMaybeFullScreenMode); - if (bMaybeFullScreenMode) - return S_OK; + PBYTE _this = (PBYTE)eventHandler - g_SMAnimationPatchOffsets.startExperienceManager_SingleViewShellExperienceEventHandler; RECT rc; enum EDGEUI_TRAYSTUCKPLACE tsp; bool bUnknown; - RECT rc2; - HMONITOR hMonitor; - HRESULT hr = CStartExperienceManager_GetMonitorInformationFunc(_this, experience, &rc, &tsp, &bUnknown, &rc2, &hMonitor); - if (FAILED(hr)) - return hr; - - enum DWMTRANSITION_TARGET target = DWMTARGET_LAUNCHERFLYOUT; - if (*(bool*)((PBYTE)experience + 0x34)) - target = DWMTARGET_LAUNCHERFULLSCREEN; - else if (tsp == TSP_LEFT) - target = DWMTARGET_LAUNCHERFLYOUTTOLEFT; - else if (tsp == TSP_TOP) - target = DWMTARGET_LAUNCHERFLYOUTTOTOP; - else if (tsp == TSP_RIGHT) - target = DWMTARGET_LAUNCHERFLYOUTTORIGHT; - else if (tsp == TSP_BOTTOM) - target = DWMTARGET_LAUNCHERFLYOUTTOBOTTOM; - - hr = CExperienceManagerAnimationHelper_BeginFunc( - _this + g_SMAnimationPatchOffsets.startExperienceManager_closingAnimation, - *(void**)((PBYTE)experience + 0x18), // viewWrapper - target | 0x200000u, NULL, NULL, NULL, NULL, &rc); - - return hr; -} - -// Note: `void* experience` is never valid because the compiler optimized out the argument passing. At least on 22621.1992 -HRESULT CStartExperienceManager_GetMonitorInformationHook(void* _this, void* experience, RECT* a3, enum EDGEUI_TRAYSTUCKPLACE* pTsp, bool* a5, RECT* a6, HMONITOR* a7) -{ - HRESULT hr = CStartExperienceManager_GetMonitorInformationFunc(_this, experience, a3, pTsp, a5, a6, a7); - // We add code to OnViewUncloaking through this function - if (SUCCEEDED(hr) && *(PBYTE)_ReturnAddress() == 0x85 && *((PBYTE)_ReturnAddress() + 1) == 0xC0 && *((PBYTE)_ReturnAddress() + 2) == 0x78) + if (SUCCEEDED(CStartExperienceManager_GetMonitorInformationFunc(_this, pSender, &rc, &tsp, &bUnknown, NULL))) { - experience = (PBYTE)_this + g_SMAnimationPatchOffsets.startExperienceManager_singleViewShellExperience; - enum DWMTRANSITION_TARGET target = DWMTARGET_LAUNCHERFLYOUT; - if (*(bool*)((PBYTE)experience + 0x34)) + if (*(bool*)((PBYTE)pSender + 0x34)) target = DWMTARGET_LAUNCHERFULLSCREEN; - else if (*pTsp == TSP_LEFT) + else if (tsp == EUITSP_LEFT) target = DWMTARGET_LAUNCHERFLYOUTTORIGHT; - else if (*pTsp == TSP_TOP) + else if (tsp == EUITSP_TOP) target = DWMTARGET_LAUNCHERFLYOUTTOBOTTOM; - else if (*pTsp == TSP_RIGHT) + else if (tsp == EUITSP_RIGHT) target = DWMTARGET_LAUNCHERFLYOUTTOLEFT; - else if (*pTsp == TSP_BOTTOM) + else if (tsp == EUITSP_BOTTOM) target = DWMTARGET_LAUNCHERFLYOUTTOTOP; CExperienceManagerAnimationHelper_BeginFunc( - (PBYTE)_this + g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation, - *(void**)((PBYTE)experience + 0x18), // viewWrapper - target | 0x200000u, NULL, NULL, NULL, NULL, a3); - return E_FAIL; // Don't invoke ReportUsage() called in OnViewUncloaking + _this + g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation, + *(void**)((PBYTE)pSender + 0x18), // viewWrapper + target | 0x200000, NULL, NULL, NULL, NULL, &rc); } - return hr; -} -HRESULT(*OnViewUncloakingFunc)(void* eventHandler, void* experience); + return OnViewUncloakingFunc(eventHandler, pSender); +} -HRESULT(*OnViewUncloakedFunc)(void* eventHandler, void* experience); -HRESULT OnViewUncloakedHook(void* eventHandler, void* experience) +HRESULT(*OnViewUncloakedFunc)(void* eventHandler, void* pSender); +HRESULT OnViewUncloakedHook(void* eventHandler, void* pSender) { - PBYTE _this = (PBYTE)eventHandler - g_SMAnimationPatchOffsets.startExperienceManager_singleViewShellExperienceEventHandler; + PBYTE _this = (PBYTE)eventHandler - g_SMAnimationPatchOffsets.startExperienceManager_SingleViewShellExperienceEventHandler; + CExperienceManagerAnimationHelper_EndFunc(_this + g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation); - return S_OK; + + return OnViewUncloakedFunc(eventHandler, pSender); +} + +HRESULT(*OnViewCloakingFunc)(void* eventHandler, void* pSender); +HRESULT OnViewCloakingHook(void* eventHandler, void* pSender) +{ + PBYTE _this = (PBYTE)eventHandler - g_SMAnimationPatchOffsets.startExperienceManager_SingleViewShellExperienceEventHandler; + + bool bTransitioningToCortana = *(_this + g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana); + if (!bTransitioningToCortana) + { + RECT rc; + enum EDGEUI_TRAYSTUCKPLACE tsp; + bool bUnknown; + HMONITOR hMonitor; + if (SUCCEEDED(CStartExperienceManager_GetMonitorInformationFunc(_this, pSender, &rc, &tsp, &bUnknown, &hMonitor))) + { + enum DWMTRANSITION_TARGET target = DWMTARGET_LAUNCHERFLYOUT; + if (*(bool*)((PBYTE)pSender + 0x34)) + target = DWMTARGET_LAUNCHERFULLSCREEN; + else if (tsp == EUITSP_LEFT) + target = DWMTARGET_LAUNCHERFLYOUTTOLEFT; + else if (tsp == EUITSP_TOP) + target = DWMTARGET_LAUNCHERFLYOUTTOTOP; + else if (tsp == EUITSP_RIGHT) + target = DWMTARGET_LAUNCHERFLYOUTTORIGHT; + else if (tsp == EUITSP_BOTTOM) + target = DWMTARGET_LAUNCHERFLYOUTTOBOTTOM; + + CExperienceManagerAnimationHelper_BeginFunc( + _this + g_SMAnimationPatchOffsets.startExperienceManager_closingAnimation, + *(void**)((PBYTE)pSender + 0x18), // viewWrapper + target | 0x200000u, NULL, NULL, NULL, NULL, &rc); + } + } + + return OnViewCloakingFunc(eventHandler, pSender); +} + +HRESULT(*OnViewHiddenFunc)(void* eventHandler, void* pSender); +HRESULT OnViewHiddenHook(void* eventHandler, void* pSender) +{ + PBYTE _this = (PBYTE)eventHandler - g_SMAnimationPatchOffsets.startExperienceManager_SingleViewShellExperienceEventHandler; + + bool bTransitioningToCortana = *(_this + g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana); + if (!bTransitioningToCortana) + { + CExperienceManagerAnimationHelper_EndFunc(_this + g_SMAnimationPatchOffsets.startExperienceManager_closingAnimation); + } + + return OnViewHiddenFunc(eventHandler, pSender); } BOOL FixStartMenuAnimation(LPMODULEINFO mi) @@ -11144,23 +11160,44 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi) // `StartDocked::ShouldUseStartDocked()`, we crosscheck the removed code and piece together a patch for proper // animations on 22000.65+. + g_SMAnimationPatchOffsets.startExperienceManager_IStartExperienceManager = 0x28; + g_SMAnimationPatchOffsets.startExperienceManager_SingleViewShellExperienceEventHandler = 0x60; + + // ### CStartExperienceManager::`vftable'{for `SingleViewShellExperienceEventHandler'} + // ``` + // 48 89 46 48 48 8D 05 ?? ?? ?? ?? 48 89 46 60 48 8D 4E 68 E8 + // ^^^^^^^^^^^ + // ``` + // Ref: CStartExperienceManager::CStartExperienceManager() + PBYTE matchVtable = FindPattern( + mi->lpBaseOfDll, + mi->SizeOfImage, + "\x48\x89\x46\x48\x48\x8D\x05\x00\x00\x00\x00\x48\x89\x46\x60\x48\x8D\x4E\x68\xE8", + "xxxxxxx????xxxxxxxxx" + ); + if (matchVtable) + { + matchVtable += 4; + matchVtable += 7 + *(int*)(matchVtable + 3); + printf("[SMA] matchVtable = %llX\n", matchVtable - (PBYTE)mi->lpBaseOfDll); + } + // ### Offset of SingleViewShellExperience instance and its event handler // ``` - // 48 8D 8E ?? ?? ?? ?? 44 8D 45 ?? 48 8D 56 ?? E8 - // ^^^^^^^^^^^ SVSE ^^ SVSEEH + // 48 8D 8E ?? ?? ?? ?? 44 8D 45 ?? 48 8D 56 60 E8 + // ^^^^^^^^^^^ SVSE ^^ SVSEEH (hardcoded to 0x60, included in pattern for sanity check) // ``` // Ref: CStartExperienceManager::CStartExperienceManager() - PBYTE match1 = FindPattern( + PBYTE matchSingleViewShellExperienceFields = FindPattern( mi->lpBaseOfDll, mi->SizeOfImage, - "\x48\x8D\x8E\x00\x00\x00\x00\x44\x8D\x45\x00\x48\x8D\x56\x00\xE8", - "xxx????xxx?xxx?x" + "\x48\x8D\x8E\x00\x00\x00\x00\x44\x8D\x45\x00\x48\x8D\x56\x60\xE8", + "xxx????xxx?xxxxx" ); - if (match1) + if (matchSingleViewShellExperienceFields) { - g_SMAnimationPatchOffsets.startExperienceManager_singleViewShellExperience = *(int*)(match1 + 3); - g_SMAnimationPatchOffsets.startExperienceManager_singleViewShellExperienceEventHandler = (int)*(char*)(match1 + 14); - printf("[SMA] match1 = %llX\n", match1 - (PBYTE)mi->lpBaseOfDll); + g_SMAnimationPatchOffsets.startExperienceManager_singleViewShellExperience = *(int*)(matchSingleViewShellExperienceFields + 3); + printf("[SMA] matchSingleViewShellExperienceFields = %llX\n", matchSingleViewShellExperienceFields - (PBYTE)mi->lpBaseOfDll); } // ### Offsets of Animation Helpers @@ -11170,36 +11207,35 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi) // ``` // Ref: CStartExperienceManager::CStartExperienceManager() // AH2 is located right after AH1. AH is 32 bytes - PBYTE match2 = FindPattern( + PBYTE matchAnimationHelperFields = FindPattern( mi->lpBaseOfDll, mi->SizeOfImage, "\x40\x88\xAE\x00\x00\x00\x00\xC7\x86\x00\x00\x00\x00\x38\x00\x00\x00", "xxx????xx????xxxx" ); - if (match2) + if (matchAnimationHelperFields) { - g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation = *(int*)(match2 + 3); + g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation = *(int*)(matchAnimationHelperFields + 3); g_SMAnimationPatchOffsets.startExperienceManager_closingAnimation = g_SMAnimationPatchOffsets.startExperienceManager_openingAnimation + 32; - printf("[SMA] match2 = %llX\n", match2 - (PBYTE)mi->lpBaseOfDll); + printf("[SMA] matchAnimationHelperFields = %llX\n", matchAnimationHelperFields - (PBYTE)mi->lpBaseOfDll); } - // ### Offset of bMaybeFullScreenMode + // ### Offset of bTransitioningToCortana // ``` - // 80 B9 ?? ?? ?? ?? 00 0F 85 ?? ?? ?? ?? 45 33 C0 B2 01 - // ^^^^^^^^^^^ bMaybeFullScreenMode + // 80 B9 ?? ?? ?? ?? 00 75 ?? 48 83 C1 D8 + // ^^^^^^^^^^^ bTransitioningToCortana // ``` - // Ref: CStartExperienceManager::OnViewHidden() - // TODO Broke on 25951 Canary - PBYTE match3 = FindPattern( + // Ref: CStartExperienceManager::DimStart() + PBYTE matchTransitioningToCortanaField = FindPattern( mi->lpBaseOfDll, mi->SizeOfImage, - "\x80\xB9\x00\x00\x00\x00\x00\x0F\x85\x00\x00\x00\x00\x45\x33\xC0\xB2\x01", - "xx????xxx????xxxxx" + "\x80\xB9\x00\x00\x00\x00\x00\x75\x00\x48\x83\xC1\xD8", + "xx????xx?xxxx" ); - if (match3) + if (matchTransitioningToCortanaField) { - g_SMAnimationPatchOffsets.startExperienceManager_bMaybeFullScreenMode = g_SMAnimationPatchOffsets.startExperienceManager_singleViewShellExperienceEventHandler + *(int*)(match3 + 2); - printf("[SMA] match3 = %llX\n", match3 - (PBYTE)mi->lpBaseOfDll); + g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana = g_SMAnimationPatchOffsets.startExperienceManager_IStartExperienceManager + *(int*)(matchTransitioningToCortanaField + 2); + printf("[SMA] matchTransitioningToCortanaField = %llX\n", matchTransitioningToCortanaField - (PBYTE)mi->lpBaseOfDll); } // ### Offset of CStartExperienceManager::GetMonitorInformation() @@ -11208,53 +11244,76 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi) // ^^^^^^^^^^^ // ``` // Ref: CStartExperienceManager::PositionMenu() - PBYTE match4 = FindPattern( + PBYTE matchGetMonitorInformation = FindPattern( mi->lpBaseOfDll, mi->SizeOfImage, "\xE8\x00\x00\x00\x00\x8B\x00\x85\xC0\x0F\x88\x00\x00\x00\x00\xC6\x44\x24", "x????x?xxxx????xxx" ); - if (match4) + if (matchGetMonitorInformation) { - match4 += 5 + *(int*)(match4 + 1); - CStartExperienceManager_GetMonitorInformationFunc = match4; - printf("[SMA] CStartExperienceManager::GetMonitorInformation() = %llX\n", match4 - (PBYTE)mi->lpBaseOfDll); + matchGetMonitorInformation += 5 + *(int*)(matchGetMonitorInformation + 1); + CStartExperienceManager_GetMonitorInformationFunc = matchGetMonitorInformation; + printf("[SMA] CStartExperienceManager::GetMonitorInformation() = %llX\n", matchGetMonitorInformation - (PBYTE)mi->lpBaseOfDll); } // ### Offset of CExperienceManagerAnimationHelper::Begin() - // ``` - // 44 8B C7 E8 ?? ?? ?? ?? 85 C0 79 19 - // ^^^^^^^^^^^ - // ``` + // * Pattern 1, used when all arguments are available: + // ``` + // 44 8B C7 E8 ?? ?? ?? ?? 85 C0 79 19 + // ^^^^^^^^^^^ + // ``` + // * Pattern 2, used when a4, a5, and a6 are optimized out (e.g. 26020, 26058): + // ``` + // 44 8B C7 48 8D 8B ?? ?? ?? ?? E8 ?? ?? ?? ?? 85 C0 79 19 + // ^^^^^^^^^^^ + // ``` // Ref: CJumpViewExperienceManager::OnViewUncloaking() - PBYTE match5 = FindPattern( + PBYTE matchAnimationBegin = FindPattern( mi->lpBaseOfDll, mi->SizeOfImage, "\x44\x8B\xC7\xE8\x00\x00\x00\x00\x85\xC0\x79\x19", "xxxx????xxxx" ); - if (match5) + if (matchAnimationBegin) + { + matchAnimationBegin += 3; + matchAnimationBegin += 5 + *(int*)(matchAnimationBegin + 1); + } + else + { + matchAnimationBegin = FindPattern( + mi->lpBaseOfDll, + mi->SizeOfImage, + "\x44\x8B\xC7\x48\x8D\x8B\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x85\xC0\x79\x19", + "xxxxxx????x????xxxx" + ); + if (matchAnimationBegin) + { + matchAnimationBegin += 10; + matchAnimationBegin += 5 + *(int*)(matchAnimationBegin + 1); + } + } + if (matchAnimationBegin) { - match5 += 3; - match5 += 5 + *(int*)(match5 + 1); - CExperienceManagerAnimationHelper_BeginFunc = match5; - printf("[SMA] CExperienceManagerAnimationHelper::Begin() = %llX\n", match5 - (PBYTE)mi->lpBaseOfDll); + CExperienceManagerAnimationHelper_BeginFunc = matchAnimationBegin; + printf("[SMA] CExperienceManagerAnimationHelper::Begin() = %llX\n", matchAnimationBegin - (PBYTE)mi->lpBaseOfDll); } // ### Offset of CExperienceManagerAnimationHelper::End() // ``` // 40 53 48 83 EC 20 80 39 00 74 // ``` - PBYTE match6 = FindPattern( + PBYTE matchAnimationEnd = FindPattern( mi->lpBaseOfDll, mi->SizeOfImage, "\x40\x53\x48\x83\xEC\x20\x80\x39\x00\x74", "xxxxxxxxxx" ); - if (match6) + if (matchAnimationEnd) { - CExperienceManagerAnimationHelper_EndFunc = match6; - printf("[SMA] CExperienceManagerAnimationHelper::End() = %llX\n", match6 - (PBYTE)mi->lpBaseOfDll); + CExperienceManagerAnimationHelper_EndFunc = matchAnimationEnd; + printf("[SMA] CExperienceManagerAnimationHelper::End() = %llX\n", matchAnimationEnd - (PBYTE)mi->lpBaseOfDll); } // ### CStartExperienceManager::Hide() @@ -11263,153 +11322,105 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi) // ^^ Turn jz into jmp // ``` // Perform on exactly two matches - PBYTE match7a = FindPattern( + PBYTE matchHideA = FindPattern( mi->lpBaseOfDll, mi->SizeOfImage, "\x74\x00\x00\x03\x00\x00\x00\x44\x88", "x??xxxxxx" ); - PBYTE match7b = NULL; - if (match7a) + PBYTE matchHideB = NULL; + if (matchHideA) { - printf("[SMA] match7a in CStartExperienceManager::Hide() = %llX\n", match7a - (PBYTE)mi->lpBaseOfDll); - match7b = FindPattern( - match7a + 14, - mi->SizeOfImage - (match7a + 14 - (PBYTE)mi->lpBaseOfDll), + printf("[SMA] matchHideA in CStartExperienceManager::Hide() = %llX\n", matchHideA - (PBYTE)mi->lpBaseOfDll); + matchHideB = FindPattern( + matchHideA + 14, + mi->SizeOfImage - (matchHideA + 14 - (PBYTE)mi->lpBaseOfDll), "\x74\x00\x00\x03\x00\x00\x00\x44\x88", "x??xxxxxx" ); - if (match7b) + if (matchHideB) { - printf("[SMA] match7b in CStartExperienceManager::Hide() = %llX\n", match7b - (PBYTE)mi->lpBaseOfDll); + printf("[SMA] matchHideB in CStartExperienceManager::Hide() = %llX\n", matchHideB - (PBYTE)mi->lpBaseOfDll); } } - // ### CStartExperienceManager::OnViewCloaking() - // ``` - // 48 83 EC 28 80 B9 ?? ?? ?? ?? 00 75 ?? 45 33 C0 - // ``` - // Just hook - // TODO: Broke on 25951 Canary - PBYTE match8 = FindPattern( - mi->lpBaseOfDll, - mi->SizeOfImage, - "\x48\x83\xEC\x28\x80\xB9\x00\x00\x00\x00\x00\x75\x00\x45\x33\xC0", - "xxxxxx????xx?xxx" - ); - if (match8) + if (!matchVtable + || !matchSingleViewShellExperienceFields + || !matchAnimationHelperFields + || !matchTransitioningToCortanaField + || !matchGetMonitorInformation + || !matchAnimationBegin + || !matchAnimationEnd + || !matchHideA + || !matchHideB) { - OnViewCloakingFunc = match8; - printf("[SMA] CStartExperienceManager::OnViewCloaking() = %llX\n", match8 - (PBYTE)mi->lpBaseOfDll); + printf("[SMA] Not all offsets were found, cannot perform patch\n"); + return FALSE; } - // ### CStartExperienceManager::OnViewHidden() - // ``` - // 80 B9 ?? ?? ?? ?? 00 0F 85 ?? ?? ?? ?? 45 33 C0 B2 01 - // ^^ Start overwriting here. 17 bytes, rest NOP - // ``` - // TODO Broke on 25951 Canary - PBYTE match9 = FindPattern( - mi->lpBaseOfDll, - mi->SizeOfImage, - "\x80\xB9\x00\x00\x00\x00\x00\x0F\x85\x00\x00\x00\x00\x45\x33\xC0\xB2\x01", - "xx????xxx????xxxxx" - ); - if (match9) - { - printf("[SMA] match9 in CStartExperienceManager::OnViewHidden() = %llX\n", match9 - (PBYTE)mi->lpBaseOfDll); - } + DWORD dwOldProtect = 0; - // ### CStartExperienceManager::OnViewUncloaked() - // ``` - // 48 83 EC 28 45 33 C0 48 8D 0D ?? ?? ?? ?? B2 01 E8 ?? ?? ?? ?? 33 C0 - // ``` - // Just hook - // TODO: Broke on 25951 Canary - PBYTE match10 = FindPattern( - mi->lpBaseOfDll, - mi->SizeOfImage, - "\x48\x83\xEC\x28\x45\x33\xC0\x48\x8D\x0D\x00\x00\x00\x00\xB2\x01\xE8\x00\x00\x00\x00\x33\xC0", - "xxxxxxxxxx????xxx????xx" - ); - if (match10) - { - OnViewUncloakedFunc = match10; - printf("[SMA] CStartExperienceManager::OnViewUncloaked() = %llX\n", match10 - (PBYTE)mi->lpBaseOfDll); - } + void** vtable = (void**)matchVtable; + void** p_OnViewUncloaking = &vtable[4]; + void** p_OnViewUncloaked = &vtable[5]; + void** p_OnViewCloaking = &vtable[6]; + void** p_OnViewHidden = &vtable[10]; - if (!match1 || !match2 || !match3 || !match4 || !match5 || !match6 || !match7a || !match7b || !match8 || !match9 || !match10) + // OnViewUncloaking + if (*p_OnViewUncloaking != OnViewUncloakingHook) { - printf("[SMA] Not all offsets were found, cannot perform patch\n"); - return FALSE; + OnViewUncloakingFunc = *p_OnViewUncloaking; + if (VirtualProtect(p_OnViewUncloaking, sizeof(void*), PAGE_EXECUTE_READWRITE, &dwOldProtect)) + { + *p_OnViewUncloaking = OnViewUncloakingHook; + VirtualProtect(p_OnViewUncloaking, sizeof(void*), dwOldProtect, &dwOldProtect); + } } - int rv = funchook_prepare( - funchook, - (void**)&CStartExperienceManager_GetMonitorInformationFunc, - CStartExperienceManager_GetMonitorInformationHook - ); - if (rv != 0) + // OnViewUncloaked + if (*p_OnViewUncloaked != OnViewUncloakedHook) { - printf("Failed to hook CStartExperienceManager::GetMonitorInformation(). rv = %d\n", rv); + OnViewUncloakedFunc = *p_OnViewUncloaked; + if (VirtualProtect(p_OnViewUncloaked, sizeof(void*), PAGE_EXECUTE_READWRITE, &dwOldProtect)) + { + *p_OnViewUncloaked = OnViewUncloakedHook; + VirtualProtect(p_OnViewUncloaked, sizeof(void*), dwOldProtect, &dwOldProtect); + } } - DWORD dwOldProtect = 0; - if (VirtualProtect(match7a + 11, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect)) + // OnViewCloaking + if (*p_OnViewCloaking != OnViewCloakingHook) { - match7a[0] = 0xEB; - VirtualProtect(match7a + 11, 1, dwOldProtect, &dwOldProtect); - - dwOldProtect = 0; - if (VirtualProtect(match7b + 11, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect)) + OnViewCloakingFunc = *p_OnViewCloaking; + if (VirtualProtect(p_OnViewCloaking, sizeof(void*), PAGE_EXECUTE_READWRITE, &dwOldProtect)) { - match7b[0] = 0xEB; - VirtualProtect(match7b + 11, 1, dwOldProtect, &dwOldProtect); + *p_OnViewCloaking = OnViewCloakingHook; + VirtualProtect(p_OnViewCloaking, sizeof(void*), dwOldProtect, &dwOldProtect); } } - rv = funchook_prepare( - funchook, - (void**)&OnViewCloakingFunc, - OnViewCloakingHook - ); - if (rv != 0) + // OnViewHidden + if (*p_OnViewHidden != OnViewHiddenHook) { - printf("Failed to hook CStartExperienceManager::OnViewCloaking(). rv = %d\n", rv); + OnViewHiddenFunc = *p_OnViewHidden; + if (VirtualProtect(p_OnViewHidden, sizeof(void*), PAGE_EXECUTE_READWRITE, &dwOldProtect)) + { + *p_OnViewHidden = OnViewHiddenHook; + VirtualProtect(p_OnViewHidden, sizeof(void*), dwOldProtect, &dwOldProtect); + } } - PBYTE begin = match9 + 13; - PBYTE end = begin + 17; - - // Craft the code to call End() - BYTE code[] = { - // lea rcx, [rbx+] ; rbx is the `this`, offset to closingAnimation - 0x48, 0x8D, 0x8B, 0x11, 0x11, 0x11, 0x11, - // call CExperienceManagerAnimationHelper::End - 0xE8, 0x22, 0x22, 0x22, 0x22, - }; - - *(int*)(code + 3) = -g_SMAnimationPatchOffsets.startExperienceManager_singleViewShellExperienceEventHandler + g_SMAnimationPatchOffsets.startExperienceManager_closingAnimation; - *(int*)(code + 8) = (int)((PBYTE)CExperienceManagerAnimationHelper_EndFunc - (begin + sizeof(code))); - - PBYTE nopBegin = begin + sizeof(code); - - dwOldProtect = 0; - if (VirtualProtect(begin, end - begin, PAGE_EXECUTE_READWRITE, &dwOldProtect)) + if (VirtualProtect(matchHideA + 11, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect)) { - memcpy(begin, code, sizeof(code)); - memset(nopBegin, 0x90, end - nopBegin); - VirtualProtect(begin, end - begin, dwOldProtect, &dwOldProtect); - } + matchHideA[0] = 0xEB; + VirtualProtect(matchHideA + 11, 1, dwOldProtect, &dwOldProtect); - rv = funchook_prepare( - funchook, - (void**)&OnViewUncloakedFunc, - OnViewUncloakedHook - ); - if (rv != 0) - { - printf("Failed to hook CStartExperienceManager::OnViewUncloaked(). rv = %d\n", rv); + dwOldProtect = 0; + if (VirtualProtect(matchHideB + 11, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect)) + { + matchHideB[0] = 0xEB; + VirtualProtect(matchHideB + 11, 1, dwOldProtect, &dwOldProtect); + } } return TRUE; @@ -12553,7 +12564,6 @@ DWORD Inject(BOOL bIsExplorer) } if ((global_rovi.dwBuildNumber > 22000 || global_rovi.dwBuildNumber == 22000 && global_ubr >= 65) // Allow on 22000.65+ - && global_rovi.dwBuildNumber < 25000 // But not on 25xxx (yet) && dwStartShowClassicMode) { // Make sure crash counter is enabled. If one of the patches make Explorer crash while the start menu is open, @@ -13493,8 +13503,8 @@ int Start_SetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw) HRESULT hr = IsThreadCoreWindowVisible(&bIsWindowVisible); if (SUCCEEDED(hr)) { - if (global_rovi.dwBuildNumber >= 25000 && dwStartShowClassicMode) - ShowWindow(hWnd, bIsWindowVisible ? SW_SHOW : SW_HIDE); + /*if (global_rovi.dwBuildNumber >= 25000 && dwStartShowClassicMode) + ShowWindow(hWnd, bIsWindowVisible ? SW_SHOW : SW_HIDE);*/ DWORD TaskbarAl = InterlockedAdd(&dwTaskbarAl, 0); if (bIsWindowVisible && (!TaskbarAl ? (dwStartShowClassicMode ? StartUI_EnableRoundedCornersApply : StartDocked_DisableRecommendedSectionApply) : 1)) {