Fix: Client misparses screen-control batches when record count is a multiple of 7

ProcessCommand chose the MSG record size by testing "ulLength % 28 == 0"
before "% 48 == 0". The two sizes' least common multiple is 336 (7*48 =
12*28), so a 48-byte batch whose record count is a multiple of 7 was
misclassified as 28-byte MSG32 records, shifting every field and garbling
(or silently dropping) injected input.

Check "% 48 == 0" first. The modern controller always emits 48-byte MSG64;
the 28-byte MSG32 path is legacy 32-bit-controller compatibility and is only
reached when 48 does not divide evenly. This is the first feature (MCP
remote_keyboard "type", and the upcoming remote_mouse drag) to emit
multi-record batches, which is what made the latent bug reachable.

Co-Authored-By: deepseek-v4-pro
This commit is contained in:
yuanyuanxiang
2026-08-25 13:21:54 +02:00
parent 09018e2b4d
commit c844ba7614

View File

@@ -1726,11 +1726,15 @@ bool IsExtendedKey(WPARAM vKey)
VOID CScreenManager::ProcessCommand(LPBYTE szBuffer, ULONG ulLength) VOID CScreenManager::ProcessCommand(LPBYTE szBuffer, ULONG ulLength)
{ {
// 记录大小判定:现代控制端(本服务端)统一发 48 字节 MSG6428 字节 MSG32 仅为兼容
// 老 32 位控制端。二者长度的最小公倍数是 336=7×48=12×28批量注入如 MCP 远程
// 控制的 type/拖拽)时若先判 %28会把 7 的整数倍条 MSG64 误判成 MSG32字段错位导致
// 输入错乱甚至吞掉按键;故先判 %48仅当不整除 48 才回落到 28。
int msgSize = sizeof(MSG64); int msgSize = sizeof(MSG64);
if (ulLength % 28 == 0) // 32位控制端发过来的消息 if (ulLength % 48 == 0) // 64位控制端(现代服务端)发过来的消息
msgSize = 28;
else if (ulLength % 48 == 0) // 64位控制端发过来的消息
msgSize = 48; msgSize = 48;
else if (ulLength % 28 == 0) // 32位控制端发过来的消息兼容
msgSize = 28;
else return; // 数据包不合法 else return; // 数据包不合法
// 命令个数 // 命令个数