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开发, 云资产清单, 命名管道, 实时字幕提取, 实时语音转文字, 屏幕文本捕获, 屏幕阅读器, 数据擦除, 无障碍辅助, 流量审计, 端点可见性, 系统安全研究, 系统底层开发, 绕过沙箱, 进程间通信, 逆向工程