Compare commits

...

10 Commits

  1. 13
      CHANGELOG.md
  2. 247
      ExplorerPatcher/TwinUIPatches.cpp
  3. 43
      ExplorerPatcher/dllmain.c
  4. 47
      ExplorerPatcher/utility.h
  5. 78
      ep_startmenu/ep_sm_main.c
  6. 2
      version.h

13
CHANGELOG.md

@ -4,7 +4,7 @@ This document includes the same release notes as in the [Releases](https://githu @@ -4,7 +4,7 @@ This document includes the same release notes as in the [Releases](https://githu
## 26100.4946.69
Tested on OS builds 26100.4946, 26100.5074, and 26200.5751.
Tested on OS builds 26100.4946, 26100.5074, 26200.5751, and 26220.6682.
##### 1
@ -23,11 +23,18 @@ Tested on OS builds 26100.4946, 26100.5074, and 26200.5751. @@ -23,11 +23,18 @@ Tested on OS builds 26100.4946, 26100.5074, and 26200.5751.
##### 2
* Fixed weather button not having an icon. (#4545) (6959c69)
* You may need to perform "Clear weather widget local data" in EP properties > Weather.
##### 3
* File Explorer: Fixed "Shrink address bar height" resulting in broken graphics on recent 24H2 builds. (#4552) (6d946bd)
* Start10: Fixed open/close animation patching on x64 27938+ and ARM64 27881+. (201a7e5, 79f8dd3, f873888, 465117e, 4434d10)
* Start10: Fixed Windows 10 Start menu refusing to open when the new Windows 11 Start menu feature flag(s) are enabled. (#4523) (afd109f)
* Fixed Windows 10 Alt+Tab and Windows 10 taskbar Win+X functionality on ARM64 226x1 and 27686+. (18dfcd0)
Known issues we will address in the short term:
* Changing weather icon pack to "Microsoft" has no effect.
* Shrink address bar height results in unexpected dimensions on recent 24H2 builds.
* When the new Windows 11 Start menu feature flag is enabled, Windows 10 Start menu will refuse to open due to an internal change.
* On Nickel (Windows 11 22H2/23H2), when the new Windows 11 Start menu is enabled, using Windows 10 or Windows 10 (ExplorerPatcher) taskbar will crashloop explorer.exe.
## 22631.5335.68

247
ExplorerPatcher/TwinUIPatches.cpp

@ -2004,6 +2004,7 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi) @@ -2004,6 +2004,7 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi)
// ### Offset of bTransitioningToCortana
#if defined(_M_X64)
// `(CStartExperienceManager *)((char *)this - 40)` after field access
// ```
// 80 B9 ?? ?? ?? ?? 00 75 ?? 48 83 C1 D8
// ^^^^^^^^^^^ bTransitioningToCortana
@ -2019,6 +2020,25 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi) @@ -2019,6 +2020,25 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi)
{
g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana = g_SMAnimationPatchOffsets.startExperienceManager_IStartExperienceManager + *(int*)(matchTransitioningToCortanaField + 2);
}
else
{
// `(CStartExperienceManager *)((char *)this - 40)` before field access
// ```
// 48 83 C1 ?? 80 B9 ?? ?? ?? ?? 00 75 ?? 41 B0 01
// ^^^^^^^^^^^ bTransitioningToCortana
// ```
// Ref: CStartExperienceManager::DimStart()
matchTransitioningToCortanaField = (PBYTE)FindPattern(
mi->lpBaseOfDll,
mi->SizeOfImage,
"\x48\x83\xC1\x00\x80\xB9\x00\x00\x00\x00\x00\x75\x00\x41\xB0\x01",
"xxx?xx????xx?xxx"
);
if (matchTransitioningToCortanaField)
{
g_SMAnimationPatchOffsets.startExperienceManager_bTransitioningToCortana = *(int*)(matchTransitioningToCortanaField + 6);
}
}
#elif defined(_M_ARM64)
// ```
// ?? ?? ?? 39 E8 00 00 35 ?? ?? ?? ?? 01 ?? ?? 91 22 00 80 52
@ -2068,24 +2088,44 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi) @@ -2068,24 +2088,44 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi)
matchGetMonitorInformation += 5 + *(int*)(matchGetMonitorInformation + 1);
}
#elif defined(_M_ARM64)
// * Pattern for 226xx
// * Pattern for 226xx, CSingleViewShellExperience* first arg *not* passed (E1 03 14 AA)
// ```
// E3 ?? 00 91 E2 ?? 00 91 E0 03 13 AA ?? ?? ?? ?? F4 03 00 2A
// ^^^^^^^^^^^
// A9 E4 ?? ?? ?? E3 ?? ?? 91 E2 ?? ?? 91 E0 03 13 AA ?? ?? ?? ?? ?? 03 00 2A
// ^^^^^^^^^^^
// ```
// Ref: CStartExperienceManager::PositionMenu()
PBYTE matchGetMonitorInformation = (PBYTE)FindPattern(
mi->lpBaseOfDll,
mi->SizeOfImage,
"\xE3\x00\x00\x91\xE2\x00\x00\x91\xE0\x03\x13\xAA\x00\x00\x00\x00\xF4\x03\x00\x2A",
"x?xxx?xxxxxx????xxxx"
"\xA9\xE4\x00\x00\x00\xE3\x00\x00\x91\xE2\x00\x00\x91\xE0\x03\x13\xAA\x00\x00\x00\x00\x00\x03\x00\x2A",
"xx???x??xx??xxxxx?????xxx"
);
if (matchGetMonitorInformation)
{
matchGetMonitorInformation += 12;
matchGetMonitorInformation += 17;
matchGetMonitorInformation = (PBYTE)ARM64_FollowBL((DWORD*)matchGetMonitorInformation);
}
if (!matchGetMonitorInformation)
{
// * Pattern for 226xx, CSingleViewShellExperience* first arg passed (E1 03 14 AA)
// ```
// A9 E4 ?? ?? ?? E3 ?? ?? 91 E2 ?? ?? 91 E1 03 14 AA E0 03 13 AA ?? ?? ?? ?? ?? 03 00 2A
// ^^^^^^^^^^^
// ```
// Ref: CStartExperienceManager::PositionMenu()
matchGetMonitorInformation = (PBYTE)FindPattern(
mi->lpBaseOfDll,
mi->SizeOfImage,
"\xA9\xE4\x00\x00\x00\xE3\x00\x00\x91\xE2\x00\x00\x91\xE1\x03\x14\xAA\xE0\x03\x13\xAA\x00\x00\x00\x00\x00\x03\x00\x2A",
"xx???x??xx??xxxxxxxxx?????xxx"
);
if (matchGetMonitorInformation)
{
matchGetMonitorInformation += 21;
matchGetMonitorInformation = (PBYTE)ARM64_FollowBL((DWORD*)matchGetMonitorInformation);
}
}
if (!matchGetMonitorInformation)
{
// * Pattern for 26100.1, 265, 470, 560, 670, 712, 751, 863, 1000, 1150
// ```
@ -2309,61 +2349,63 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi) @@ -2309,61 +2349,63 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi)
}
#elif defined(_M_ARM64)
// ```
// ?? ?? ?? 34 ?? 00 80 52 ?? 8E 0A 39
// ^^^^^^^^^^^ Turn CBZ into B
// E1 03 ?? 2A ?? ?? 04 91 ?? ?? ?? ?? ?? 03 00 2A
// ```
// Check two instructions before, and NOP these:
// ```
// MOV W??, #3
// STRB W??, [X??,#0x???]
// ```
// Perform on exactly two matches
PBYTE matchHideA = (PBYTE)FindPattern(
PBYTE matchHideA = nullptr;
PBYTE matchHideB = nullptr;
auto findTheIfBody = [](PBYTE pAnchor) -> PBYTE
{
// 27881.1000+ has CBNZ before us, follow it if it is.
// Otherwise, just check the two instructions before.
PBYTE pMaybeFollowed = (PBYTE)ARM64_FollowCBNZW((DWORD*)(pAnchor - 4));
PBYTE pIfBlockBegin = pMaybeFollowed ? pMaybeFollowed : pAnchor - 8;
DWORD insnMovzw = *(DWORD*)pIfBlockBegin;
if (!ARM64_IsMOVZW(insnMovzw))
return nullptr;
DWORD movzwImm16 = ARM64_ReadBitsSignExtend(insnMovzw, 20, 5);
if (movzwImm16 != 3)
return nullptr;
DWORD insnStrbimm = *(DWORD*)(pIfBlockBegin + 4);
if (!ARM64_IsSTRBIMM(insnStrbimm))
return nullptr;
return pIfBlockBegin;
};
PBYTE matchHideAAfter = (PBYTE)FindPattern(
mi->lpBaseOfDll,
mi->SizeOfImage,
"\x34\x00\x00\x80\x52\x00\x8E\x0A\x39",
"x?xxx?xxx"
"\xE1\x03\x00\x2A\x00\x00\x04\x91\x00\x00\x00\x00\x00\x03\x00\x2A",
"xx?x??xx?????xxx"
);
PBYTE matchHideB = nullptr;
if (matchHideAAfter)
{
matchHideA = findTheIfBody(matchHideAAfter);
}
if (matchHideA)
{
matchHideA -= 3;
printf("[SMA] matchHideA in CStartExperienceManager::Hide() = %llX (Pattern A)\n", matchHideA - (PBYTE)mi->lpBaseOfDll);
matchHideB = (PBYTE)FindPattern(
matchHideA + 12,
mi->SizeOfImage - (matchHideA + 12 - (PBYTE)mi->lpBaseOfDll),
"\x34\x00\x00\x80\x52\x00\x8E\x0A\x39",
"x?xxx?xxx"
printf("[SMA] matchHideA in CStartExperienceManager::Hide() = %llX\n", matchHideA - (PBYTE)mi->lpBaseOfDll);
PBYTE matchHideBAfter = (PBYTE)FindPattern(
matchHideAAfter + 16,
1024,
"\xE1\x03\x00\x2A\x00\x00\x04\x91\x00\x00\x00\x00\x00\x03\x00\x2A",
"xx?x??xx?????xxx"
);
if (matchHideB)
if (matchHideBAfter)
{
matchHideB -= 3;
printf("[SMA] matchHideB in CStartExperienceManager::Hide() = %llX (Pattern A)\n", matchHideB - (PBYTE)mi->lpBaseOfDll);
matchHideB = findTheIfBody(matchHideBAfter);
}
}
else
{
// ```
// ?? ?? ?? 34 ?? 00 80 52 ?? 4E 0B 39
// ^^^^^^^^^^^ Turn CBZ into B
// ```
// Perform on exactly two matches
matchHideA = (PBYTE)FindPattern(
mi->lpBaseOfDll,
mi->SizeOfImage,
"\x34\x00\x00\x80\x52\x00\x4E\x0B\x39",
"x?xxx?xxx"
);
if (matchHideA)
if (matchHideB)
{
matchHideA -= 3;
printf("[SMA] matchHideA in CStartExperienceManager::Hide() = %llX (Pattern B)\n", matchHideA - (PBYTE)mi->lpBaseOfDll);
matchHideB = (PBYTE)FindPattern(
matchHideA + 12,
mi->SizeOfImage - (matchHideA + 12 - (PBYTE)mi->lpBaseOfDll),
"\x34\x00\x00\x80\x52\x00\x4E\x0B\x39",
"x?xxx?xxx"
);
if (matchHideB)
{
matchHideB -= 3;
printf("[SMA] matchHideB in CStartExperienceManager::Hide() = %llX (Pattern B)\n", matchHideB - (PBYTE)mi->lpBaseOfDll);
}
printf("[SMA] matchHideB in CStartExperienceManager::Hide() = %llX\n", matchHideB - (PBYTE)mi->lpBaseOfDll);
}
}
#endif
@ -2405,20 +2447,18 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi) @@ -2405,20 +2447,18 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi)
}
}
#elif defined(_M_ARM64)
if (VirtualProtect(matchHideA, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect))
if (VirtualProtect(matchHideA, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
DWORD newInsn = ARM64_CBZWToB(*(DWORD*)matchHideA);
if (newInsn)
*(DWORD*)matchHideA = newInsn;
VirtualProtect(matchHideA, 4, dwOldProtect, &dwOldProtect);
*(DWORD*)(matchHideA + 0) = 0xD503201F; // NOP
*(DWORD*)(matchHideA + 4) = 0xD503201F; // NOP
VirtualProtect(matchHideA, 8, dwOldProtect, &dwOldProtect);
dwOldProtect = 0;
if (VirtualProtect(matchHideB, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect))
if (VirtualProtect(matchHideB, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
newInsn = ARM64_CBZWToB(*(DWORD*)matchHideB);
if (newInsn)
*(DWORD*)matchHideB = newInsn;
VirtualProtect(matchHideB, 4, dwOldProtect, &dwOldProtect);
*(DWORD*)(matchHideB + 0) = 0xD503201F; // NOP
*(DWORD*)(matchHideB + 4) = 0xD503201F; // NOP
VirtualProtect(matchHideB, 8, dwOldProtect, &dwOldProtect);
}
}
#endif
@ -3124,17 +3164,17 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets) @@ -3124,17 +3164,17 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets)
pOffsets[0] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile);
}
#elif defined(_M_ARM64)
// ?? AE 00 71 ?? ?? 00 54 ?? 06 40 F9 E3 03 ?? AA E2 03 ?? AA E1 03 ?? 2A ?? ?? ?? ??
// ?? ?? 00 71 ?? ?? 00 54 ?? ?? 40 F9 E3 03 ?? AA E2 03 ?? AA E1 03 ?? 2A ?? ?? ?? ??
// ^^^^^^^^^^^
// Ref: CMultitaskingViewFrame::v_WndProc()
PBYTE match = (PBYTE)FindPattern(
pFile, dwSize,
"\xAE\x00\x71\x00\x00\x00\x54\x00\x06\x40\xF9\xE3\x03\x00\xAA\xE2\x03\x00\xAA\xE1\x03\x00\x2A",
"xxx??xx?xxxxx?xxx?xxx?x"
"\x00\x71\x00\x00\x00\x54\x00\x00\x40\xF9\xE3\x03\x00\xAA\xE2\x03\x00\xAA\xE1\x03\x00\x2A",
"xx??xx??xxxx?xxx?xxx?x"
);
if (match)
{
match += 23;
match += 22;
pOffsets[0] = (DWORD)FileOffsetToRVA(pFile, (PBYTE)ARM64_FollowBL((DWORD*)match) - pFile);
}
#endif
@ -3146,25 +3186,25 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets) @@ -3146,25 +3186,25 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets)
if (!pOffsets[1] || pOffsets[1] == 0xFFFFFFFF)
{
#if defined(_M_X64)
// Don't worry if this is too long, this works on 17763 and 25951
// 40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 4C 8B B5 ? ? ? ? 41 8B C1
// Don't worry if this is too long, this works on 17763 ~ 27943
// 40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 4C 8B ? ? ? ? ? 41 8B C1
PBYTE match = (PBYTE)FindPattern(
pFile, dwSize,
"\x40\x55\x53\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x00\x00\x00\x00\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x85\x00\x00\x00\x00\x4C\x8B\xB5\x00\x00\x00\x00\x41\x8B\xC1",
"xxxxxxxxxxxxxxxxx????xxx????xxx????xxxxxx????xxx????xxx"
"\x40\x55\x53\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x00\x00\x00\x00\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x85\x00\x00\x00\x00\x4C\x8B\x00\x00\x00\x00\x00\x41\x8B\xC1",
"xxxxxxxxxxxxxxxxx????xxx????xxx????xxxxxx????xx?????xxx"
);
if (match)
{
pOffsets[1] = (DWORD)(match - pFile);
}
#elif defined(_M_ARM64)
// 40 F9 43 03 1C 32 E4 03 15 AA ?? ?? FF 97
// 40 F9 43 03 1C 32 E4 03 ?? AA ?? ?? FF 97
// ^^^^^^^^^^^
// Ref: ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu()
PBYTE match = (PBYTE)FindPattern(
pFile, dwSize,
"\x40\xF9\x43\x03\x1C\x32\xE4\x03\x15\xAA\x00\x00\xFF\x97",
"xxxxxxxxxx??xx"
"\x40\xF9\x43\x03\x1C\x32\xE4\x03\x00\xAA\x00\x00\xFF\x97",
"xxxxxxxx?x??xx"
);
if (match)
{
@ -3191,12 +3231,12 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets) @@ -3191,12 +3231,12 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets)
pOffsets[2] = (DWORD)(match - pFile);
}
#elif defined(_M_ARM64)
// 7F 23 03 D5 F3 53 BF A9 FD 7B BB A9 FD 03 00 91 F3 03 00 AA F4 03 01 AA ?? ?? ?? ?? FF ?? 03 A9
// 7F 23 03 D5 F3 53 BF A9 FD 7B BB A9 FD 03 00 91 ?? 03 00 AA ?? 03 01 AA ?? ?? ?? ?? FF ?? 03 A9
// ----------- PACIBSP, don't scan for this because it's everywhere
PBYTE match = (PBYTE)FindPattern(
pFile, dwSize,
"\xF3\x53\xBF\xA9\xFD\x7B\xBB\xA9\xFD\x03\x00\x91\xF3\x03\x00\xAA\xF4\x03\x01\xAA\x00\x00\x00\x00\xFF\x00\x03\xA9",
"xxxxxxxxxxxxxxxxxxxx????x?xx"
"\xF3\x53\xBF\xA9\xFD\x7B\xBB\xA9\xFD\x03\x00\x91\x00\x03\x00\xAA\x00\x03\x01\xAA\x00\x00\x00\x00\xFF\x00\x03\xA9",
"xxxxxxxxxxxx?xxx?xxx????x?xx"
);
if (match)
{
@ -3224,17 +3264,32 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets) @@ -3224,17 +3264,32 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets)
match += 17;
pOffsets[3] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile);
}
else
{
// 48 8B ? E8 ? ? ? ? 4C 8D 47 ? 48 8B ? 48 8B CE E8 ? ? ? ? 90
// ^^^^^^^
match = (PBYTE)FindPattern(
pFile, dwSize,
"\x48\x8B\xCB\xE8\x00\x00\x00\x00\x4C\x8D\x47\x00\x48\x8B\x00\x48\x8B\xCE\xE8\x00\x00\x00\x00\x90",
"xx?x????xxx?xx?xxxx????x"
);
if (match)
{
match += 18;
pOffsets[3] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile);
}
}
#elif defined(_M_ARM64)
// 82 62 00 91 ?? ?? 00 91 E0 03 ?? AA ?? ?? ?? ?? 1F 20 03 D5
// ^^^^^^^^^^^
// ?? 0A 40 F9 ?? 02 40 F9 ?? ?? 00 F9 ?? ?? ?? ?? ?? 62 00 91 ?? ?? 00 91 E0 03 ?? AA ?? ?? ?? ?? 1F 20 03 D5
// ^^^^^^^^^^^
PBYTE match = (PBYTE)FindPattern(
pFile, dwSize,
"\x82\x62\x00\x91\x00\x00\x00\x91\xE0\x03\x00\xAA\x00\x00\x00\x00\x1F\x20\x03\xD5",
"xxxx??xxxx?x????xxxx"
"\x0A\x40\xF9\x00\x02\x40\xF9\x00\x00\x00\xF9\x00\x00\x00\x00\x00\x62\x00\x91\x00\x00\x00\x91\xE0\x03\x00\xAA\x00\x00\x00\x00\x1F\x20\x03\xD5",
"xxx?xxx??xx?????xxx??xxxx?x????xxxx"
);
if (match)
{
match += 12;
match += 27;
pOffsets[3] = (DWORD)FileOffsetToRVA(pFile, (PBYTE)ARM64_FollowBL((DWORD*)match) - pFile);
}
#endif
@ -3246,30 +3301,32 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets) @@ -3246,30 +3301,32 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets)
if (!pOffsets[4] || pOffsets[4] == 0xFFFFFFFF)
{
#if defined(_M_X64)
// 48 8B ? E8 ? ? ? ? 48 8B D3 48 8B CF E8 ? ? ? ? 90 48 8D 56 ? 48 8B CE
// ^^^^^^^ ------------------- Non-inlined ~::final_suspend()
// Cobalt:
// 48 89 46 ? 48 8B CB E8 ? ? ? ? 48 8B D3 48 8B CF E8 ? ? ? ? 90
// ^^^^^^^
PBYTE match = (PBYTE)FindPattern(
pFile, dwSize,
"\x48\x8B\x00\xE8\x00\x00\x00\x00\x48\x8B\xD3\x48\x8B\xCF\xE8\x00\x00\x00\x00\x90\x48\x8D\x56\x00\x48\x8B\xCE",
"xx?x????xxxxxxx????xxxx?xxx"
"\x48\x89\x46\x00\x48\x8B\xCB\xE8\x00\x00\x00\x00\x48\x8B\xD3\x48\x8B\xCF\xE8\x00\x00\x00\x00\x90",
"xxx?xxxx????xxxxxxx????x"
);
if (match)
{
match += 14;
match += 18;
pOffsets[4] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile);
}
else
{
// 48 8B ? E8 ? ? ? ? 48 8B D3 48 8B CF E8 ? ? ? ? 90 48 8B 05 ? ? ? ? 48
// ^^^^^^^ ------------------- Inlined ~::final_suspend()
// Nickel+:
// 48 89 03 48 8B CB E8 ? ? ? ? 48 8B D3 48 8B CF E8 ? ? ? ? 90
// ^^^^^^^
match = (PBYTE)FindPattern(
pFile, dwSize,
"\x48\x8B\x00\xE8\x00\x00\x00\x00\x48\x8B\xD3\x48\x8B\xCF\xE8\x00\x00\x00\x00\x90\x48\x8B\x05\x00\x00\x00\x00\x48",
"xx?x????xxxxxxx????xxxx????x"
"\x48\x89\x03\x48\x8B\xCB\xE8\x00\x00\x00\x00\x48\x8B\xD3\x48\x8B\xCF\xE8\x00\x00\x00\x00\x90",
"xxxxxxx????xxxxxxx????x"
);
if (match)
{
match += 14;
match += 17;
pOffsets[4] = (DWORD)(match + 5 + *(int*)(match + 1) - pFile);
}
}
@ -3333,11 +3390,11 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets) @@ -3333,11 +3390,11 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets)
}
}
#elif defined(_M_ARM64)
// F3 53 BE A9 F5 5B 01 A9 FD 7B ?? A9 FD 03 00 91 30 00 80 92 F5 03 04 AA B0 ?? 00 F9 F3 03 00 AA BF 02 00 F9 68 2E 40 F9 F6 03 03 AA B3 23 02 A9 ?? ?? 00 B5
// F3 53 BE A9 F5 5B 01 A9 FD 7B ?? A9 FD 03 00 91 30 00 80 92 ?? 03 04 AA B0 ?? 00 F9 ?? 03 00 AA ?? 02 00 F9 ?? 2E 40 F9 ?? 03 03 AA ?? 23 02 A9 ?? ?? 00 B5
PBYTE match = (PBYTE)FindPattern(
pFile, dwSize,
"\xF3\x53\xBE\xA9\xF5\x5B\x01\xA9\xFD\x7B\x00\xA9\xFD\x03\x00\x91\x30\x00\x80\x92\xF5\x03\x04\xAA\xB0\x00\x00\xF9\xF3\x03\x00\xAA\xBF\x02\x00\xF9\x68\x2E\x40\xF9\xF6\x03\x03\xAA\xB3\x23\x02\xA9\x00\x00\x00\xB5",
"xxxxxxxxxx?xxxxxxxxxxxxxx?xxxxxxxxxxxxxxxxxxxxxx??xx"
"\xF3\x53\xBE\xA9\xF5\x5B\x01\xA9\xFD\x7B\x00\xA9\xFD\x03\x00\x91\x30\x00\x80\x92\x00\x03\x04\xAA\xB0\x00\x00\xF9\x00\x03\x00\xAA\x00\x02\x00\xF9\x00\x2E\x40\xF9\x00\x03\x03\xAA\x00\x23\x02\xA9\x00\x00\x00\xB5",
"xxxxxxxxxx?xxxxxxxxx?xxxx?xx?xxx?xxx?xxx?xxx?xxx??xx"
);
if (match)
{
@ -3386,11 +3443,11 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets) @@ -3386,11 +3443,11 @@ void TryToFindTwinuiPCShellOffsets(DWORD* pOffsets)
}
}
#elif defined(_M_ARM64)
// F3 53 BC A9 F5 5B 01 A9 F7 13 00 F9 F9 17 00 F9 FB 1B 00 F9 FD 7B BC A9 FD 03 00 91 FF ?? 00 D1 30 00 80 92 FB 03 04 AA
// F3 53 BC A9 F5 5B 01 A9 F7 13 00 F9 F9 17 00 F9 FB 1B 00 F9 FD 7B BC A9 FD 03 00 91 FF ?? 00 D1 30 00 80 92 ?? 03 04 AA
PBYTE match = (PBYTE)FindPattern(
pFile, dwSize,
"\xF3\x53\xBC\xA9\xF5\x5B\x01\xA9\xF7\x13\x00\xF9\xF9\x17\x00\xF9\xFB\x1B\x00\xF9\xFD\x7B\xBC\xA9\xFD\x03\x00\x91\xFF\x00\x00\xD1\x30\x00\x80\x92\xFB\x03\x04\xAA",
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx?xxxxxxxxxx"
"\xF3\x53\xBC\xA9\xF5\x5B\x01\xA9\xF7\x13\x00\xF9\xF9\x17\x00\xF9\xFB\x1B\x00\xF9\xFD\x7B\xBC\xA9\xFD\x03\x00\x91\xFF\x00\x00\xD1\x30\x00\x80\x92\x00\x03\x04\xAA",
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx?xxxxxx?xxx"
);
if (match)
{

43
ExplorerPatcher/dllmain.c

@ -2431,20 +2431,20 @@ static void HookImmersiveMenuFunctions( @@ -2431,20 +2431,20 @@ static void HookImmersiveMenuFunctions(
GetModuleInformation(GetCurrentProcess(), module, &mi, sizeof(MODULEINFO));
#if defined(_M_X64)
// 40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 4C 8B B5 ? ? ? ? 41 8B C1
// 40 55 53 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 4C 8B ? ? ? ? ? 41 8B C1
PBYTE match = (PBYTE)FindPattern(
mi.lpBaseOfDll, mi.SizeOfImage,
"\x40\x55\x53\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x00\x00\x00\x00\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x85\x00\x00\x00\x00\x4C\x8B\xB5\x00\x00\x00\x00\x41\x8B\xC1",
"xxxxxxxxxxxxxxxxx????xxx????xxx????xxxxxx????xxx????xxx"
"\x40\x55\x53\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x00\x00\x00\x00\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x33\xC4\x48\x89\x85\x00\x00\x00\x00\x4C\x8B\x00\x00\x00\x00\x00\x41\x8B\xC1",
"xxxxxxxxxxxxxxxxx????xxx????xxx????xxxxxx????xx?????xxx"
);
#elif defined(_M_ARM64)
// 40 F9 43 03 1C 32 E4 03 15 AA ?? ?? FF 97
// 40 F9 43 03 1C 32 E4 03 ?? AA ?? ?? FF 97
// ^^^^^^^^^^^
// Ref: ImmersiveContextMenuHelper::ApplyOwnerDrawToMenu()
PBYTE match = (PBYTE)FindPattern(
mi.lpBaseOfDll, mi.SizeOfImage,
"\x40\xF9\x43\x03\x1C\x32\xE4\x03\x15\xAA\x00\x00\xFF\x97",
"xxxxxxxxxx??xx"
"\x40\xF9\x43\x03\x1C\x32\xE4\x03\x00\xAA\x00\x00\xFF\x97",
"xxxxxxxx?x??xx"
);
if (match)
{
@ -8801,7 +8801,7 @@ static void PatchAddressBarSizing(const MODULEINFO* mi) @@ -8801,7 +8801,7 @@ static void PatchAddressBarSizing(const MODULEINFO* mi)
VirtualProtect(match, 9, dwOldProtect, &dwOldProtect);
}
// CAddressBand::_AddressBandWndProc()
// CAddressBand::_AddressBandWndProc() <- CAddressBand::_GetAdjustedClientRect()
// 83 45 ?? ?? 83 6D ?? ?? 0F
// xx To 03 xx To 01
match = FindPattern(
@ -8810,11 +8810,32 @@ static void PatchAddressBarSizing(const MODULEINFO* mi) @@ -8810,11 +8810,32 @@ static void PatchAddressBarSizing(const MODULEINFO* mi)
"\x83\x45\x00\x00\x83\x6D\x00\x00\x0F",
"xx??xx??x"
);
if (match && VirtualProtect(match, 9, PAGE_EXECUTE_READWRITE, &dwOldProtect))
if (match)
{
match[3] = 3;
match[7] = 1;
VirtualProtect(match, 9, dwOldProtect, &dwOldProtect);
if (VirtualProtect(match, 9, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
match[3] = 3;
match[7] = 1;
VirtualProtect(match, 9, dwOldProtect, &dwOldProtect);
}
}
else
{
// CAddressBand::_GetAdjustedClientRect()
// 0F 1F 44 00 00 83 43 04 ?? 83 43 0C ??
// xx To 03 xx To FF (-1)
match = FindPattern(
mi->lpBaseOfDll,
mi->SizeOfImage,
"\x0F\x1F\x44\x00\x00\x83\x43\x04\x00\x83\x43\x0C",
"xxxxxxxx?xxx"
);
if (match && VirtualProtect(match + 5, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
match[8] = 3;
match[12] = (BYTE)-1;
VirtualProtect(match + 5, 8, dwOldProtect, &dwOldProtect);
}
}
}
else

47
ExplorerPatcher/utility.h

@ -605,6 +605,42 @@ inline BOOL IncrementDLLReferenceCount(HINSTANCE hinst) @@ -605,6 +605,42 @@ inline BOOL IncrementDLLReferenceCount(HINSTANCE hinst)
return TRUE;
}
inline void SectionBeginAndSize(HMODULE hModule, const char* pszSectionName, PBYTE* beginSection, DWORD* sizeSection)
{
*beginSection = NULL;
*sizeSection = 0;
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hModule;
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE)
{
PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS64)((BYTE*)dosHeader + dosHeader->e_lfanew);
if (ntHeader->Signature == IMAGE_NT_SIGNATURE)
{
PIMAGE_SECTION_HEADER firstSection = IMAGE_FIRST_SECTION(ntHeader);
for (unsigned int i = 0; i < ntHeader->FileHeader.NumberOfSections; ++i)
{
PIMAGE_SECTION_HEADER section = firstSection + i;
if (strncmp((const char*)section->Name, pszSectionName, IMAGE_SIZEOF_SHORT_NAME) == 0)
{
*beginSection = (PBYTE)dosHeader + section->VirtualAddress;
*sizeSection = section->SizeOfRawData;
break;
}
}
}
}
}
__forceinline void TextSectionBeginAndSize(HMODULE hModule, PBYTE* beginSection, DWORD* sizeSection)
{
SectionBeginAndSize(hModule, ".text", beginSection, sizeSection);
}
__forceinline void RDataSectionBeginAndSize(HMODULE hModule, PBYTE* beginSection, DWORD* sizeSection)
{
SectionBeginAndSize(hModule, ".rdata", beginSection, sizeSection);
}
PVOID FindPattern(PVOID pBase, SIZE_T dwSize, LPCSTR lpPattern, LPCSTR lpMask);
#if _M_X64
@ -665,6 +701,17 @@ __forceinline BOOL ARM64_IsCBZW(DWORD insn) { return ARM64_ReadBits(insn, 31, 24 @@ -665,6 +701,17 @@ __forceinline BOOL ARM64_IsCBZW(DWORD insn) { return ARM64_ReadBits(insn, 31, 24
__forceinline BOOL ARM64_IsCBNZW(DWORD insn) { return ARM64_ReadBits(insn, 31, 24) == 0b00110101; }
__forceinline BOOL ARM64_IsBL(DWORD insn) { return ARM64_ReadBits(insn, 31, 26) == 0b100101; }
__forceinline BOOL ARM64_IsADRP(DWORD insn) { return (ARM64_ReadBits(insn, 31, 24) & ~0b01100000) == 0b10010000; }
__forceinline BOOL ARM64_IsMOVZW(DWORD insn) { return ARM64_ReadBits(insn, 31, 23) == 0b010100101; }
__forceinline BOOL ARM64_IsSTRBIMM(DWORD insn) { return ARM64_ReadBits(insn, 31, 22) == 0b0011100100; }
__forceinline DWORD* ARM64_FollowCBNZW(DWORD* pInsnCBNZW)
{
DWORD insnCBNZW = *pInsnCBNZW;
if (!ARM64_IsCBNZW(insnCBNZW))
return NULL;
int imm19 = ARM64_ReadBitsSignExtend(insnCBNZW, 23, 5);
return pInsnCBNZW + imm19; // offset = imm19 * 4
}
__forceinline DWORD* ARM64_FollowBL(DWORD* pInsnBL)
{

78
ep_startmenu/ep_sm_main.c

@ -77,27 +77,7 @@ void PatchXamlMetaDataProviderGuid() @@ -77,27 +77,7 @@ void PatchXamlMetaDataProviderGuid()
PBYTE beginRData = NULL;
DWORD sizeRData = 0;
// Our target is in .rdata
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
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)
{
PIMAGE_SECTION_HEADER firstSection = IMAGE_FIRST_SECTION(ntHeader);
for (unsigned int i = 0; i < ntHeader->FileHeader.NumberOfSections; ++i)
{
PIMAGE_SECTION_HEADER section = firstSection + i;
if (!strncmp(section->Name, ".rdata", 6))
{
beginRData = (PBYTE)dosHeader + section->VirtualAddress;
sizeRData = section->SizeOfRawData;
break;
}
}
}
}
RDataSectionBeginAndSize(GetModuleHandleW(NULL), &beginRData, &sizeRData);
if (!beginRData || !sizeRData)
{
return;
@ -132,6 +112,62 @@ void Init() @@ -132,6 +112,62 @@ void Init()
LoadLibraryW(L"JumpViewUI_.dll");
g_bIsUsingOwnJumpViewUI = TRUE;
}
PBYTE beginText = NULL;
DWORD sizeText = 0;
TextSectionBeginAndSize(GetModuleHandleW(NULL), &beginText, &sizeText);
if (beginText && sizeText)
{
// Fix 0x800704DA (The service is already registered) exception when feature flag 58205615 is enabled
// Feature flag introduced in:
// - Germanium Client 26100.5742+
// - Germanium Server 26461+
// - Bromine Canary 27924+ (reworked in 27938)
// Used to be inlined in StartMenuExperienceHost::App::OnLaunched(), the rework made it be called using
// std::call_once, therefore we have a function that we can make it do nothing.
// StartMenuExperienceHost::App::SetExperienceManagerPropertiesAsync()
// Early return that function
#if defined(_M_X64)
// TODO Improve pattern
// 40 53 57 48 83 EC 28 E8 ?? ?? ?? ?? 48 8B D8 48 89 44 24 40 48 8B C8
PBYTE match = FindPattern(
beginText,
sizeText,
"\x40\x53\x57\x48\x83\xEC\x28\xE8\x00\x00\x00\x00\x48\x8B\xD8\x48\x89\x44\x24\x40\x48\x8B\xC8",
"xxxxxxxx????xxxxxxxxxxx"
);
if (match)
{
DWORD dwOldProtect = 0;
if (VirtualProtect(match, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
match[0] = 0xC3; // ret
VirtualProtect(match, 1, dwOldProtect, &dwOldProtect);
}
}
#elif defined(_M_ARM64)
// TODO Improve pattern
// 7F 23 03 D5 F3 53 BF A9 FD 7B BC A9 FD 03 00 91 30 00 80 92
// ----------- PACIBSP, don't scan for this because it's everywhere
PBYTE match = FindPattern(
beginText,
sizeText,
"\xF3\x53\xBF\xA9\xFD\x7B\xBC\xA9\xFD\x03\x00\x91\x30\x00\x80\x92",
"xxxxxxxxxxxxxxxx"
);
if (match)
{
match -= 4; // include PACIBSP
DWORD dwOldProtect = 0;
if (VirtualProtect(match, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
*(DWORD*)match = 0xD65F03C0; // RET
VirtualProtect(match, 4, dwOldProtect, &dwOldProtect);
}
}
#endif
}
}
HMODULE hMod;
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, hModule, &hMod);

2
version.h

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
#define VER_MAJOR 26100
#define VER_MINOR 4946
#define VER_BUILD_HI 69
#define VER_BUILD_LO 2
#define VER_BUILD_LO 3
#define VER_FLAGS VS_FF_PRERELEASE

Loading…
Cancel
Save