Microsoft Pinyin (ChsIME.exe) on Windows 11 25H2: a second IME instance accumulates kernel-mode CPU close to one core; historical samples show persistent TSF connect failures
Summary
On Windows 11 25H2 (Build 26200.9711), ChsIME.exe (Microsoft Pinyin IME) is registered as an out-of-process COM local server: CImeServerChs, under two CLSIDs, each with a LocalServer32 subkey whose default value points at C:\Windows\System32\InputMethod\CHS\ChsIME.exe. In the registry views we queried, neither CLSID has an AppID value, and neither has a LocalService or LocalSystem value. RunAs is configured on an AppID key rather than on a CLSID key, so no RunAs setting applies to an activation that resolves through these CLSIDs. We did not enumerate AppID keys elsewhere in the registry, so this is not a claim that no such key exists.
Impact observed on our test machine. On 2026-09-07 an affected instance ran for about four hours, with the lid closed for about two of them; the case record for that incident notes sustained high fan speed, and battery charge fell from 100% (29,032 mWh) to 15% (4,499 mWh) between 21:58 and 23:43. A later instance (activated 2026-09-20, captured 2026-09-22) had accumulated about 47.3 hours of kernel-mode CPU over 51.7 hours of uptime when it was captured. Over the 31-day monitoring window, some instances ended only after manual intervention. Separately, in controlled activation attempts on 2026-09-22, the resulting instance could neither be opened nor terminated by our non-elevated test process. We have not isolated the mechanism of the battery drain; the CPU accounting is the part we can quantify.
On our test machine we observed two ChsIME.exe instances running side by side with the same parent process, svchost.exe (PID 1240). One had 78 threads; the other had 2. The second accumulates CPU time almost entirely in kernel mode: one affected instance took 69.925 hours of kernel-mode CPU over 75.51 hours of wall-clock uptime (~92.6% of one core).
Separately, September captures from an earlier affected instance recorded repeated TSF connection failures on the monitor port \BaseNamedObjects\msctf.serverDefault1. We have not established that the October instance followed the same failure path.
We do not know which process requested the activation, and we have not established the exact failure status returned by the connect attempt. Both are listed below as open questions rather than findings.
Environment
- Windows 11 25H2, Build 26200.9711. Note:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersionstill reportsProductName = Windows 10 Enterprise; the Windows 11 / 25H2 identification is based onDisplayVersion = 25H2withCurrentBuild = 26200andUBR = 9711(re-measured 2026-10-26). -
C:\Windows\System32\InputMethod\CHS\ChsIME.exe, file version 10.0.26100.9278, ownerNT SERVICE\TrustedInstaller, Authenticode statusValid— re-measured 2026-10-26 (signer subject not re-captured in this record). - The observations concern the single interactive user session, with Chinese (Simplified) IME installed. Desktop affiliation at failure time was not recorded.
-
TextInputManagementService(the renamed Touch Keyboard / Handwriting Panel service), statusRunning, startup typeAutomatic— re-measured 2026-10-26.
Observed behavior
| Observation | Value |
|---|---|
| Instances coexisting | Two ChsIME.exe with the same parent svchost.exe (PID 1240); the hosting service group was not verified. Thread counts 78 and 2 |
| Threads | Long-lived 78; affected 2 (range across cases: 2–8) |
| CPU accounting (affected) | 69.925 h kernel + 0.816 h user over 75.51 h uptime (~92.6% of one core in kernel mode) |
| Connect attempts (historical sample) | 170 Start events span 2.5385173 s, giving 169 inter-start intervals → 66.574 starts/s. Same-thread, time-ordered pairing yields 169 complete Start→Failed intervals after excluding the unmatched boundary events: mean 14.933 ms, median 14.764 ms, minimum 10.3177 ms |
| Occurrences | Monitoring identified 7 distinct process instances matching the low-thread / high-kernel-CPU criterion over 31.078 days (2026-09-24 → 2026-10-25). The 1,918 retained latches include repeated records of the same instances (4 log files contain 1,921 LATCH lines, of which 3 are self-test); 7 groups is not 7 independently verified mechanisms |
| Age at last retained snapshot | 0.35 h to 93.9 h (process age at capture, not confirmed lifetime) |
| HOW it ends | Some instances ended after manual intervention; termination cause for the rest is not individually determined |
Retry cadence and Start→Failed intervals are wall-clock measurements, not CPU costs. Their arithmetic product (≈0.994, dimensionless) must not be read as CPU time, and the earlier "more than one core" reading is incorrect. Process accounting establishes the high cumulative kernel CPU usage; the captured stack identifies a sampled call path, not its share of CPU consumption. The ~92.6% figure is cumulative kernel CPU time divided by process age: it is a lifetime average, not evidence that the process was busy in every interval.
Evidence inventory (capture dates shown; historical version coverage incomplete)
The historical mechanism evidence has not been verified against the October build.
| ID | Evidence | How obtained | Grade |
|---|---|---|---|
| A1 | Both CLSIDs resolve to CImeServerChs, and under each the LocalServer32 subkey's default value points at ChsIME.exe. The property list under each CLSID contains only its default value: no AppID value, and no LocalService or LocalSystem value. Because RunAs is an AppID-key setting, no RunAs applies to an activation that resolves through these CLSIDs. HKCU and WOW6432Node CLSID overrides were absent. AppID keys elsewhere in the registry were not exhaustively enumerated; an earlier query that addressed AppID\ChsIME.exe by executable name returned nothing, which is not evidence of absence. Scope of the query: HKLM 64-bit and 32-bit views plus current-user HKCU, 2026-10-25 |
reg query / registry property read, 2026-10-25 |
Measured (within the views queried) |
| A2 | Affected command line ChsIME.exe -Embedding; parent svchost.exe. The -Embedding switch indicates that the process was launched as a COM local server; it does not identify the activating client or the CLSID used |
Win32_Process, 2026-10-25 |
Measured |
| A3a | Token attributes measured during the 2026-09-07 incident (measurements taken 2026-09-08, 00:06–01:30): spinning instance PID 51828 = S-1-16-8192 (Medium); ctfmon.exe (PID 26236) = S-1-16-12288 (High); our probe process = S-1-16-8192 (Medium), and its connections to \BaseNamedObjects\msctf.serverDefault1 succeeded 4/4 (a deliberately bogus port name returned STATUS_OBJECT_NAME_NOT_FOUND) |
OpenProcessToken + GetTokenInformation(TokenIntegrityLevel / TokenUIAccess), 2026-09-08 |
Measured |
| A3b | Token attributes recorded later: long-lived instance PID 14660 = IL=0x3000, UIAccess=1; second instance PID 12972 could not be opened from a non-elevated process (OpenProcess → error 5). The affected instance's Medium (0x2000) / UIAccess=0 comes from contemporaneous case notes, not an independent token export. An earlier query on 2026-09-22 returned an invalid integrity RID (0x60) and is discarded as a code defect |
OpenProcessToken + GetTokenInformation, 2026-10-25 |
Recorded (no original export retained) |
| A4 | An XML string found in the executable contains requestedExecutionLevel level="asInvoker" uiAccess="false". The retained record documents a byte-string search, not enumeration of PE manifest resources |
Byte-string search of the image (UTF-8 decode + regex), 2026-10-25 | Measured (string found) / not conclusive (manifest structure) |
| A5 | Retry cadence and failure events on the affected thread | ETW tsf trace, 2026-09 |
Measured (2026-09 capture; event XML also contains the machine name — see sanitization note) |
| A6 | Process age and CPU accounting per instance | Retained per-instance snapshots; latest October snapshot. Exact per-instance timestamps and PID mappings are kept in our local records | Measured |
| A7 | Historical dump stacks include msctf!CAlpcPort::Open and NtAlpcConnectPortEx. ETW separately records repeated connection failures on the affected thread, and disassembly shows a reconnect path that does contain a wait (WaitForMultipleObjectsEx, 1000 ms or INFINITE); in the build we disassembled (msctf 10.0.26100.8875, from the 2026-09-22 dump) and in the code paths we followed, we found no explicit increasing backoff and no retry cap |
Dump analysis + ETW + disassembly; dump captured 2026-09-22, ETW captured 2026-09 | Measured (stack sample / ETW events) / not conclusive (backoff absence, CPU share) |
Note on A3a — same integrity level, different outcome
On 2026-09-07 the spinning instance and our probe process were both at Medium (the probe was run after midnight, on 2026-09-08). The probe connected to the monitor port four times in a row, while the affected instance did not. This is the single most informative comparison we have: it means the difference between "connects" and "does not connect" is not explained by integrity level alone.
We previously assumed a security-context rejection. That assumption is withdrawn insofar as it rests on integrity level alone; other differences in security context have not been excluded. We still do not know the actual failure status of the affected instance's connect calls; the ETW failure events carry no status payload.
What we did not establish
- Which process (or component) requested the activation.
- The exact status returned when connecting to
msctf.serverDefault1; our failure events carry no status payload. - Whether the TSF monitor rejects the connection on integrity/UIAccess grounds, on some other security check, or for another reason. Note that a probe at the same integrity level connected successfully, so a pure integrity-level rule is not supported.
- Whether the system's decision to create a second instance instead of reusing the long-lived one is a documented rule, and what inputs it uses.
- A stable reproduction of the natural failure: the controlled attempts did not reproduce the high-CPU symptom. A bare COM activation did not produce a spinning instance, and in the GUI attempt the resulting instance could not be opened or terminated by the non-elevated test process; its integrity level was not directly established.
Questions for Microsoft
Primary request: please investigate the reported high kernel-mode CPU usage in ChsIME.exe, and tell us which supported diagnostics are needed to determine the cause.
- What is the intended activation and security context for the
CImeServerChslocal server? Should a medium-integrity caller be able to activate a functional instance, and if not, what is the expected outcome for that caller? - What determines whether an existing
ChsIME.exeinstance is reused or a new one is created? We observe two instances with the same parent; we do not know which rule produced that. - In the retry path (symbolized as
msctf!CAlpcPort::Open→NtAlpcConnectPortEx), is a persistent connect failure expected to be bounded? Inmsctf10.0.26100.8875 and the code paths we followed, we did not find an explicit increasing backoff or a retry cap; the observed behaviour is a sustained high-frequency failure loop. - Which diagnostics would let us determine (a) the activating client and (b) the actual connect failure status? Is there a supported channel to submit raw dumps and ETW traces?
- Is terminating the affected instance the recommended workaround, or is there a supported mitigation?
- Could a desktop switch, or an application disabling and then re-enabling the IME, affect
CImeServerChsinitialization or its connection to the monitor? Which supported diagnostics distinguish desktop/session state from a security-context rejection? We have not recorded the desktop affiliation at failure time.