Gawasna/mslc-extractor

GitHub: Gawasna/mslc-extractor

一个原生 Windows 注入工具,通过挂钩 Azure Speech SDK 从 Windows 实时字幕引擎提取并显示语音识别文本。

Stars: 0 | Forks: 0

# 实时字幕提取器 (MSLC Extractor) **项目概述** - **描述**:原生 Windows 注入器 + Hook 工具,通过 Hook Azure Speech SDK 核心 API 从 Microsoft Live Captions 引擎提取实时字幕文本,并在分屏控制台 UI 中显示实时字幕。 - **组件**: - **Loader**(注入器 + 带有 Named Pipe 服务器的分屏控制台 UI) - **HookCore**(用于 Hook Azure Speech SDK 结果 API 的 DLL) ## 工作原理 ### 注入过程 - **Loader** 定位 `LiveCaptions.exe`(如果未运行,则打开 Live Captions 设置) - 为 `HookCore.dll` 设置 DACL 权限以兼容 AppContainer 沙盒 - 通过 `CreateRemoteThread` + `LoadLibraryW` 将 `HookCore.dll` 注入目标进程 - 启动带有 NULL DACL 的 Named Pipe 服务器(`\\.\pipe\LiveCaptionPipe`)用于 IPC ### Hook 机制 - **HookCore** 使用 `EnumProcessModules` 主动扫描 `microsoft.cognitiveservices.speech.core.dll` - 从 Azure Speech SDK 中定位两个导出函数: - `result_get_text` - 检索已识别的文本缓冲区 - `result_get_reason` - 查询识别状态(部分或最终) - 在 `result_get_text` 上安装 MinHook 挂钩以拦截所有字幕文本 - 实现模块检测重试机制(以 1 秒间隔尝试 20 次) ### 数据流 1. **捕获**:Detour 拦截带有已识别文本缓冲区(`char*`)的 `result_get_text` 调用 2. **状态检测**:查询 `result_get_reason` 以确定结果是部分的(`ResultReason_RecognizingSpeech`)还是最终的(`ResultReason_RecognizedSpeech`) 3. **日志记录**:捕获的文本会带有 ISO 8601 时间戳写入 `C:\Users\Public\live_caption_debug.txt` 4. **管道通信**:JSON payload 通过持久 Named Pipe 连接发送给 Loader - 格式:`{"text":"...","is_final":true/false,"bytes":N,"ts_ms":T}` - 持久连接(不按数据包重新连接)以保留 splitter 状态 5. **控制台显示**:Loader 在分屏 UI 中呈现字幕: - **左面板**:带有 `[~]`(部分)和 `[F]`(最终)标签的实时流 - **中面板**:通过 delta watermark splitter 提取的已确认句子 - **右面板**:实时统计信息(数据包数、字节数、延迟、时间戳) ### 关键实现细节 **HookCore (DLL)**: - **Hook 目标**:`result_get_text` 函数(stdcall 调用约定) - **函数签名**:`int __stdcall result_get_text(SPXRESULTHANDLE hresult, char* buffer, uint32_t bufferLen)` - **模块发现**:通过 `FindModuleByPartialName()` 进行动态扫描,而不是被动的 `GetModuleHandle()` - **文本格式**:来自核心 API 的窄字符串(`char*`),而非来自 UI 层的宽字符串 - **管道策略**:持久连接,在写入失败时延迟重连(防止 splitter 重置) - **线程安全**:`CRITICAL_SECTION` 保护管道句柄免受并发 hook 调用的影响 **Loader(控制台 UI)**: - **分屏布局**:3 列设计,使用制表符(Unicode U+2502, U+2500, U+253C) - **句子分割器**:Delta watermark 算法,防止句子重复 - 跟踪 `confirmed_len`(已提交到 Confirmed 面板的字符数) - 仅扫描新后缀 `[confirmed_len .. end]` 以查找句子边界(`.?!`) - 处理快速语音(多句子批次)而不产生重复 - 在检测到 FINAL 或回归时重置 watermark - **日志记录**:滚动窗口(最多 100 行)写入 `C:\Users\Public\loader_debug.txt` - **延迟跟踪**:通过 `GetTickCount64()` 差值测量管道延迟(HookCore 捕获 → Loader 接收) ## 安全与隐私 ⚠️ **重要安全提示**: - 本项目在 Live Captions 运行时 Hook 其 RAM 并从中提取文本 - **Windows Defender 和杀毒软件会将其检测为恶意软件/PUP** - 您**必须将**项目文件夹或构建的二进制文件加入白名单,以避免误报 - 为了兼容 AppContainer,代码在注入前为 DLL 设置了 DACL 权限(读取/执行) **信任与验证**: - 如果您不信任此发行版,请**从源代码构建**或验证 `SHA256SUMS.txt` 中的 SHA256 校验和 - 验证命令: ``` CertUtil -hashfile .\x64\Release\Loader.exe SHA256 CertUtil -hashfile .\x64\Release\HookCore.dll SHA256 ``` ## 构建说明 ### 前置条件 - Visual Studio 2022(或更高版本)及 C++ 桌面开发工作负载 - MinHook 库(包含在项目中) - 目标:x64 架构 ### 步骤 1. **打开解决方案**:在 Visual Studio 中打开 `Native.sln` 2. **配置 MinHook**(如果需要): - 在某些 VS 2022 环境中,需手动将库名从 `libMinHook-x86-v141-mt.lib` 修改为 `libMinHook.lib` - 确保在项目属性中正确设置了 MinHook 的 include/lib 路径 3. **构建配置**: - 将平台设置为 `x64` - 将配置设置为 `Release` - 构建 `Loader` 和 `HookCore` 项目 4. **输出**:构建的二进制文件将出现在 `x64\Release\` 中 ## 用法 ### 前置条件 - 启用了 Live Captions 功能的 Windows 11 - 建议具有管理员权限(用于注入) ### 运行 Extractor 1. **导航至 Release 文件夹**: ``` cd .\x64\Release\ ``` 2. **运行 Loader**: ``` .\Loader.exe ``` 3. **预期行为**: - 如果 `LiveCaptions.exe` 未运行,Loader 将打开 Live Captions 设置并等待 - 一旦检测到,HookCore.dll 将被注入 - 控制台将显示分屏 UI: ┌─────────────────────────────────────────────┬─────────────────────────────────────────────┬──────────────────────────┐ │ LIVE STREAM │ CONFIRMED SENTENCES │ STATS │ ├─────────────────────────────────────────────┼─────────────────────────────────────────────┼──────────────────────────┤ │ [~] text being recognized... │ 1. This is a complete sentence. │ Pkts : 42 │ │ [F] completed sentence here. │ 2. Another confirmed sentence. │ Bytes : 1024 │ │ │ │ Avg : 24 B │ │ │ │ Delay : 15 ms │ │ │ │ Last : 12:34:56 │ └─────────────────────────────────────────────┴─────────────────────────────────────────────┴──────────────────────────┘ - 调试日志: - HookCore:`C:\Users\Public\live_caption_debug.txt`(ISO 8601 时间戳) - Loader:`C:\Users\Public\loader_debug.txt`(100 行滚动窗口) ### 故障排除 **注入失败**: - 以管理员身份运行 `Loader.exe` - 确保 Loader 和目标进程均为 x64(而非 x86) - 检查 Windows Defender 排除项 **未捕获到字幕**: - 检查 `live_caption_debug.txt` 中的诊断信息 - 检查 Live Captions 是否正在积极转录音频 - 确保正在加载正确的 DLL(检查日志中的 "Core DLL handle found") - 验证 `result_get_text` 和 `result_get_reason` 导出是否已成功解析 **未找到模块**: - DLL 扫描将以 1 秒间隔运行 20 次 - 如果仍然失败,Windows 可能已更新核心 DLL 的名称/结构 - 检查日志中的 "Could not find Core DLL handle after all retries" **句子重复**: - 检查 `loader_debug.txt` 中 splitter watermark 的进度 - 验证 splitter 是否未在语音中途重置(查找 "REGRESSION detected") - 确保管道连接是持久的(HookCore 日志中没有 "Pipe write failed" 错误) ## 方法论依据 ### HookCore 配置 **常量**(文件顶部): - `LOG_PATH`:HookCore 调试日志位置(默认:`C:\Users\Public\live_caption_debug.txt`) - `PIPE_NAME`:Named Pipe 端点(默认:`\\.\pipe\LiveCaptionPipe`) - `MODULE_SCAN_RETRIES`:查找核心 DLL 的最大尝试次数(默认:20) - `MODULE_SCAN_INTERVAL`:扫描之间的延迟,以毫秒为单位(默认:1000) **目标 DLL**:`microsoft.cognitiveservices.speech.core.dll` - 如果 Microsoft 更改了 DLL 名称,请在 `FindModuleByPartialName()` 调用中进行修改 **目标函数**: - `result_get_text` - 被 Hook 以拦截文本缓冲区 - `result_get_reason` - 被调用(未 Hook)以查询识别状态 - 如果 API 签名发生更改,请更新 `GetProcAddress()` 调用 ### Loader 配置 **面板布局**(文件顶部): - `COL_LIVE_W`:实时流面板宽度,以字符为单位(默认:46) - `COL_CONFIRM_W`:已确认句子面板宽度(默认:46) - `COL_STATS_W`:统计面板宽度(默认:26) - `CONSOLE_H`:控制台高度,以行为单位(默认:40) **句子分割器**: - `BOUNDARIES`:用于句子分割的标点字符(默认:`.?!`) - 如果您想包含/排除标点符号,请在 `SentenceSplitter::BOUNDARIES` 中修改 ## 架构演变 ### v1:UI 层 Hooking(已弃用) - 从运行时 DLL 中 Hook `GetUnimicDecoderNBestDisplayText` - 从内存偏移(`TEXT_OFFSET 0x190`)提取文本 - 宽字符串(`wchar_t*`)处理 - 脆弱:在 Windows 更新时失效 ### v2:核心 API Hooking(当前) - 从 Azure Speech SDK 核心 DLL 中 Hook `result_get_text` - 查询 `result_get_reason` 以检测识别状态 - 带有标准函数签名的直接 API 拦截 - 窄字符串(`char*`)处理 - 持久 Named Pipe 连接以保留 splitter 状态 - Delta watermark 句子分割器以防止重复 **关键改进**: - 更早地访问已识别的文本(在 UI 渲染之前) - 通过 SDK API(而非标点符号启发式方法)进行可靠的 partial/final 检测 - 更好地兼容 Windows 更新 - 带有实时统计信息的分屏控制台 UI - 针对快速语音(多句子批次)的智能句子分割 - 延迟跟踪(捕获 → 显示管道) ## 许可证 本项目基于 MIT 许可证授权 - 有关详细信息,请参阅 [LICENSE](LICENSE) 文件。 ## 免责声明 此工具旨在通过提取 Live Captions 输出来增强可访问性。用户有责任遵守有关录音和转录的当地法律。
标签:API Hook, API接口, Azure语音识别SDK, C++, DACL权限, DLL注入, LiveCaptions, MinHook, Windows API, Windows开发, 云资产清单, 命名管道, 实时字幕提取, 实时语音转文字, 屏幕文本捕获, 屏幕阅读器, 数据擦除, 无障碍辅助, 流量审计, 端点可见性, 系统安全研究, 系统底层开发, 绕过沙箱, 进程间通信, 逆向工程