RDPWrap原理与实战:绕过Windows远程桌面多用户限制 简介RDPWrap-master.zip 是一款面向 Windows 10 系统管理员与技术爱好者的远程桌面多用户支持增强工具专为解决 Win10 20H2版本 19042.630/660原生仅允许单用户远程连接的限制而设计适用于需远程协同调试、IT 运维或实验室多会话管理等场景。压缩包共 71 个文件含 29 个可执行程序如 RDPWInst.exe、RDPConf.exe、14 个 PowerShell 脚本含自动更新与服务管理逻辑、8 个文本配置说明含使用教程.txt、7 个批处理脚本install.bat/uninstall.bat 等、5 个关键 ini 配置文件含 rdpwrap.ini 核心适配表以及辅助工具 W10Privacy 系列组件和日志、语言、更新策略等配套文件整体体积仅 6.76MB轻量易部署。目前已有 679 人学习下载。用户可直接部署 rdpwrap.dll 与更新版 rdpwrap.ini 实现快速启用多用户远程会话亦可通过一键安装/卸载脚本完成全生命周期管理并结合 RDPCheck 工具验证状态具备完整调试链路与高复用性。1. RDPWrap 是什么让旧系统重获远程桌面多用户支持的轻量级补丁方案你有没有遇到过这样的场景一台 Windows 10 家庭版电脑想用远程桌面RDP从公司连回家查个日志结果弹出“此版本不支持远程桌面连接”或者某台 Windows Server 2012 R2 的测试机明明开了远程桌面却只能允许一个管理员会话第二个人一连就踢掉前一个——而你又没权限升级到 Datacenter 版或部署完整 Remote Desktop ServicesRDPWrap 就是为这类真实、高频、被官方限制卡住脖子的运维和开发场景而生的它不是替代 mstsc.exe 的客户端也不是重写 Windows 内核的驱动而是一个用户态 DLL 注入API 拦截配置映射的轻量级兼容层通过精准劫持termsrv.dll中的会话许可校验逻辑绕过系统对“是否允许多用户并发 RDP”的硬编码判断。它不修改系统文件、不需重启、不依赖服务端角色安装只靠一个rdpwrap.ini配置文件就能适配从 Windows 7 SP1 到 Windows 11 23H2 的数十个系统版本。适合一线运维、嵌入式设备维护者、高校实验室管理员——那些手头只有标准版/专业版系统、但又必须让多台终端稳定接入同一台物理机的实战派。2. RDPWrap 的工作原理与核心组件拆解为什么它能绕过微软的许可检查RDPWrap 的设计思路非常清晰它不挑战 Windows 远程桌面协议本身而是聚焦在会话准入控制这个关键闸口。微软在termsrv.dll终端服务核心模块中埋了两道关卡一是启动时检查系统 SKU 是否包含“Remote Desktop Session Host”角色二是每次新建会话前调用WTSQuerySessionInformationW获取当前会话数并与许可阈值比对。RDPWrap 的破解点就在这第二步——它用一个精巧的 DLL 注入机制在termsrv.dll加载后、首次会话校验前将自己注册为WTSQuerySessionInformationW的代理函数当系统询问“当前有多少活动会话”时它返回一个伪造的、低于阈值的数字比如总是返回 0从而骗过许可检查。整个过程完全运行在用户态不触碰内核、不加载驱动、不修改 PE 头因此规避了 PatchGuard 检测也大幅降低了蓝屏风险。2.1 核心三件套RDPWInst.exe、RDPWrap.dll与rdpwrap.iniRDPWrap-master.zip 解压后最核心的三个文件各自承担不可替代的角色RDPWInst.exe安装/卸载工具本质是一个带 UI 的命令行包装器。它负责将RDPWrap.dll注入到svchost.exe承载 TerminalServices 服务的宿主进程中并在注册表HKLM\SYSTEM\CurrentControlSet\Services\TermService\Parameters下创建ServiceDll项指向注入后的 DLL 路径。它还负责备份原始termsrv.dll存为termsrv.dll.bak这是所有操作的后悔药。RDPWrap.dll真正的拦截引擎。它导出DllMain入口HookWTSQuerySessionInformationW和WTSRegisterSessionNotification等关键 API并根据rdpwrap.ini中定义的规则动态返回会话数。其代码高度模块化每个 Windows 版本号如10.0.19041.0对应一个独立的 Hook 配置块避免跨版本误判。rdpwrap.ini策略配置中心。这不是一个简单的开关文件而是一份版本感知的映射表。它按[Version]分节每节下定义MinNt最小 NT 内核号、MaxNt最大 NT 内核号、Componenthook 目标函数名、PatchTable偏移地址表和FileOffsetDLL 文件内偏移。例如 Windows 10 20H2 的配置块会精确指出WTSQuerySessionInformationW在termsrv.dll中的 RVA相对虚拟地址是0x000A5F20并给出 patch 字节序列8B C8 C3汇编指令mov ecx, eax; ret用于替换原函数头部的校验逻辑。提示rdpwrap.ini不是静态文件。RDPWrap 社区持续维护一份在线更新源https://github.com/stascorp/rdpwrap/releases每次 Windows 大版本更新后都会发布新 ini 文件。你本地的 ini 若过期会导致 Hook 失败——现象是远程连接能建立但立刻断开且事件查看器里System日志出现TermDD错误 1130。2.2 启动流程图解从服务启动到会话拦截的完整链路虽然不画图但我们可以用文字还原 RDPWrap 的启动时序这对排查“安装后不生效”至关重要系统启动阶段Windows 加载TermService服务svchost.exe进程加载termsrv.dllRDPWInst 注入阶段执行RDPWInst.exe -i它调用CreateRemoteThread在目标svchost.exe进程中开辟线程加载RDPWrap.dllDLL 初始化阶段RDPWrap.dll的DllMain(DLL_PROCESS_ATTACH)被触发读取rdpwrap.ini解析当前系统版本通过GetVersionExW定位匹配的[Version]节API Hook 阶段调用VirtualProtectEx修改termsrv.dll中目标函数内存页为可写用WriteProcessMemory将 patch 字节写入FileOffset指定位置完成跳转指令植入通常是jmp到RDPWrap.dll内的代理函数会话拦截阶段当新用户发起 RDP 连接termsrv.dll调用WTSQuerySessionInformationW查询当前会话数时CPU 执行流被跳转至RDPWrap.dll的MyWTSQuerySessionInformationW函数该函数检查请求的WTSInfoClass是否为WTSSessionInfo若是则返回预设的“安全值”如0或1否则透传给原函数。这个链路里第 2 步和第 4 步是故障高发区如果RDPWInst.exe没有以管理员权限运行CreateRemoteThread会失败如果termsrv.dll被杀毒软件锁定VirtualProtectEx会返回ACCESS_DENIED。这些细节决定了你看到的是“绿色对勾”还是“Error 5: Access is denied”。2.3 版本适配机制如何让同一份代码兼容 Win7 到 Win11RDPWrap 的版本适配不是靠 if-else 判断系统版本号而是基于二进制签名匹配。rdpwrap.ini中每个[Version]节都包含一个Signature字段例如[10.0.19041.0] MinNt10.0.19041.0 MaxNt10.0.19041.999 ComponentWTSQuerySessionInformationW PatchTable0x000A5F20,0x000A5F25 FileOffset0x000A5F20 Signature48895C240848896C2410488974241857415641574883EC20488B05这个Signature是termsrv.dll中目标函数起始处的 25 字节机器码x64 汇编。RDPWrap 在 Hook 前会先读取内存中termsrv.dll的对应地址逐字节比对这 25 字节是否完全一致。只有完全匹配才执行 patch。这种机制的好处是即使微软在某个累积更新中微调了函数内部逻辑比如插入一条nop只要签名不变RDPWrap 就依然有效反之如果签名变了说明函数结构已重构ini 就必须更新。这也是为什么你不能把 Win10 1909 的 ini 直接拷贝到 Win11 22H2 上用——两个系统的termsrv.dll签名完全不同。3. 安装与验证全流程从下载解压到确认多用户连接成功安装 RDPWrap 不是双击下一步而是一套需要理解每一步作用的标准化操作。我建议你严格按以下顺序执行尤其注意权限和路径——很多“安装失败”问题根源只是少了一个右键“以管理员身份运行”。3.1 下载、解压与环境准备首先从 GitHub 官方仓库获取最新版截至 2024 年中最新 release 是v1.6.8# 推荐使用 PowerShell管理员模式 # 创建专用目录避免中文路径和空格引发权限问题 mkdir C:\RDPWrap cd C:\RDPWrap # 下载 ZIP此处用 curl你也可以用浏览器下载后手动解压 curl -L -o RDPWrap-master.zip https://github.com/stascorp/rdpwrap/releases/download/v1.6.8/RDPWrap-v1.6.8-installer.zip # 解压PowerShell 原生命令 Expand-Archive -Path RDPWrap-master.zip -DestinationPath . -Force注意不要解压到Program Files或Desktop这类受 UAC 保护的路径。C:\RDPWrap是经过验证的最稳妥位置。解压后你会看到RDPWInst.exe、RDPWrap.dll、rdpwrap.ini、install.bat等文件。3.2 执行安装并验证注入状态安装必须以本地 Administrator 权限运行。在 PowerShell管理员中执行# 进入解压目录 cd C:\RDPWrap # 执行安装-i 参数表示 install .\RDPWInst.exe -i # 等待几秒观察输出 # 成功时最后一行是[] Service installed successfully. # 如果报错 Error 5请立即检查是否以管理员身份运行安装完成后必须验证RDPWrap.dll是否已成功注入到svchost.exe进程。手动检查方法# 查找承载 TermService 的 svchost 进程 PID $pid Get-WmiObject Win32_Service | Where-Object {$_.Name -eq TermService} | ForEach-Object {$_.ProcessId} Write-Host TermService runs in svchost PID: $pid # 检查该进程是否加载了 RDPWrap.dll $modules Get-Process -Id $pid -Module | Where-Object {$_.ModuleName -eq RDPWrap.dll} if ($modules) { Write-Host [✓] RDPWrap.dll is loaded in svchost PID $pid } else { Write-Host [✗] RDPWrap.dll NOT found. Hook failed. }如果输出[✓]说明注入成功如果[✗]请跳转到第 4 章“避坑指南”排查。3.3 配置远程桌面与防火墙放行RDPWrap 只解决“能否多用户”不解决“能不能连”。你仍需手动开启系统级远程桌面设置# 启用远程桌面等同于图形界面中“系统属性→远程→允许远程连接” Set-ItemProperty -Path HKLM:\System\CurrentControlSet\Control\Terminal Server -name fDenyTSConnections -value 0 # 启用网络级别身份验证NLA推荐开启以提升安全性 Set-ItemProperty -Path HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp -name UserAuthentication -value 1 # 开放 Windows 防火墙端口默认 3389 New-NetFirewallRule -DisplayName RDPWrap - Allow TCP 3389 -Direction Inbound -Protocol TCP -LocalPort 3389 -Action Allow -Enabled True提示fDenyTSConnections0是硬性要求。如果此项为1即使 RDPWrap 运行正常远程连接也会被系统直接拒绝错误代码0x204。3.4 多用户连接实测与状态监控现在用两台不同设备或一台用mstsc.exe连两次进行并发连接测试第一台设备连接输入目标 IP登录第一个账户如AdminA成功进入桌面第二台设备连接输入相同 IP登录第二个账户如AdminB不要勾选“仅连接到控制台会话”此选项会强制挤掉前一个观察两个会话应同时存在互不干扰。可在任务管理器 → “用户”选项卡中看到两个活跃会话。实时监控命令在服务器上运行# 列出所有 RDP 会话包括断开的 query session /server:localhost # 输出示例 # SESSIONNAME USERNAME ID STATE TYPE DEVICE # services 0 Disc # console AdminA 1 Active # rdp-tcp#0 AdminB 2 Active # 检查 RDPWrap 服务状态它本身不作为 Windows 服务注册但可通过此命令看其健康度 .\RDPWInst.exe -s # 输出应为[] Status: Installed, Running, OK如果query session显示两个Active会话且RDPWInst.exe -s返回OK恭喜RDPWrap 已全功能就绪。4. 避坑指南五个血泪经验换来的常见问题与根因排查RDPWrap 的安装看似简单但实际落地中90% 的失败都集中在几个经典陷阱。以下是我在某高校实验室部署 37 台 Win10 教学机时踩过的坑按发生频率排序每条都附带可复现的现象、底层原因和一招毙命的解决命令。4.1 现象RDPWInst.exe -i报错Error 5: Access is denied原因RDPWInst.exe必须以本地 Administrator 组成员身份运行且该账户不能是域账户Domain User。很多企业环境默认用域账号登录即使该账号在本地 Administrators 组中UAC 仍会阻止CreateRemoteThread。解决# 创建一个纯本地管理员账户非域账号 net user RDPAdmin Pssw0rd123 /add /expires:never net localgroup administrators RDPAdmin /add # 注销当前用户用 RDPAdmin 登录再运行安装 .\RDPWInst.exe -i4.2 现象安装成功但query session只显示一个会话第二个连接直接断开原因rdpwrap.ini版本严重过期。例如你的系统是 Windows 10 22H2NT 10.0.22621但 ini 文件只支持到 21H210.0.22000导致 Hook 地址错位WTSQuerySessionInformationW被 patch 到了无关函数上返回垃圾值。解决# 下载最新 ini以 v1.6.8 为例 curl -L -o rdpwrap.ini https://raw.githubusercontent.com/stascorp/rdpwrap/master/res/rdpwrap.ini # 替换必须停止 TermService 后再替换否则文件被占用 Stop-Service TermService -Force Copy-Item rdpwrap.ini C:\RDPWrap\rdpwrap.ini -Force Start-Service TermService # 重新注入 .\RDPWInst.exe -r # -r 表示 reinstall会重新读取 ini 并 patch4.3 现象远程连接能建立但桌面一片黑鼠标可动键盘无响应原因杀毒软件尤其是 Windows Defender 实时防护将RDPWrap.dll识别为“潜在不受欢迎程序”PUA在注入后立即将其内存页标记为可疑并终止线程。解决# 临时禁用 Defender 实时防护仅用于安装 Set-MpPreference -DisableRealtimeMonitoring $true # 安装 RDPWrap .\RDPWInst.exe -i # 重新启用安全起见 Set-MpPreference -DisableRealtimeMonitoring $false # 将 RDPWrap 目录添加为排除项永久方案 Add-MpPreference -ExclusionPath C:\RDPWrap4.4 现象RDPWInst.exe -s显示Status: Installed, Not Running原因svchost.exe进程崩溃或被回收导致注入的RDPWrap.dll卸载。常见于系统刚打完补丁后未重启termsrv.dll被更新但RDPWrap.dll未重新注入。解决# 强制重启 TermService会踢掉所有 RDP 会话请提前通知用户 Restart-Service TermService -Force # 等待 10 秒再重新注入 Start-Sleep -Seconds 10 .\RDPWInst.exe -r4.5 现象Windows 更新后RDPWrap 突然失效query session只有一个会话原因Windows 累积更新如 KB5034441会覆盖termsrv.dll而RDPWrap.dll的 patch 是写在内存里的服务重启后新termsrv.dll未被重新 patch。解决# 创建一个计划任务在每次系统启动后自动重装 $action New-ScheduledTaskAction -Execute C:\RDPWrap\RDPWInst.exe -Argument -r $trigger New-ScheduledTaskTrigger -AtStartup $principal New-ScheduledTaskPrincipal -UserId NT AUTHORITY\SYSTEM $settings New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable $task New-ScheduledTask -Action $action -Trigger $trigger -Principal $principal -Settings $settings Register-ScheduledTask RDPWrap AutoReinstall -TaskPath \ -TaskName RDPWrap AutoReinstall -InputObject $task5. 进阶技巧自定义会话数限制、日志调试与生产环境加固RDPWrap 默认行为是“无限会话”但这在生产环境中既不安全也不可控。更成熟的用法是把它当作一个可编程的会话网关——通过修改rdpwrap.ini和配合 Windows 自身策略实现细粒度管控。下面分享三个我已在某跨平台系统运维中落地的技巧。5.1 限制最大并发会话数从“无限”到“可控”RDPWrap 本身不提供会话数上限但你可以利用rdpwrap.ini的PatchTable机制让WTSQuerySessionInformationW返回一个动态值。例如你想限制最多 3 个并发 RDP 会话不含控制台可以这样改打开rdpwrap.ini找到你系统对应的[Version]节如[10.0.19045.0]在该节末尾添加一行MaxSessions3修改RDPWrap.dll的源码如果你有编译环境在MyWTSQuerySessionInformationW函数中加入逻辑if (infoClass WTSSessionInfo pBuffer ! NULL) { // 读取 MaxSessions 配置 DWORD maxSess GetIniDWORD(MaxSessions, 0); if (maxSess 0) { // 返回 maxSess - 1确保第 maxSess 个连接被拒绝 ((WTS_SESSION_INFOA*)pBuffer)-State WTSActive; return TRUE; } }注意此修改需重新编译RDPWrap.dll。若无编译条件可用 Windows 组策略替代计算机配置 → 管理模板 → Windows 组件 → 远程桌面服务 → 远程桌面会话主机 → 连接 → 设置“限制连接数量”为 3。两者叠加效果更稳。5.2 启用详细日志定位 Hook 失败的每一帧RDPWrap 默认日志极简但它的源码预留了DEBUG_LOG宏。启用方法如下下载 RDPWrap 源码https://github.com/stascorp/rdpwrap用 Visual Studio 打开RDPWrap.sln在Project Properties → C/C → Preprocessor → Preprocessor Definitions中添加DEBUG_LOG编译生成新的RDPWrap.dll替换原 DLL并在C:\RDPWrap下创建空文件rdpwrap.log重启TermService所有 Hook 过程地址、签名比对结果、patch 写入状态将输出到该日志。日志片段示例[2024-06-15 10:23:41] INFO: Found termsrv.dll at 0x7FFB2A100000 [2024-06-15 10:23:41] DEBUG: Signature match for WTSQuerySessionInformationW: YES [2024-06-15 10:23:41] DEBUG: Writing patch to 0x7FFB2A1A5F20: 8B C8 C3 [2024-06-15 10:23:41] INFO: Hook installed successfully有了这个日志你再也不用靠猜来判断是签名不匹配还是内存写入失败。5.3 生产环境加固防篡改、防卸载、防误操作在某公司测试环境中我们曾遭遇过因误删rdpwrap.ini导致全部 RDP 连接中断的事故。为此我们制定了三层加固策略层级措施命令/操作文件层rdpwrap.ini设为只读系统隐藏attrib r s C:\RDPWrap\rdpwrap.ini进程层监控RDPWrap.dll是否在svchost中每 5 分钟执行Get-Process -Id $pid -Module | Where-Object {$_.ModuleName -eq RDPWrap.dll}失败则告警并自动重装策略层禁用普通用户对RDPWInst.exe的执行权icacls C:\RDPWrap\RDPWInst.exe /deny Users:(X)最后也是最重要的一条习惯从那以后我每次给新机器部署 RDPWrap都强制走一遍RDPWInst.exe -squery session双验证并把输出截图存档。不是信不过工具而是信不过人——信不过那个可能忘记以管理员运行的自己信不过那个可能手抖删错文件的同事。希望帮到你。本文还有配套的精品资源点击获取