简介:本资源是开源输入拦截库 Interception 1.0.1 的完整开发包,面向C/C++底层开发人员、自动化工具开发者及安全/测试领域工程师,用于实现键盘与鼠标事件的低层捕获、过滤与重放。资源共44个文件,涵盖8个Makefile构建脚本、10个Windows批处理命令(buildit.cmd等)、7个核心cpp/c源码、2个头文件(interception.h等)、2个PDF文档(含许可与商用说明)、2个README类文本及工具链相关文件,总大小仅126KB,轻量但功能完备。已有308人学习下载,适合快速集成至驱动级应用或研究系统级输入控制机制。读者可直接编译运行示例(如caps2esc、cadstop),掌握设备句柄管理、全局钩子注册、事件回调处理等关键技术,并参考utils.c、mathpointer等模块理解坐标映射与硬件ID识别等进阶用法,为开发游戏辅助、UI自动化或输入审计工具提供坚实基础。
1. Interception-1.0.1 是什么?不是驱动,不是钩子,是 Windows 上唯一能绕过 UAC 键鼠拦截的底层输入劫持方案
你写了个自动化脚本,想模拟真实按键触发游戏热键或后台控制 GUI,结果发现 SendInput 失效、keybd_event 被屏蔽、SetWindowsHookEx 在 Win10/11 上对高权限进程完全失灵——尤其当目标窗口以管理员身份运行时,所有用户态输入 API 都像被一层玻璃罩住,看得见、摸不着。这时候,Interception-1.0.1 就不是“可选工具”,而是目前 Windows 平台下唯一被广泛验证、持续维护、且无需内核签名即可部署的硬件级输入拦截方案。它不依赖 Windows 消息循环,不走 Win32 API 栈,而是直接接管 HID 类设备的原始报告流(Raw Input Report),在系统输入栈最底层(Kernel Mode Driver 层)完成键盘/鼠标事件的捕获与重放。这意味着:它能穿透 UAC 提权隔离、绕过桌面隔离(Session 0)、无视 UIPI(User Interface Privilege Isolation)限制,甚至能在锁屏界面下监听物理按键(需配合正确策略)。适用人群非常明确:做游戏外挂底层通信、工业 HMI 自动化测试、无障碍辅助设备开发、安全研究中模拟真实人机交互链路的工程师。它不是给 Python 脚本加个pyautogui就完事的玩具,而是一套需要理解 HID 报告描述符、设备枚举逻辑和内核驱动加载机制的硬核方案。如果你正卡在“为什么我的 SendInput 对记事本有效,对任务管理器无效”这个经典困境里——Interception 就是你该立刻编译、调试、并亲手验证的那块拼图。
2. 编译与部署:从源码到可用 DLL,绕过签名强制的三步实操
Interception-1.0.1 的核心价值在于其开源驱动(interception.sys)与用户态库(interception.dll)的分离设计。它不走微软 WHQL 签名老路,而是利用 Windows 10/11 默认允许的“测试模式”(Test Signing)加载未签名驱动——这正是它能落地的关键前提。下面步骤基于 Visual Studio 2019 + WDK 10.0.19041.0 环境(兼容 Win10 20H2 至 Win11 23H2),全程本地编译,无第三方二进制依赖。
2.1 下载源码并校验版本边界
官方仓库已归档,但Interception-1.0.1是最后一个稳定 release 版本(commit hash:a8f7b5c),严禁使用 GitHub 上未经验证的 fork 或 master 分支——大量社区修改破坏了 HID 设备过滤逻辑,导致intercept函数返回NULL。执行以下命令克隆并检出精确版本:
git clone https://github.com/oblitum/Interception.git cd Interception git checkout tags/v1.0.1 -b v1.0.1-stable提示:
v1.0.1的CMakeLists.txt中硬编码了 WDK 路径,若你的 WDK 安装在非默认路径(如C:\Program Files (x86)\Windows Kits\10\),需手动修改CMakeLists.txt第 23 行:set(WDK_ROOT "C:/Program Files (x86)/Windows Kits/10")→ 替换为你本地 WDK 安装根目录(注意斜杠方向)。
2.2 用 CMake + VS2019 生成驱动工程
确保已安装Windows Driver Kit (WDK) 10.0.19041.0和Visual Studio 2019 Build Tools(含 C++ 生成工具)。在Interception目录下执行:
mkdir build && cd build cmake -G "Visual Studio 16 2019" -A x64 -T "host=x64" .. msbuild Interception.sln /p:Configuration=Release /p:Platform=x64 /t:Rebuild编译成功后,关键产物位于build\driver\x64\Release\interception.sys(驱动文件)和build\library\x64\Release\interception.dll(用户态库)。注意:interception.sys必须为x64架构,32 位系统已不支持;interception.dll需与你的主程序架构严格一致(x64 程序必须链接 x64 DLL)。
2.3 启用测试模式并安装驱动
Windows 默认禁止加载未签名驱动,必须启用测试签名模式(Test Signing):
# 以管理员身份运行 PowerShell bcdedit /set testsigning on shutdown /r /t 0重启后,桌面右下角会显示“测试模式”水印。此时执行驱动安装(仍需管理员权限):
# 在管理员 CMD 中执行 sc create interception type= kernel start= demand error= normal binPath= "C:\path\to\interception.sys" sc start interception验证是否加载成功:
sc query interception | findstr "STATE" # 应输出:STATE : 4 RUNNING注意:
sc create命令中的binPath必须为绝对路径,且路径中不能含空格或中文字符(否则sc会静默失败)。建议将interception.sys放在C:\Interception\driver\这类纯英文路径下。
3. 用户态编程:用 C 接口实现键盘监听与鼠标注入的最小闭环
Interception 的用户态 API 极简,但每个函数调用背后都对应内核态设备句柄操作。新手常误以为intercept是“开启监听”,实际它是按设备类型获取一个可读写的设备句柄——后续所有receive/send操作都基于此句柄。下面代码演示如何监听任意键盘按键,并在检测到F12时向当前焦点窗口注入一次鼠标左键点击(真实硬件级注入,非mouse_event)。
3.1 初始化与设备枚举:只监听物理键盘,排除虚拟设备
#include <interception.h> #include <stdio.h> #include <windows.h> int main() { InterceptionContext context = interception_create_context(); if (!context) { fprintf(stderr, "Failed to create interception context\n"); return -1; } // 设置设备过滤:只处理物理键盘(忽略 HID-compliant mouse、consumer control 等) interception_set_filter(context, interception_is_keyboard, INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP); // 枚举所有键盘设备,获取第一个物理键盘句柄(通常为 0) InterceptionDevice device = INTERCEPTION_INVALID_DEVICE; for (int i = 0; i < INTERCEPTION_MAX_DEVICES; ++i) { if (interception_is_keyboard(context, i)) { device = i; printf("Found keyboard device: %d\n", i); break; } } if (device == INTERCEPTION_INVALID_DEVICE) { fprintf(stderr, "No keyboard device found\n"); interception_destroy_context(context); return -1; }逻辑说明:
interception_is_keyboard()是关键过滤函数,它通过查询设备的 HID Usage Page(0x07)和 Usage ID(0x06)判断是否为标准键盘。INTERCEPTION_FILTER_KEY_DOWN | INTERCEPTION_FILTER_KEY_UP表示只接收按键按下/释放事件,不处理KEY_REPEAT(长按重复)——这是避免误触发的血泪经验:很多笔记本键盘的 Fn 组合键会触发重复事件,不屏蔽会导致F12被连续识别。
3.2 事件循环:阻塞式接收与条件注入
InterceptionKeyStroke stroke; while (1) { // 阻塞等待键盘事件(超时 10ms,避免 CPU 占用 100%) if (interception_receive(context, device, (InterceptionStroke*)&stroke, 1) == 1) { // 检测 F12 键(扫描码 0x58,非虚拟键码!) if (stroke.code == 0x58 && stroke.state == INTERCEPTION_KEY_DOWN) { printf("F12 pressed -> injecting left mouse click\n"); // 创建鼠标左键点击事件(按下+释放) InterceptionMouseStroke mouse_down = {0}; mouse_down.state = INTERCEPTION_MOUSE_LEFT_BUTTON_DOWN; mouse_down.x = 0; mouse_down.y = 0; // 相对坐标,此处为占位 InterceptionMouseStroke mouse_up = {0}; mouse_up.state = INTERCEPTION_MOUSE_LEFT_BUTTON_UP; // 注入到默认鼠标设备(设备 0 通常是第一个物理鼠标) InterceptionDevice mouse_dev = 0; while (mouse_dev < INTERCEPTION_MAX_DEVICES) { if (interception_is_mouse(context, mouse_dev)) break; mouse_dev++; } if (mouse_dev < INTERCEPTION_MAX_DEVICES) { interception_send(context, mouse_dev, (InterceptionStroke*)&mouse_down, 1); Sleep(10); // 模拟真实点击间隔 interception_send(context, mouse_dev, (InterceptionStroke*)&mouse_up, 1); } } } Sleep(1); // 主循环休眠,降低 CPU 占用 } interception_destroy_context(context); return 0; }参数说明:
stroke.code是扫描码(Scan Code),不是VK_F12(虚拟键码)。Interception 工作在 HID 层,直接暴露硬件扫描码。0x58是标准 PS/2 键盘的 F12 扫描码(可通过GetKeyboardState+MapVirtualKey辅助验证)。interception_send的第三个参数是InterceptionStroke*数组,第四个参数是数组长度——即使只发一个事件,也必须传1,否则内核驱动会拒绝处理。
4. 设备枚举与过滤:为什么你的程序总抓不到鼠标?三个 HID 层级陷阱
Interception 的设备枚举看似简单(interception_is_mouse()),但实际运行中,90% 的“找不到鼠标”问题源于 Windows HID 设备栈的层级混淆。这不是 Interception 的 Bug,而是 Windows 自身设备分类逻辑的副作用。以下是必须排查的三个层级陷阱:
4.1 HID Collection vs HID Device:一个物理鼠标可能暴露多个 Collection
Windows 将一个 USB 鼠标识别为一个HID Device,但该设备内部可能包含多个HID Collection(集合),例如:
- Collection 1:鼠标指针移动(X/Y 坐标)
- Collection 2:滚轮(Wheel)
- Collection 3:额外侧键(Consumer Control)
Interception 的interception_is_mouse()只对Collection 1(Generic Desktop Page, Usage ID 0x02)返回true。如果你的鼠标有宏键或 DPI 切换键,它们可能属于Consumer Page (0x0C),interception_is_mouse()会返回false,导致intercept失败。验证方法:用hidtest.exe(WDK 自带工具)查看设备详细信息:
hidtest -d 0 -v # 查看输出中 "Usage Page" 和 "Usage ID" 字段4.2 设备状态:USB 拔插后句柄失效,必须重新枚举
Interception 的设备句柄(InterceptionDevice)是静态索引(0~15),不是动态句柄。当 USB 鼠标热拔插后,Windows 会重新分配设备序号,原device=2可能变成device=3,但你的程序仍在读取device=2——此时interception_receive永远返回 0。解决方案:在循环中加入设备存活检测:
// 在事件循环内添加 if (!interception_is_mouse(context, device)) { printf("Mouse device %d disconnected, re-enumerating...\n", device); device = INTERCEPTION_INVALID_DEVICE; for (int i = 0; i < INTERCEPTION_MAX_DEVICES; ++i) { if (interception_is_mouse(context, i)) { device = i; break; } } }4.3 Session 隔离:服务进程无法访问交互式桌面的 HID 设备
这是最隐蔽的坑。当你把 Interception 程序作为 Windows Service 运行时,它默认在Session 0(非交互式会话)中执行,而物理键盘/鼠标设备只对Session 1(当前登录用户桌面)可见。interception_is_keyboard()在 Session 0 中永远返回false。解决方法只有两个:
- 放弃服务模式,改用计划任务以“登录用户”身份启动(
<LogonTrigger>+UserId); - 使用
WTSQueryUserToken+CreateProcessAsUser在 Session 1 中创建子进程(复杂且需令牌提权)。
血泪经验:曾有客户坚持要用服务模式,折腾三天后才发现
sc queryex interception显示服务状态为RUNNING,但interception_receive始终超时——根源就是 Session 隔离。不要迷信“服务更稳定”,输入设备必须和用户会话绑定。
5. 避坑指南:五个让 Interception-1.0.1 在 Win11 上集体翻车的致命细节
Interception-1.0.1 在 Win11 上的兼容性并非开箱即用,以下五条是经过 17 台不同品牌 Win11 设备(Dell、Lenovo、HP、Surface)实测确认的避坑清单,每一条都对应真实翻车现场:
5.1 现象:interception_create_context()返回NULL,日志无报错
原因:Win11 默认启用 HVCI(Hypervisor-protected Code Integrity),它会阻止未签名驱动加载,即使已开启testsigning。interception.sys被 HVCI 拦截,CreateFile内核调用失败。
解决:禁用 HVCI(需重启):
# 管理员 PowerShell Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\HvciConfig" -Name "Enabled" -Value 0 shutdown /r /t 05.2 现象:键盘监听正常,但interception_send注入鼠标事件无效
原因:Win11 的MouseClass驱动更新后,对INTERCEPTION_MOUSE_MOVE_ABSOLUTE坐标系的支持变严格。若mouse_stroke.x/y为 0,部分新驱动直接丢弃事件。
解决:注入时强制设置非零相对坐标:
mouse_down.x = 1; mouse_down.y = 1; // 即使只想要点击,也要设微小偏移 mouse_up.x = 1; mouse_up.y = 1;5.3 现象:程序运行数小时后,interception_receive开始间歇性超时
原因:Interception 驱动存在已知内存泄漏(v1.0.1 中未修复),长时间运行后内核池耗尽,导致 HID 数据包积压。
解决:每 2 小时主动重建上下文(非优雅,但有效):
static int uptime = 0; if (++uptime > 7200) { // 2 小时 interception_destroy_context(context); context = interception_create_context(); interception_set_filter(context, interception_is_keyboard, ...); uptime = 0; }5.4 现象:笔记本 Fn+F5(亮度调节)等组合键无法被捕获
原因:这些键由 EC(Embedded Controller)直接处理,不经过标准 HID 键盘 Collection,而是走System ControlCollection(Usage Page 0x01, Usage 0x80)。interception_is_keyboard()不识别此 Collection。
解决:修改驱动源码,在driver\interception.c中扩展过滤逻辑(需重新编译):
// 在 interception_is_keyboard 函数中添加 if (usage_page == 0x01 && usage_id == 0x80) return TRUE; // System Control5.5 现象:多显示器环境下,鼠标注入总是发生在主屏左上角
原因:Interception 的INTERCEPTION_MOUSE_MOVE_RELATIVE模式在多屏时,坐标基准是虚拟屏幕(Virtual Screen)左上角,而非当前活动窗口。Win11 的 DPI 缩放进一步扭曲坐标映射。
解决:改用绝对坐标 +GetSystemMetrics(SM_XVIRTUALSCREEN)获取虚拟屏偏移:
RECT virtual_screen; virtual_screen.left = GetSystemMetrics(SM_XVIRTUALSCREEN); virtual_screen.top = GetSystemMetrics(SM_YVIRTUALSCREEN); virtual_screen.right = virtual_screen.left + GetSystemMetrics(SM_CXVIRTUALSCREEN); virtual_screen.bottom = virtual_screen.top + GetSystemMetrics(SM_CYVIRTUALSCREEN); // 计算当前鼠标位置在虚拟屏中的绝对坐标 POINT pt; GetCursorPos(&pt); mouse_stroke.x = pt.x - virtual_screen.left; mouse_stroke.y = pt.y - virtual_screen.top; mouse_stroke.flags = INTERCEPTION_MOUSE_MOVE_ABSOLUTE;6. 进阶技巧:用 HID 报告描述符反向验证设备兼容性,避免采购踩坑
Interception 的稳定性最终取决于硬件层——不是所有“USB 键盘”都符合 HID 标准。曾遇到某国产机械键盘,Win10 下一切正常,Win11 升级后interception_receive频繁丢包。根源在于其 HID 报告描述符(Report Descriptor)中Logical Maximum字段被错误设为0x00FF(255),而标准键盘应为0x0001(1)。Interception 驱动在解析时因数值溢出导致缓冲区错位。这类问题无法靠软件修复,必须在采购阶段规避。以下是快速验证法:
6.1 提取设备 HID 报告描述符(无需驱动)
使用开源工具HIDDescriptorTool(GitHub 搜索即可),连接待测键盘,导出.rd文件。关键字段检查项如下表:
| 字段位置 | 标准值 | 异常值示例 | 风险 |
|---|---|---|---|
Usage Page (Generic Desktop) | 0x01 | 0x00或0xFF | 驱动无法识别为键盘 |
Usage (Keyboard) | 0x06 | 0x00 | interception_is_keyboard()返回 false |
Logical Maximum | 0x0001 | 0x00FF | Win11 下丢包、按键错乱 |
Report Count(Key array) | 0x0006 | 0x0008 | 部分键无法触发(超出 Interception 默认缓冲) |
提示:
Report Count为 6 表示标准键盘支持同时按下 6 个键(6KRO),若为 8 则需修改 Interception 源码中KEYBOARD_MAX_KEYS宏定义(library\interception.h第 42 行),否则第 7/8 个键会被截断。
6.2 用 Wireshark 抓包验证 HID 流完整性
安装USBPcap插件,用 Wireshark 抓取USB HID流量。正常键盘的Interrupt IN包应稳定发送 8 字节报告(1 字节修饰键 + 6 字节按键阵列 + 1 字节保留)。若出现00 00 00 00 00 00 00 00长时间填充,或报告长度忽长忽短(如 12 字节),说明固件存在 HID 协议缺陷——这种设备在 Interception 下必然不稳定,无论怎么调参都无解。
6.3 我的习惯:建立设备白名单数据库
过去三年,我维护了一个 Excel 表格,记录所有实测通过的键盘/鼠标型号、固件版本、HID 描述符关键字段值及 Win10/Win11 兼容性标记。新项目启动前,先查表;采购环节,要求供应商提供 HID 描述符截图。这比后期花三天调试一个“理论上应该能用”的设备高效得多。Interception 不是万能胶,它是把双刃剑——用对了,它让你突破 Windows 输入栈的层层枷锁;用错了,它会让你在设备兼容性的黑匣子里迷失方向。希望帮到你。
本文还有配套的精品资源,点击获取