akhil-dara/WAInsight

GitHub: akhil-dara/WAInsight

一款专为数字取证人员打造的 WhatsApp Android 数据库深度分析套件,提供类原生界面浏览全部聊天并涵盖媒体恢复、视觉搜索、设备归属、跨联系人分析及离线报告生成等 30 个取证功能页面。

Stars: 30 | Forks: 2

WAInsight logo # WAInsight - WhatsApp 取证分析套件 ### 用于已提取 WhatsApp Android 数据库的取证分析套件 它的功能,用一段话概括:将这些文件导入到一个标准化的、**只读的**案件数据库中,然后打开一个 30 页的桌面 UI,在这里每个对话都**可以像 WhatsApp 主屏幕那样完全浏览** —— 包含头像/未读/置顶/静音/已归档的聊天列表,点击任何聊天,滚动时间线(气泡、编辑、撤回、回复、回应、回执、转发标记),带有点击跳转的搜索、日历过滤、提及标签、置顶消息条,以及每个气泡上的取证信息侧边面板。在这个浏览界面之上,有 30 个取证页面:媒体画廊、感知视觉搜索、媒体恢复、幽灵/编辑/撤回浏览器、通话页面、位置、投票、链接、联系人和群组报告、离线导出包,以及文件夹形式的 Media Dashboard。 专为数字取证团队、执法人员和事件响应人员打造。**源 `msgstore.db` 在打开时会使用 `?mode=ro&immutable=1` 参数** —— WAInsight 绝不会向证据写入任何数据。 [![许可证: MIT](https://img.shields.io/badge/License-MIT-green.svg)](#许可证) [![Python 3.10+](https://img.shields.io/badge/Python-3.10+-blue.svg)](#技术栈) [![PySide6](https://img.shields.io/badge/Qt-PySide6-41cd52.svg)](#技术栈) [![状态: 活跃](https://img.shields.io/badge/status-active-brightgreen.svg)]() [![GitHub stars](https://img.shields.io/github/stars/akhil-dara/WAInsight?style=social)](https://github.com/akhil-dara/WAInsight/stargazers) [![GitHub forks](https://img.shields.io/github/forks/akhil-dara/WAInsight?style=social)](https://github.com/akhil-dara/WAInsight/network/members) [![访客](https://visitor-badge.laobi.icu/badge?page_id=akhil-dara.WAInsight&left_text=Visitors)](https://github.com/akhil-dara/WAInsight) ## 目录 - [WAInsight 的功能](#what-wainsight-does) - [截图](#screenshots-suggested-shots-to-add) - [快速开始](#quick-start) - [核心亮点](#highlights) - [页面](#pages) - [报告](#reports) - [离线 HTML 与仪表盘导出](#offline-html--dashboard-exports) - [系统架构](#architecture) - [取证完整性](#forensic-integrity) - [技术栈](#tech-stack) - [仓库结构](#repository-layout) - [路线图](#roadmap) - [许可证](#license) ## WAInsight 的功能 您只需将 WAInsight 指向包含**已提取** WhatsApp Android 文件的文件夹(该工具不会从手机中提取任何内容 —— 那是数据获取步骤,由分析人员使用其现有的工具单独完成)。具体来说,它需要: - `msgstore.db`(聊天、消息、媒体、通话、投票、提及等) - `wa.db`(保存的联系人、商业/认证状态、头像) - `Media/` 和 `Avatars/` 目录 ……它会通过 **29 个连续的阶段** 导入这些文件,将所有内容标准化为包含 **47 个索引表** 的单一 `analysis.db`,并呈现一个桌面 UI,分析人员可以在其中: - **像打开 WhatsApp 本身一样浏览每个聊天** —— 主屏幕风格的对话列表,点击任何聊天,滚动气泡时间线,内联查看编辑/撤回/回应/回复/回执/转发徽章 - 通过带有级联过滤器的文件夹形离线仪表盘对 **200k+ 媒体文件** 进行分类筛选 - 通过 CDN 重新下载或哈希链接恢复已从设备删除的媒体 - 查找共享相同 SHA-256 的每个聊天记录(跨聊天传播) - 运行感知哈希视觉搜索,在整个案例中查找相似图像 - 在联系人、群组、通话、链接、位置、投票、状态更新、日程事件之间进行数据透视 - 导出单一离线 HTML 压缩包,供案件专员直接交接(无需 Python,无需服务器,只需 `index.html`) - 按群组或按联系人生成横向 A4 PDF / HTML 取证报告 所有操作均在本地进行。没有遥测,没有网络请求,除了可选的 CDN 媒体重新下载外无需联网(且这需要分析人员明确点击)。 ## 截图 ### 主视觉图 ![WAInsight 聊天查看器](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/202a634662024559.png) *在 QWebEngine 中渲染的聊天查看器:气泡、编辑铅笔药丸、回复徽章、每条消息的取证 ℹ 按钮、发送者头像、状态勾选。* ### 开始使用 | | | |---|---| | ![案件选择器](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/0354014905024600.png) | ![仪表盘](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/e431b26797024602.png) | | **案件选择器** —— 发现现有的 `.wfacase` 包或导入新的提取数据。 | **仪表盘** —— 加载案件后立即显示全案件总计 + 活动热力图。 | | ![对话列表](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/d048b72317024603.png) | ![日历热力图过滤器](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/425b78af43024604.png) | | **对话列表** —— WhatsApp 风格,带有头像、未读徽章、置顶/静音/已归档标记、搜索。 | **日历热力图过滤器** —— 每天像机票价格网格一样显示消息数量;点击 + 拖拽进行过滤。 | ### 阅读聊天 | | | |---|---| | ![取证信息面板](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/92edb80b95024606.png) | ![编辑历史弹窗](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/d9810ea2e0024607.png) | | **取证信息面板** —— 每个气泡的 ℹ 按钮会打开此面板:msgstore 源 ID、原始标志、SQL 来源、原始 JID。 | **编辑历史弹窗** —— 并排显示编辑消息的每个修订版本,预编辑文本完全可见。 | | ![回复侧边栏](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/4da7eb7aaa024608.png) | ![回执详情](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/9555b0621b024609.png) | | **回复侧边栏** —— 点击回复链徽章 → 查看该消息的所有回复 + “跳至原消息”按钮。 | **回执详情** —— 点击任意勾选 → 查看按接收者划分的已送达/已读/已播放时间线及毫秒级延迟。 | | ![图像右键菜单](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/beb29284b9024610.png) | ![查找副本弹窗](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/c13ad0a66c024612.png) | | **媒体气泡上的右键上下文菜单** —— 查找副本 (精确 SHA-256)、查找相似图像 (感知)、复制 ID / 文件路径 / 密钥、打开文件位置。 | **查找副本弹窗** —— 曾经共享过相同 SHA-256 的每个聊天,带有可直接跳转到确切消息的“跳至聊天”按钮。 | | ![一次性下载](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/8a61842990024613.png) | | | **一次性恢复** —— 标记为“一次性”的语音消息/图像,即使在设备端文件过期后,仍可从气泡直接下载(使用来自 msgstore 的 CDN URL + media_key)。 | | ### 浏览与搜索 | | | |---|---| | ![媒体画廊级联过滤](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/224668b329024614.png) | ![媒体恢复仪表盘](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/34933bd0ac024616.png) | | **媒体画廊** —— 快速缩略图网格上的级联过滤器 (发送者 × 对话 × 日期 × 类型 × 状态)。 | **媒体恢复** —— 按对话划分的磁盘上/可下载/已过期/缺失无密钥 媒体明细,支持一键批量重新下载。 | | ![图像相似度页面](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/072f45ad00024617.png) | ![图像相似度结果](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/cda16c906f024618.png) | | **图像相似度** —— 拖放屏幕截图、浏览或从剪贴板粘贴;选择精确 (SHA-256) 或视觉 匹配模式。 | **匹配结果** —— 整个案例中的精确/近乎精确/近似重复/模板匹配层级(此处索引了 89 651 张图像)。 | | ![通话页面](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/71913e36c0024619.png) | ![位置页面](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/243903c5fc024621.png) | | **通话页面** —— 带有类型/方向/结果过滤器的通话记录;日历弹窗显示每日通话次数徽章。 | **位置** —— 每次静态 + 实时位置共享,包含起始/最终坐标和实时共享持续时间。 | | ![投票页面](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/e1ce9e4ee0024622.png) | | | **投票** —— 包含选项 + 投票统计的每个投票;点击行查看按选项划分的明细图表。 | | ### 群组与联系人情报 | | | |---|---| | ![群组信息 - 所有者横幅](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/a1d7a30b3f024623.png) | ![群组成员 + 前成员](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/3c5a9de639024625.png) | | **群组信息 —— 设备所有者横幅** —— 清楚地说明案件所有者在此群组中是管理员/成员/已被移除,以及解码后的 `chat.participation_status` 来源。 | **群组成员 + 前成员** —— 带有角色/消息/媒体计数的当前名单;前成员部分数据来源于 `group_past_participant`、`group_member.is_current=0` 以及仅消息推断。 | | ![群组编辑历史](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/cbd1441570024626.png) | | | **群组编辑历史** —— 带有差异视图的每个名称/DP/描述/设置更改,可按类型排序。 | | | ![设备历史](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/a24c17e084024627.png) | ![联系人报告](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/5934df4cb6024628.png) | | **每个联系人的设备会话** —— 该联系人使用过的每台设备(主要 Android、iPhone、此处的 14 个 Web/桌面伴侣设备)、首次/最后一次出现、消息分布、置信度得分。 | **联系人活动报告** (HTML) —— 完整的取证身份 + 按群组划分的活动 + 一对一时间线 + 回应 + 共同群组。 | ### 报告 | | | |---|---| | ![群组报告对话框](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/bcbbce18fd024629.png) | ![主要贡献者片段](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/ab2805d17b024631.png) | | **群组报告对话框** —— 选择输出格式 (HTML / PDF),限制为特定日期范围,精确勾选要包含的部分。 | **主要贡献者片段** —— 生成的报告中的示例部分:带有每个贡献者完整 JID 的排名条形图,具有所有者感知功能。 | ### 标记消息打包导出 | | | |---|---| | ![标记导出对话框](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/d42f910572024632.png) | ![标记导出查看器](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/2bb416e992024633.png) | | **标记导出对话框** —— 三种模式:完整对话/仅标记/标记 ± N 天缓冲。打包离线 HTML 查看器 + (可选) 实际媒体文件;输出为单个 ZIP。 | **标记导出查看器 (浏览器)** —— 在 Chrome 中离线打开导出的 `index.html`:聊天列表 + 标记的对话;压缩标记显示了标记消息之间隐藏的消息数量。 | ## 快速开始 ``` # 1. 克隆 + 安装依赖 (需要 Python 3.10+) git clone https://github.com//WAInsight.git cd WAInsight python -m pip install -r requirements.txt # 2. 启动 GUI python wainsight.py ``` 首次运行时,启动屏幕会要求您**创建新案件**(指向包含 `msgstore.db` 及其相关文件的文件夹 —— 导入器将运行所有 29 个阶段并显示进度事件),或者如果已经存在,则**打开现有的 `.wfacase` 包**。 ### 系统要求 - **操作系统:** 已在 Windows 11 上测试 - **Python:** 3.10 或更高版本 - **内存:** 最低 8 GB,对于超过 100 万条消息的案件建议 16 GB - **磁盘:** 大约为源 `Media/` 文件夹大小的 2 倍(用于只读镜像 + 缩略图 + 索引) - **可选:** 位于 `PATH` 中的 `ffmpeg` 用于 Media Dashboard 中的视频缩略图,`pymupdf`(`pip install pymupdf`)用于 PDF 首页缩略图 ## 核心亮点 **设计上保证只读。** 源 `msgstore.db` 在挂载时使用了 SQLite 的 `?mode=ro&immutable=1` 标志,案件文件夹是唯一的可写入区域,并且每个操作都记录到 `chain_of_custody.jsonl` 中,包含时间戳 + 源哈希值。 **29 阶段导入管道。** 消息 → 媒体 → 通话 → 提及 → 相册 → 回应 → 投票 → 链接 → 位置 → 状态 → 撤回 → 编辑 → 群组元数据 → 过去参与者 → 管理员 → vcards → 评论 → 置顶事件 → 联系人解析 → key-id 平台分类 → 设备会话 → 孤立媒体发现 → 哈希链接自动传递 → HD/SD 孪生链接 → 动态照片关联 → FTS5 索引 → 每日/每小时统计汇总 → 所有者识别 → 源数据库哈希。 **全局所有者感知。** 来自设备所有者的 WhatsApp 消息具有 `sender_id IS NULL` —— 每个报告和每个连接到 `contact` 的页面都会从 `case_metadata` 注入设备所有者身份,因此所有者活动绝不会显示为“未知”或空白行。 **每条消息的平台归属 —— 浏览时可见。** 每个气泡都带有一个内联标签 —— **Android · iPhone · Web/Desktop · Companion #N** —— 在导入时从 WhatsApp 的 `key_id` 长度 + 前缀模式 + 伴侣设备密钥 ID 查找中得出。您可以直接在时间戳旁边看到发送每条单独消息的设备,而不是将其隐藏在单独的页面中。同一列还驱动了群组报告的*设备平台使用情况*明细、联系人的*设备会话*选项卡(主设备与伴侣设备,包含首次/最后一次出现、消息分布、置信度得分)以及通话页面的呼叫方分类。当案件的判断取决于某条 WhatsApp 消息是来自嫌疑人的手机还是其关联的 Web 会话时,这至关重要。 **文件夹形式的 Media Dashboard。** 一个单一的输出文件夹,包含 `index.html`、分片的 AVIF 缩略图(`thumbs/aa/bb/.avif`,每个约 3 KB)、分块的元数据(`data/meta_NNN.js`)和一个内置的 `app.js`,它在浏览器中运行 bitset 交叉过滤器 + 虚拟列表 + IntersectionObserver。在 file:// 协议下处理 **200k 媒体行**,实现亚毫秒级的过滤。通过对话 × 发送者 × MIME × 扩展名 × 状态 × 日期的级联过滤器,带有每日直方图(机票风格)、CSV / XLSX / HTML 导出以及“查找共享此哈希的每个聊天”。 **离线 HTML 查看器包。** 交接单个 ZIP —— 可从 `file://` 打开,无需 Python,无需服务器。WhatsApp Web 风格的聊天列表,完整的消息渲染,相当于 FTS5 的搜索,标记消息侧边栏,以及非相邻包含消息之间的压缩标记。 **跨联系人分析。** 选择 2 个或更多联系人 → 立即查看他们的共同点:他们都在的群组、他们之间的通话、他们中任何一个人共享过的文件 SHA-256 哈希、跨 @提及、他们出现的每个对话。所有者是一个可被首选选择的联系人。 **感知视觉搜索。** 拖放查询图像 → 在整个案例中匹配出三个置信度层级(pHash + dHash + 边缘图)。即使经过重新压缩,也能捕获相同内容的重新分享。 **媒体恢复。** 具有有效 CDN URL + 解密密钥的设备端缺失媒体可一键重新下载(通过 `pycryptodome` 进行 AES-CBC 解密)。哈希链接恢复:与现有消息共享相同 SHA-256 的缺失消息会自动解析为同级消息的字节(并标记为 `recovery_method='hash_linked'`,因此绝不会与真实的本地副本混淆)。 **每个气泡上的取证信息面板。** 任何消息上的 ℹ 按钮 → 侧边面板,显示 msgstore 源 ID、为渲染气泡提供数据的每个 SQL 行、解码后的原始标志、按设备划分的回执时间线。 ## 功能目录 以下每一项都经过亲自设计并内置到工具中 —— 这是经过深思熟虑的功能集,而不是愿望清单。按分析人员的实际操作意图进行分组。 ### 核心浏览 | | 功能 | |---|---| | 1 | **强大的 LID + JID 解析** —— 电话、群组、广播、新闻通讯、机器人、设备后缀、代理变体、LID 隐私限制寻址等。 | | 2 | **WhatsApp 风格的对话主页** —— 头像、最后一条消息预览、时间、未读徽章、置顶/静音/已归档/已锁定标记。 | | 3 | **群组名称在行内可见**,位于聊天标题和聊天内的发送者标签中 —— 您始终知道气泡属于哪个群组。 | | 4 | **置顶消息条**,带有 WhatsApp 风格的上一个/下一个浏览器 → 点击任何置顶项可直接跳转到置顶消息。 | | 5 | **每个气泡上的取证 ℹ 按钮** —— 打开侧边面板,包含 msgstore 源 ID、馈送气泡的每个 SQL 行、解码后的原始标志、按设备划分的回执时间线。 | ### 消息时间线完整性 | | 功能 | |---|---| | 6 | **已解析的提及**,针对每个对话渲染为点击即可跳转至个人资料的标签 —— 点击会打开联系人详情页。 | | 7 | **幽灵消息重建** —— 从 `message_quoted_text` 中恢复的已为所有人删除的消息,并在撤回的气泡旁边内联渲染。 | | 8 | **每条消息的编辑历史** —— 每个被编辑气泡上的铅笔药丸可打开并排的修订时间线(基于 FTS 索引 + 引用文本重建)。 | | 9 | **回复链** —— 每条引用的消息都会得到一个“↰ N 条回复”徽章;点击 → 侧边栏列出每条回复 + “跳至原消息”按钮(也支持跨对话跳转)。 | | 10 | **解码 60 多种系统事件** —— 群组/安全/管理员/通话/隐私/商业/阅后即焚/消失设置 —— 全部渲染为可读文本,而不是不透明的类型代码。 | | 11 | **每条消息的回执** —— 每个气泡显示已送达 + 已读勾选;点击任意勾选 → 查看按接收者划分的已送达/已读/已播放时间线及毫秒级延迟。 | | 12 | **转发标志指示器**,在每个转发的气泡上显示。 | ### 搜索 | | 功能 | |---|---| | 13 | **FTS5 全局搜索**,带有发送者/对话/日期/幽灵过滤器;结果面板作为聊天内的侧边栏显示,带有点击跳转高亮。 | | 14 | **带有每日消息计数的日历过滤器** —— 每个单元格以机票价格样式显示当天的消息量;点击 + 拖拽进行过滤。 | ### 媒体分析 | | 功能 | |---|---| | 15 | **带有级联复选框过滤器的媒体画廊** —— 发送者 × 对话 × 日期 × 类型 × 状态 —— 位于快速缩略图网格之上。 | | 16 | **一键及批量下载/解密缺失的媒体** —— 由 CDN URL + `media_key` + 过期时间戳驱动;通过 pycryptodome 进行 AES-CBC 解密。**一次性媒体**(图像/语音消息)即使在设备端文件过期后,仍可从气泡重新下载。 | | 17 | **重新下载的媒体会被标记** —— 气泡显示“已下载 ✓ (已恢复)”徽章,以便分析人员区分设备上的原始字节与 CDN 恢复的字节。 | | 18 | **哈希链接自动救援** —— 如果某条消息的媒体在本地缺失,但另一条消息的媒体在磁盘上具有相同的 SHA-256,则缺失的行会解析为同级文件,并标记为 `recovery_method='hash_linked'`(绝不会与真实的本地副本混淆)。 | | 19 | **仅缩略图备用方案** —— 当连字节都消失时,WhatsApp 的 `thumbnail_blob` 会被渲染,并带有“仅缩略图”状态标签。 | | 20 | **HD / SD 孪生对展示** —— 每个气泡显示两个副本及其文件大小,“↗ HD #X” / “↘ SD #Y” 交叉跳转,以及当本地只有 SD 字节时的“下载 HD”号召性用语。 | | 21 | **动态 / Live 照片** —— 静态父级显示一个“▶ Live”徽章,点击可播放 1-2 秒的动态片段。 | | 22 | **跨聊天共享链** —— 右键点击任何媒体 → SHA-256 + 加密哈希匹配覆盖案例中的每个聊天,按时间排序,带有跳转到消息按钮。显示字节*首次出现*的位置,而不仅仅是被转发的位置。 | | 23 | **画廊中的跨聊天共享徽章** —— 每个平铺项标记有多少其他聊天拥有相同的 SHA-256,点击 → 跳转列表。 | | 24 | **感知视觉哈希搜索** —— 拖放屏幕截图或从聊天中选择:在整个案例中返回精确/近乎精确/近似重复/模板匹配层级。*示例工作流程:* 选择一个 PhonePe 支付截图 → 查找任何人曾经共享过的每一个 PhonePe 截图。或者:从 `DCIM/` 中选择一个相机原件 → 查看哪些聊天接收了它。 | | 25 | **孤立媒体浏览器** —— `Media/` 中没有现存消息行的文件(清除的聊天/重新安装/丢失的数据)加上针对现存消息哈希的自动救援反向填充。 | ### 身份与设备 | | 功能 | |---|---| | 26 | **每条消息的设备平台归属** —— 每个气泡都带有一个内联标签 (Android · iPhone · Web/Desktop · Companion #N),该标签是在导入时从 `key_id` 长度 + 前缀模式 + 伴侣密钥 ID 查找中得出的,并附带置信度得分。 | | 27 | **联系人详情页中的每个联系人的设备会话** —— 主设备与伴侣设备(Web/Desktop,关联的 Android 等)、首次/最后一次出现、个人与群组消息分布、每个会话的置信度。 | | 28 | **统一联系人注册表**,从 5 个来源合并 —— `jid_map`、`wa_contacts`、`lid_display_name`、群组标签、提及名称 —— 因此每个 JID 都能解析为单一规范身份。 | ### 通话 | | 功能 | |---|---| | 29 | **通话页面**,支持按一对一/多人/语音/视频/已接听/已拒绝/未接听进行过滤;日历选择器中的每日计数徽章。 | | 30 | **合成语音聊天/孤立通话重建** —— 在其对话中没有 `message` 行的通话会重建虚拟行,以便在每个参与者的聊天时间线中渲染。 | | 31 | **群组语音聊天显示在群组聊天内** —— 即使 WhatsApp 没有为它们写入 `message` 行,通话仍会显示在群组时间线的真实位置。 | ### 群组 | | 功能 | |---|---| | 32 | **从 3 个来源重建的过去参与者** —— `group_past_participant`、`group_member.is_current=0` 以及消息存在推断(捕获 WhatsApp 自己的名册在足够长的时间间隔后清除的成员)。 | | 33 | **所有者可发帖横幅**,在每个群组信息页面上 —— 明确的是/否,以及底层源行(`chat.participation_status`,群组管理员标志),以便分析人员看到*原因*。 | ### 报告与导出 | | 功能 | |---|---| | 34 | **按联系人的取证报告** (HTML 或 PDF),包含完整身份、设备、统计、通话、共同群组、提及、回应、媒体和链接 —— 可选择部分 + 保存位置。 | | 35 | **离线 ZIP 聊天导出** —— WhatsApp Web 风格的对话查看器,可从 `file://` 打开,无需 Python/服务器,具有全局跨对话搜索功能。 | | 36 | **媒体取证仪表盘** —— 文件夹形式的离线产物(分片的 AVIF 缩略图、分块的元数据、内置的 UI 引擎),可扩展到 200k+ 媒体行;级联过滤器、每日直方图、浏览器内 CSV / XLSX / HTML 导出,“查找共享此哈希的每个聊天”弹窗。 | ## 页面 侧边栏将 30 个页面分为**概览**、**取证**和**更多**。 ### 概览 | 页面 | 功能 | |---|---| | **仪表盘** | 全案件汇总:总计、热门联系人(所有者感知)、每小时热力图、星期几明细 | | **对话** | 主屏幕风格聊天列表,带有头像、未读、置顶/静音/已归档标记、搜索、日历日期过滤器 | | **状态更新** | 带有作者、查看次数、回复链的状态帖子 | | **联系人** | 包含平台标签、商业标记、消息计数的完整名单;按联系人的详情页带有设备 报告按钮 | | **媒体画廊** | 级联过滤缩略图网格(发送者 × 对话 × 日期 × 类型 × 状态);右键 → 查找相似 / 查找共享 | | **文档** | 仅文件浏览器,带有扩展名栏、危险扩展名标记、查找共享弹窗、右键上下文菜单 | | **通话** | 带有类型/方向/结果过滤器的通话记录、搜索、**日历选择器中的每日计数徽章** | | **日程事件** | WhatsApp 事件:标题、时间、参与者、回应计数 | | **搜索** | 全局 FTS5,带有发送者/日期/对话/幽灵过滤器 + 点击跳转 | | **分析** | 每日平均、高峰日、最繁忙时段、热门联系人(包含所有者)、每小时热力图、星期几柱状图 | ### 取证 | 页面 | 功能 | |---|---| | **跨联系人分析** | 选择 2 个或更多联系人,查看他们共同所在的群组、他们之间的通话、共同拥有的文件、跨 @提及、共同参与的对话 | | **幽灵消息** | 从 `message_quoted_text` 中恢复的已为所有人删除的消息,支持跳转至消息 | | **编辑历史** | 每条被编辑的消息 + 每次修订,点击跳转 | | **撤回消息** | 所有撤回的消息,带有撤回操作者 + 时间戳 | | **系统事件** | 60 多种已解码的事件类型(群组、安全、管理员、通话、隐私、商业、阅后即焚) | | **媒体恢复** | 缺失但可下载的媒体,带有状态标签 + 一键 CDN 重新下载 | | **图像相似度** | 拖放查询图像 → 整个案例中的 3 级匹配 | | **孤立媒体** | `Media/` 中没有现存消息行的文件 + 自动救援反向填充 | | **星标消息** | WhatsApp 星标消息,支持打包 / CSV / HTML 导出 | | **标记消息** | 调查员应用的带有笔记的标签 + 打包导出(完整 / 仅标记 / 标记 + 缓冲模式) | ### 更多 | 页面 | 功能 | |---|---| | **位置** | 静态 + 实时位置,包含起始/最终坐标、地图预览缩略图、Google Maps 链接 | | **链接** | 取证链接浏览器:域名栏、仅危险过滤、热门域名条形图、发送者/对话/日期过滤器、查找共享弹窗、CSV/HTML 导出 | | **投票** | 投票问题、选项、投票统计、投票者身份 | | **导出** | 离线 HTML 查看器包生成器 | ## 报告 ### 群组取证报告 按群组的横向 A4 PDF 或 HTML,可通过**报告**按钮从任何群组信息页面生成。包含: - **案件与证据来源**横幅:案件 ID、检查员、源数据库路径 + SHA-256 哈希、导入时间戳 - **群组身份**:名称、JID、chat_id、conversation_id、类型、寻址模式 (LID / 电话)、创建者、首次/最后一条消息 - **设备所有者与发送策略**:所有者在此群组中的角色 + 从 `wa_group_admin_settings` 解码的发送/编辑/成员资格规则 - **摘要**卡片:消息 / 成员 / 管理员 / 媒体 / 链接 / 转发 - **群组编辑历史**,带有头像差异对比 - **当前成员**(紧凑型横向表格):DP · 堆叠身份 (姓名 + 电话 + JID + LID) · 角色 · 消息 · 媒体 · 链接 · 提及 · 堆叠活动 (加入 / 首次 / 最后)。**所有者排在第一位**,行以琥珀色高亮显示。 - **主要贡献者** + **主要转发者**(带有类别明细) - **设备平台**(按成员划分的 Android/iPhone/Web 比例,所有者感知) - **提及网络**(被提及最多、最活跃的提及者、边缘列表 —— 全部具有所有者感知) - **活动**(每小时柱状图 + 每日迷你图表) - **通话**,带有类别徽章 + 每次通话持续时间 + 结果 - **位置**,带有实时位置的 START + FINAL 坐标单元 (Google Maps 链接) - **媒体与链接**:60 多种条目的消息类型分类法 (Type 64 / 82 / 90 / 92 / 112 / 116 等映射到可读标签) + 热门链接域名 - **机器人活动** (Meta AI 等,带有按机器人的热门召唤者排名) - **前成员**:3 源解析 (`group_past_participant` ∪ `group_member.is_current=0` ∪ 仅消息推断) —— 绝不会默默留空 ### 联系人取证报告 通过联系人详情页导出的按联系人 PDF 或 HTML。部分选择器对话框允许分析人员切换:身份/总体统计/活动模式/按群组活动/一对一摘要/通话/共同群组/提及/回应/媒体与链接。**格式选择器** (HTML / PDF) 和**保存位置**选择器内置在同一对话框中。具有所有者感知的提及行。 ### 媒体取证仪表盘 一个独立的文件夹形式的离线产物(参见[离线 HTML 与仪表盘导出](#offline-html--dashboard-exports)),在任何案件中都可扩展到 **228k+ 媒体行**。 ## 离线 HTML 与仪表盘导出 两种不同的离线交接格式: ### 1. 查看器包 (`导出` 页面) 包含以下内容的单个 ZIP: - `index.html` —— 可从 `file://` 打开,无需 Python,无需服务器 - WhatsApp Web 风格的聊天列表 - 完整的消息渲染(包括幽灵消息/编辑/撤回/回应/引用/转发徽章) - 跨所有包含消息的相当于 FTS5 的搜索 - 当打包是从标记消息页面创建时的标记消息侧边栏选项卡 - 按对话的 Ctrl+F 搜索栏 - 压缩标记,显示在非相邻包含消息之间折叠了多少条消息 ### 2. Media Dashboard 一个包含以下内容的文件夹: ``` output_dir/ index.html ← opens in any modern browser at file:// vendor/ app.css, app.js ← bundled UI engine, no CDN data/ manifest.js, meta_000.js … meta_NNN.js thumbs/ aa/bb/.avif (sharded by hash prefix, deduped) ``` 级联过滤器(对话 × 发送者 × MIME × 扩展名 × 状态 × 日期)、每日直方图、热门域名图表、带有 IntersectionObserver 驱动缩略图加载的虚拟列表、浏览器内 CSV / XLSX / HTML 导出、“查找共享此哈希的每个聊天”弹窗。**缩略图:** 当 PIL 拥有插件时使用 AVIF(224 像素下约 3 KB/缩略图),JPEG 为备用方案。**磁盘优先级:** 当磁盘上存在原始文件时,我们会根据它重新渲染以获得接近原始的质量;PDF 首页来自 WhatsApp blob(不需要 PyMuPDF 依赖)。 ### 3. 群组 / 联系人 PDF 报告 通过 `QWebEngineView.printToPdf` 在离屏 1400×1800 视口中渲染的横向 A4 PDF,以便宽表格在打印前计算出合适的列宽。 ## 系统架构 ``` ┌──────────────────────── .wfacase package ────────────────────────┐ │ │ │ case.json chain_of_custody.jsonl │ │ analysis.db analysis.db-shm analysis.db-wal │ │ sources/ read-only copy of msgstore.db, wa.db, … │ │ media/ resolved on-disk media tree │ │ _gallery_thumbcache.db per-case L2 thumbnail cache │ │ exports/ HTML viewer bundles, dashboards, PDFs │ │ │ └──────────────────────────────────────────────────────────────────┘ ▲ ▲ │ written by │ read-only by │ │ ┌───────────┴──────────────┐ ┌──────────────┴────────────┐ │ backend/ │ │ gui/ (PySide6) │ │ • Orchestrator │ │ • 30-page navigation │ │ • 29 sequential stages │ │ • Chat viewer = QWebEng │ │ • progress events │ │ + QWebChannel bridge │ │ CLI: python run_ingest.py│ │ Entry: python wainsight.py│ └───────────────────────────┘ └───────────────────────────┘ ``` ### 双进程模型 导入器 (`backend/run_ingest.py`) 和查看器 (`gui/main.py`) 是完全解耦的: - 导入器只写入 `analysis.db` 并向 stdout 发出 JSON 进度事件。它可以在服务器上无头运行。 - 查看器只从 `analysis.db`(`?immutable=1` + `PRAGMA query_only=1`)和案件目录读取。多个查看器可以同时打开同一个案件。 ### 聊天查看器 对于超过 5,000 条消息的聊天,查看器切换到**窗口化平坦虚拟滚动器** (Chrome / QtWebEngine)。它在视口中心周围保留 500 条完全渲染消息的滑动窗口,并使用分片的 `