Termsrv Patch Locator 是一个面向逆向分析与配置维护的 IDAPython 插件。它读取已加载 PDB 符号的 termsrv.dll,识别 RDP Wrapper 所需的补丁点,并生成可用于 rdpwrap.ini 的版本配置。
匹配逻辑参考 llccd/RDPWrapOffsetFinder 的 x86/x64 实现,并被拆分为可独立测试的纯 Python 核心。
Important
本工具不会修改 termsrv.dll,只负责分析偏移并生成 INI 配置。生成结果应在目标系统和对应 DLL 版本上验证后再使用。
- 自动识别目标:读取 DLL 文件版本并判断 x86、x64 或 ARM64 架构。
- 定位核心补丁:支持 SingleUser、DefPolicy、LocalOnly、SLPolicy 和 SLInit。
- 生成 RDP Wrapper 配置:输出补丁 RVA、补丁代码名称及 SLInit 变量地址。
- 兼容多种指令布局:处理 DefPolicy 寄存器切换以及 LocalOnly 的
js/jns控制流。 - 基于函数边界扫描:避免无界解码造成跨函数误匹配。
- 核心逻辑可测试:无需启动 IDA 即可运行指令匹配回归测试。
- 跨 IDA API 版本:兼容 IDA Pro 7.x、8.x 和 9.x 的相关 IDAPython 接口。
- IDA Pro 7.0–9.x
- IDA 内置的 Python 3 环境
- 目标系统的
termsrv.dll - 与 DLL 完全匹配的 PDB 符号
- Windows x86、x64 或 ARM64 目标文件
下载或克隆仓库:
git clone https://github.com/bobotechnology/termsrv_patch_locator.git
cd termsrv_patch_locator将主插件文件和辅助模块目录复制到 IDA 的 plugins 目录:
plugins/
├─ termsrv_patch_locator.py
└─ termsrv_patch_locator/
├─ __init__.py
├─ core.py
└─ output.py
不要把
core.py或output.py单独放在plugins根目录;IDA 会把根目录中的每个.py文件当作独立插件并尝试调用PLUGIN_ENTRY()。
常见插件目录示例:
C:\Program Files\IDA Professional 9.0\plugins\
%APPDATA%\Hex-Rays\IDA Pro\plugins\
重新启动 IDA Pro 后,插件会以 Termsrv RDP Patch Locator 显示。
- 在 IDA Pro 中打开目标
termsrv.dll。 - 等待自动分析完成。
- 确认 PDB 符号已加载,且能够看到类似
CDefPolicy::Query的函数名。 - 按
Ctrl+Alt+R,或从插件菜单运行 Termsrv RDP Patch Locator。 - 在输出窗口检查定位结果。
- 选择保存目录,插件将写出自动生成的 INI 文件。
输出文件名格式:
<版本>-autogenerated_<架构>.ini
例如:
10.0.26100.3912-autogenerated_x64.ini
[10.0.26100.3912]
SingleUserPatch.x64=1
SingleUserOffset.x64=1A2B3
SingleUserCode.x64=nop_4
DefPolicyPatch.x64=1
DefPolicyOffset.x64=2B3C4
DefPolicyCode.x64=CDefPolicy_Query_r9d_rdi_jmp
LocalOnlyPatch.x64=1
LocalOnlyOffset.x64=3C4D5
LocalOnlyCode.x64=jmpshort
SLInitHook.x64=1
SLInitOffset.x64=4D5E6
SLInitFunc.x64=New_CSLQuery_Initialize所有地址均为相对于映像基址的 RVA。若模式或符号未找到,输出中会保留明确的 ERROR: 行,便于定位失败环节。
| 补丁 | 目标函数或数据 | 适用范围 |
|---|---|---|
| SingleUser | CSessionArbitrationHelper::IsSingleSessionPerUserEnabled / CUtils::IsSingleSessionPerUser |
x86、x64 |
| DefPolicy | CDefPolicy::Query |
x86、x64 |
| LocalOnly | CEnforcementCore::GetInstanceOfTSLicense + LocalOnly 查询函数 |
Windows 8.1+ |
| SLPolicy | SLGetWindowsInformationDWORDWrapper |
Windows 8 / 6.2 |
| SLInit | CSLQuery::Initialize 及相关全局变量 |
Windows 8.1+ |
DefPolicy 当前支持直接比较以及 0x63C/0x638 寄存器对模式,可生成诸如:
CDefPolicy_Query_eax_rdi
CDefPolicy_Query_eax_rcx_jmp
CDefPolicy_Query_r9d_rdi_jmpIDA 数据库
│
├─ 读取 termsrv.dll 版本和架构
├─ 通过 PDB 符号定位目标函数与变量
├─ 将 IDA 指令转换为独立的指令模型
├─ 在限定的函数范围内运行补丁匹配器
└─ 汇总 RVA 和代码名称,生成 INI
项目分为两个主要模块:
| 文件 | 职责 |
|---|---|
termsrv_patch_locator.py |
IDA 插件入口、符号查找、指令适配、版本读取和 INI 输出 |
termsrv_patch_locator/core.py |
与 IDA 解耦的指令模型,以及各类补丁匹配器 |
termsrv_patch_locator/output.py |
版本段字段顺序和 SLInit 对齐格式 |
这种结构使匹配逻辑可以在普通 Python 环境中回归测试,同时保留 IDA 负责反汇编和符号解析的优势。
| 项目 | 状态 |
|---|---|
| IDA Pro 7.x | 支持 |
| IDA Pro 8.x | 支持 |
| IDA Pro 9.x | 支持 |
x86 termsrv.dll |
支持 |
x64 termsrv.dll |
支持 |
ARM64 termsrv.dll |
实验性支持 |
ARM32 termsrv.dll |
暂不支持 |
| 无 PDB 分析 | 暂不支持 |
| 自动修改 DLL | 不提供 |
ARM64 的 SingleUser、DefPolicy 和 LocalOnly 匹配参考 RDPWrapOffsetFinder/PatchARM64.cpp,当前标记为实验性。SLInit 地址仍依赖 PDB 符号。ARM32 和无符号扫描尚未实现。
运行全部回归测试:
python -m unittest discover -s tests -v运行语法检查:
python -m py_compile termsrv_patch_locator.py termsrv_patch_locator/core.py termsrv_patch_locator/output.py tests/test_patch_core.py tests/test_patch_output.py测试覆盖当前核心匹配路径,包括:
- x64
VerifyVersionInfoWSingleUser 模式 - x86 SingleUser
cmp回退模式 - DefPolicy 直接比较模式
- DefPolicy
0x63C/0x638寄存器对模式 - LocalOnly
js与jns两种控制流 - Windows 8 SLPolicy CP 模式
确认 termsrv_patch_locator.py 与 termsrv_patch_locator/ 子目录均位于 IDA 插件目录中。检查 IDA 输出窗口中的导入错误。若根目录仍残留旧版 termsrv_patch_core.py 或 termsrv_patch_output.py,请删除它们;IDA 会把这些文件误当成独立插件。
通常表示 PDB 未加载、符号与 DLL 版本不匹配,或 IDA 尚未完成分析。请先确认目标文件版本,再重新加载对应符号。
在 Names 或 Functions 窗口搜索该名称。如果完全不存在,当前 PDB 可能不匹配,或者该版本使用了尚未支持的符号/代码布局。
插件会保留未找到项目的错误信息,而不是静默生成看似完整的配置。不要直接部署包含关键定位错误的配置;请附上 DLL 版本、架构、IDA 版本和输出日志提交 Issue。
编辑 termsrv_patch_locator.py:
DEBUG_MODE = True重新加载插件后再次运行,即可在 IDA 输出窗口看到更详细的信息。
欢迎提交 Issue 和 Pull Request,尤其是以下内容:
- 新版 Windows
termsrv.dll的匹配兼容性 - x86/x64 指令布局回归样本
- ARM64 支持
- 不依赖 PDB 的定位方案
- IDA 版本兼容性修复
提交问题时建议附上:
termsrv.dll完整版本号- 架构(x86/x64)
- IDA Pro 版本
- 插件完整输出
- 可公开的反汇编片段或符号信息
请勿提交微软专有 DLL 或其他无权公开分发的文件。
- llccd/RDPWrapOffsetFinder — 核心偏移匹配逻辑参考
- stascorp/rdpwrap — RDP Wrapper 原始项目
- Hex-Rays IDAPython — IDA Python API
本项目基于 MIT License 开源。
本项目仅用于安全研究、兼容性分析和学习。你需要遵守所在地法律、软件许可条款及组织安全策略,并自行承担使用生成配置或后续修改系统文件产生的风险。项目作者不对数据丢失、系统故障、服务中断或其他损失承担责任。