Browse Source

Start10: Revise CStartExperienceManager::Hide() patching on ARM64.

Now works on 27881+.
pull/4568/merge
Amrsatrio 3 months ago
parent
commit
201a7e5bed
  1. 108
      ExplorerPatcher/TwinUIPatches.cpp
  2. 11
      ExplorerPatcher/utility.h

108
ExplorerPatcher/TwinUIPatches.cpp

@ -2309,61 +2309,63 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi)
} }
#elif defined(_M_ARM64) #elif defined(_M_ARM64)
// ``` // ```
// ?? ?? ?? 34 ?? 00 80 52 ?? 8E 0A 39 // E1 03 ?? 2A ?? ?? 04 91 ?? ?? ?? ?? ?? 03 00 2A
// ^^^^^^^^^^^ Turn CBZ into B // ```
// Check two instructions before, and NOP these:
// ```
// MOV W??, #3
// STRB W??, [X??,#0x???]
// ``` // ```
// Perform on exactly two matches // 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->lpBaseOfDll,
mi->SizeOfImage, mi->SizeOfImage,
"\x34\x00\x00\x80\x52\x00\x8E\x0A\x39", "\xE1\x03\x00\x2A\x00\x00\x04\x91\x00\x00\x00\x00\x00\x03\x00\x2A",
"x?xxx?xxx" "xx?x??xx?????xxx"
); );
PBYTE matchHideB = nullptr; if (matchHideAAfter)
{
matchHideA = findTheIfBody(matchHideAAfter);
}
if (matchHideA) if (matchHideA)
{ {
matchHideA -= 3; printf("[SMA] matchHideA in CStartExperienceManager::Hide() = %llX\n", matchHideA - (PBYTE)mi->lpBaseOfDll);
printf("[SMA] matchHideA in CStartExperienceManager::Hide() = %llX (Pattern A)\n", matchHideA - (PBYTE)mi->lpBaseOfDll); PBYTE matchHideBAfter = (PBYTE)FindPattern(
matchHideB = (PBYTE)FindPattern( matchHideAAfter + 16,
matchHideA + 12, 1024,
mi->SizeOfImage - (matchHideA + 12 - (PBYTE)mi->lpBaseOfDll), "\xE1\x03\x00\x2A\x00\x00\x04\x91\x00\x00\x00\x00\x00\x03\x00\x2A",
"\x34\x00\x00\x80\x52\x00\x8E\x0A\x39", "xx?x??xx?????xxx"
"x?xxx?xxx"
); );
if (matchHideB) if (matchHideBAfter)
{ {
matchHideB -= 3; matchHideB = findTheIfBody(matchHideBAfter);
printf("[SMA] matchHideB in CStartExperienceManager::Hide() = %llX (Pattern A)\n", matchHideB - (PBYTE)mi->lpBaseOfDll);
} }
} if (matchHideB)
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)
{ {
matchHideA -= 3; printf("[SMA] matchHideB in CStartExperienceManager::Hide() = %llX\n", matchHideB - (PBYTE)mi->lpBaseOfDll);
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);
}
} }
} }
#endif #endif
@ -2405,20 +2407,18 @@ BOOL FixStartMenuAnimation(LPMODULEINFO mi)
} }
} }
#elif defined(_M_ARM64) #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); *(DWORD*)(matchHideA + 0) = 0xD503201F; // NOP
if (newInsn) *(DWORD*)(matchHideA + 4) = 0xD503201F; // NOP
*(DWORD*)matchHideA = newInsn; VirtualProtect(matchHideA, 8, dwOldProtect, &dwOldProtect);
VirtualProtect(matchHideA, 4, dwOldProtect, &dwOldProtect);
dwOldProtect = 0; dwOldProtect = 0;
if (VirtualProtect(matchHideB, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect)) if (VirtualProtect(matchHideB, 8, PAGE_EXECUTE_READWRITE, &dwOldProtect))
{ {
newInsn = ARM64_CBZWToB(*(DWORD*)matchHideB); *(DWORD*)(matchHideB + 0) = 0xD503201F; // NOP
if (newInsn) *(DWORD*)(matchHideB + 4) = 0xD503201F; // NOP
*(DWORD*)matchHideB = newInsn; VirtualProtect(matchHideB, 8, dwOldProtect, &dwOldProtect);
VirtualProtect(matchHideB, 4, dwOldProtect, &dwOldProtect);
} }
} }
#endif #endif

11
ExplorerPatcher/utility.h

@ -665,6 +665,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_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_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_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) __forceinline DWORD* ARM64_FollowBL(DWORD* pInsnBL)
{ {

Loading…
Cancel
Save