Skip to content

Commit 6c76872

Browse files
committed
fix: resolve PspTerminateThreadByPointer signature scanning for Win11
Win11 26100+ changed PsTerminateSystemThread layout: it now has a full stack frame and calls PspTerminateThreadByPointer via 'mov r8b,1; call' (41 B0 01 E8) instead of a direct E9 jmp. The old single-byte E9 scan would match an unrelated jmp at offset 0xA6, resolving the wrong address. New strategy: prioritize Win11 4-byte pattern (41 B0 01 E8), then check for E9 within the first 16 bytes (Win10), with a generic E8 fallback.
1 parent 73be60f commit 6c76872

1 file changed

Lines changed: 31 additions & 11 deletions

File tree

‎src/process.cpp‎

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ typedef PETHREAD (NTAPI* PFN_PS_GET_NEXT_PROCESS_THREAD)(
3838

3939
// ========== PspTerminateThreadByPointer 解析 ==========
4040
//
41-
// PsTerminateSystemThread 内部以 E9 rel32 跳转到 PspTerminateThreadByPointer,
42-
// 扫描 0xFF 字节内定位目标地址。
41+
// Win10: PsTerminateSystemThread 开头直接 E9 rel32 跳转到 PspTerminateThreadByPointer
42+
// Win11: 函数有完整 stack frame,通过 41 B0 01 E8 rel32 (mov r8b,1; call) 调用
4343
//
4444

4545
typedef NTSTATUS(__fastcall* PFN_PSP_TERMINATE_THREAD)(
@@ -97,23 +97,43 @@ VOID ResolvePspTerminateThread()
9797
DbgPrint("[OpenSysKit] [Resolve] PsTerminateSystemThread=%p\n", pBase);
9898

9999
PVOID pEnd = (PVOID)((PUCHAR)pBase + 0xFF);
100+
PVOID pRelOffset = nullptr;
101+
102+
// Win11 26100+: PsTerminateSystemThread 有完整 stack frame,
103+
// 通过 "mov r8b, 1; call PspTerminateThreadByPointer" (41 B0 01 E8) 调用。
104+
// 必须优先匹配此模式,因为函数后部存在不相关的 E9 会导致误匹配。
105+
UCHAR patternWin11[] = { 0x41, 0xB0, 0x01, 0xE8 };
106+
PVOID pWin11 = SearchPattern(pBase, pEnd, patternWin11, sizeof(patternWin11));
107+
if (pWin11) {
108+
DbgPrint("[OpenSysKit] [Resolve] Win11 pattern (41 B0 01 E8) matched\n");
109+
pRelOffset = pWin11;
110+
}
100111

101-
// 先尝试 E9(jmp),再尝试 E8(call)
102-
UCHAR patternE9 = 0xE9;
103-
UCHAR patternE8 = 0xE8;
112+
// Win10/Win8.1: PsTerminateSystemThread 开头直接 E9 jmp PspTerminateThreadByPointer
113+
if (!pRelOffset) {
114+
PUCHAR pFirstByte = (PUCHAR)pBase;
115+
// 在前 16 字节内找 E9,避免匹配函数体深处不相关的 jmp
116+
for (PUCHAR p = pFirstByte; p < pFirstByte + 16 && p < (PUCHAR)pEnd; p++) {
117+
if (*p == 0xE9) {
118+
pRelOffset = (PVOID)(p + 1);
119+
DbgPrint("[OpenSysKit] [Resolve] Win10 pattern (E9 at +%d) matched\n",
120+
(int)(p - pFirstByte));
121+
break;
122+
}
123+
}
124+
}
104125

105-
PVOID pRelOffset = SearchPattern(pBase, pEnd, &patternE9, 1);
106-
if (pRelOffset) {
107-
DbgPrint("[OpenSysKit] [Resolve] found E9\n");
108-
} else {
126+
// 通用回退:在整个范围内搜索 E8(call)
127+
if (!pRelOffset) {
128+
UCHAR patternE8 = 0xE8;
109129
pRelOffset = SearchPattern(pBase, pEnd, &patternE8, 1);
110130
if (pRelOffset) {
111-
DbgPrint("[OpenSysKit] [Resolve] found E8\n");
131+
DbgPrint("[OpenSysKit] [Resolve] fallback E8 matched\n");
112132
}
113133
}
114134

115135
if (!pRelOffset) {
116-
DbgPrint("[OpenSysKit] [Resolve] neither E9 nor E8 found in PsTerminateSystemThread\n");
136+
DbgPrint("[OpenSysKit] [Resolve] no pattern matched in PsTerminateSystemThread\n");
117137
return;
118138
}
119139

0 commit comments

Comments
 (0)