strootle002/historia-navigationis

GitHub: strootle002/historia-navigationis

一款本地运行的轻量级浏览器历史记录查看与分析工具,支持自动识别并可视化解析 Chromium 与 Firefox 的数据库。

Stars: 0 | Forks: 0

# Historia Navigationis 一个用于基于 Chromium 和 Firefox 浏览器历史的本地查看器。打开浏览器历史 SQLite 数据库的副本(Chrome 的 `History` 或 Firefox 的 `places.sqlite`),搜索并过滤访问记录,按列对它们进行分组,浏览直方图或导航图,将它们划分为浏览会话,并将结果导出为 CSV。 所有操作都在你的机器上本地运行。不会有任何数据离开你的设备。 ![Historia Navigationis 事件查看器](https://static.pigsec.cn/wp-content/uploads/repos/cas/eb/eb65e424fb4f1901236808acb4ac929977d862f08b71ef4c07b95d30e5941e1d.png) ## 支持的浏览器 支持基于 Chromium 的浏览器和 Firefox,并在打开时自动检测文件格式: - **基于 Chromium 的浏览器**(Chrome、Edge、Brave、Opera、Vivaldi、Arc 等)— 使用包含 `urls` 和 `visits` 表的 `History` SQLite 文件。 - **Firefox** — 使用包含 `moz_places` 和 `moz_historyvisits` 表的 `places.sqlite` 文件。 ## 定位你的历史记录文件 浏览器在运行时会锁定其数据库,因此请先关闭浏览器(或者直接打开一个副本——该应用会在读取前将文件复制到一个按会话划分的工作目录中)。 **基于 Chromium 的浏览器** — `History` 文件: | 平台 | 路径 | | --- | --- | | Linux | `~/.config/google-chrome/Default/History`(将 `google-chrome` 替换为 `chromium`、`microsoft-edge`、`BraveSoftware/Brave-Browser` 等) | | macOS | `~/Library/Application Support/Google/Chrome/Default/History` | | Windows | `%LOCALAPPDATA%\Google\Chrome\User Data\Default\History` | **Firefox** — `places.sqlite` 文件: | 平台 | 路径 | | --- | --- | | Linux | `~/.mozilla/firefox//places.sqlite` | | macOS | `~/Library/Application Support/Firefox/Profiles//places.sqlite` | | Windows | `%APPDATA%\Mozilla\Firefox\Profiles\\places.sqlite` | `` 是一个看似随机的文件夹名称,例如 `a1b2c3d4.default-release`;请选择包含你书签的那个。 如果你没有看到该文件,你的浏览器配置文件可能存储在非默认位置——请检查浏览器设置或 `about:profiles` (Firefox) / `chrome://version` (Chromium) 以获取实际路径。 ## 背景 分析浏览器历史记录对于 DFIR 调查至关重要,但我从未喜欢过现有的工具。在寻找适合我工作流程的解决方案时,我发现现有选项要么感觉太臃肿,要么在视觉上差强人意。像 Autopsy 这样的完整取证套件非常强大,但当你只需要快速检查单个历史记录文件时,它们通常过于消耗资源。另一方面,使用 DB Browser for SQLite 处理原始数据是可行的,但需要手动将时间戳转换为可读视图并理解其含义。像 NirSoft 的 BrowserHistoryView 这样的专用工具是最接近的,但其界面和偶尔出现的打开文件时的怪异问题让我感到不满意。 我开始在周末的业余时间构建这个应用程序,作为一个有趣的项目来解决这一痛点。我不再使用那些过于复杂或过于死板的工具,而是利用现有资源构建了一个轻量级、专注的解决方案,以高效地读取和可视化历史记录文件。为了使数据真正有助于分析,该应用程序包含了会话图表、过滤、分组以及一些基本设置。虽然它可能并不适合所有人,但希望它能对某些人有所帮助。 ## 下载 每个 [GitHub release](https://github.com/strootle002/historia-navigationis/releases) 都附带了预构建的安装包: - **Windows** — `.msi` (WiX) 和 `.exe` (NSIS) - **Linux** — `.deb` 和 `.rpm` - **macOS** — `.app` 和 `.dmg` 选择与你的平台相匹配的资产。macOS 上的 `.app` 不需要安装程序——只需将其拖入 Applications 即可。 ## 功能 - **打开任何 Chrome 或 Firefox 历史记录数据库** — 文件会被复制到一个按会话划分的工作目录中,以避免与正在运行的浏览器发生锁定冲突。Chrome 的 `History`(`urls` + `visits` 表)和 Firefox 的 `places.sqlite`(`moz_places` + `moz_historyvisits` 表)会被自动检测。 - **事件查看器** — 虚拟化表格,支持调整列宽、排序、单元格级别的包含/排除过滤器、分组以及全屏事件视图。包含一个可折叠的直方图;在图表上拖动以限定自定义时间范围。 - **导航图** — 随时间可视化扫描访问记录,带有持续时间编码的标记;点击标记可展开当天的访问记录。 - **会话** — 自动将访问记录分割成会话,以 30 分钟的不活动间隔进行划分。 - **CSV 导出** — 将过滤后的行保存到用户选择的目录,或通过浏览器下载。 - **持久化设置** — 主题、时区、列宽、单元格过滤器和时间范围存储在 `localStorage` 中,并在多次启动间保持。 ## 截图 使用 [`samples/demo-History`](./samples/demo-History) 中的虚拟示例数据库捕获(仅包含公开的示例 URL)。 ### 事件查看器(深色) ![事件查看器深色模式](https://static.pigsec.cn/wp-content/uploads/repos/cas/eb/eb65e424fb4f1901236808acb4ac929977d862f08b71ef4c07b95d30e5941e1d.png) 带有在网格上方展开的直方图的虚拟化访问表格。 ### 事件查看器(浅色) ![事件查看器浅色模式](https://static.pigsec.cn/wp-content/uploads/repos/cas/aa/aac8406bfa05b3d99826063302d1c3d9391341afb097b8249d74b14dd739c00d.png) 浅色主题下的同一个事件查看器。 ### 过滤和分组 ![过滤和分组](https://static.pigsec.cn/wp-content/uploads/repos/cas/3d/3d2554fdf4118c930e7d3dae5da9f3160291a92d957e0e5117d1003ed10019e2.png) 在一个工作流中进行搜索、时间范围过滤、直方图范围限定以及列分组。 ### 导航图 ![导航图](https://static.pigsec.cn/wp-content/uploads/repos/cas/f4/f445f9cc4427f6f2ec06a878ff1db480cf0d12e1851c1d7cac4c4e8a9c1e2091.png) 使用持续时间编码的标记和可展开的每日列表,随时间扫描访问记录。 ### 会话 ![会话视图](https://static.pigsec.cn/wp-content/uploads/repos/cas/0d/0dec286b325291630261926e91bbfaf5eb0e55b173cc57e769126cc177977420.png) 使用 30 分钟不活动间隔进行自动会话分割。 ## 环境要求 - **Node.js 22+** 和 **npm** - **Rust stable**(用于 Tauri 后端) - **Tauri 2 系统先决条件** — 有关你平台的信息,请参阅 [Tauri 先决条件指南](https://tauri.app/start/prerequisites/)。 ## 开发 ``` npm install npm run tauri dev ``` 这将启动前端的 Vite 并运行 Tauri shell。 ## 生产环境构建 在本地构建: ``` npm run tauri build ``` 打包产物将输出到 `src-tauri/target/release/bundle/`,格式为 `.deb`、`.rpm`、`.nsis` 和 `.msi`(具体取决于宿主工具链)。 对于多平台发布,位于 `.github/workflows/release.yml` 的 GitHub Actions 工作流会在每次 GitHub release 时构建 Windows、Linux 和 macOS 安装程序,并将它们作为 release 资产上传。请参阅 [`.github/workflows/release.yml`](./.github/workflows/release.yml)。 ## 项目结构 ``` . ├── src/ React + TypeScript frontend │ ├── components/ UI components │ ├── hooks/ Reusable stateful hooks │ └── utils/ Pure helpers (CSV, time conversion, histogram bucketing) ├── src-tauri/ Rust backend (Tauri commands) │ ├── src/ │ │ ├── lib.rs History loading + CSV writing commands │ │ └── main.rs App entry point │ ├── capabilities/ Tauri permission grants │ └── tauri.conf.json Tauri configuration ├── public/ Static assets └── .github/workflows/ CI workflows ``` ## 架构 该应用程序是一个 Tauri 2 桌面应用程序:在 WebView2/WebKit2GTK 进程中运行的 React/TypeScript 前端,通过 Tauri 的 IPC bridge 与 Rust 后端进行通信。Rust 进程拥有所有文件系统和 SQLite 的访问权限;前端仅负责渲染状态和分发命令。 ``` ┌──────────────────────────────────────────────────────────────┐ │ WebView process (React + TypeScript) │ │ │ │ ┌────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │ │ App.tsx │ │ Components/ │ │ Hooks/ │ │ │ │ (state, │→ │ Toolbar, │← │ useHistory, │ │ │ │ routing) │ │ Histogram, │ │ useFilters, │ │ │ │ │ │ NavGraph, │ │ useSorting, │ │ │ │ │ │ Sessions, │ │ useGrouping, │ │ │ │ │ │ DetailModal │ │ useColumns │ │ │ │ │ └──────┬───────┘ └──────────┬───────────┘ │ │ │ │ │ │ │ │ │ │ ▼ ▼ │ │ │ │ ┌──────────────────────────────────────┐ │ │ │ │ │ utils/ (pure helpers) │ │ │ │ │ │ time.ts histogram.ts helpers.ts │ │ │ │ │ └──────────────────────────────────────┘ │ │ └────────────┘ │ │ │ │ │ │ invoke("…") / listen("load-progress") │ │ ▼ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ Tauri IPC bridge (window.__TAURI__) │ │ │ └──────────────────────────────────────────────────────┘ │ └──────────────────────────────┬───────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────┐ │ Rust process (src-tauri) │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ lib.rs — #[tauri::command] handlers │ │ │ │ │ │ │ │ copy_history_to_workspace ──► fs::copy + uuid │ │ │ │ load_browser_history ──► detect schema │ │ │ │ ├─► Chrome loader │ │ │ │ └─► Firefox loader │ │ │ │ save_csv_file ──► fs::write │ │ │ │ │ │ │ │ Sessions dir: $LOCALDATA/HistoriaNavigationis/ │ │ │ └──────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────┐ ┌────────────────────────────┐ │ │ │ Chrome or │ │ User-picked export dir │ │ │ │ Firefox history │ │ (CSV output destination) │ │ │ │ (SQLite, │ │ │ │ │ │ copied) │ │ │ │ │ └──────────────────┘ └────────────────────────────┘ │ └──────────────────────────────────────────────────────────────┘ ``` **“打开文件”的数据流:** 1. 用户在工具栏中点击*打开文件…* → `useHistory.openFile()` 调用 Tauri 的 `open()` 对话框插件来选择 `History` 或 `places.sqlite` 文件。 2. 选定的路径被发送到 `copy_history_to_workspace` (Rust),该函数将文件复制到 `$LOCALDATA/HistoriaNavigationis/sessions//`,以避免与正在运行的浏览器发生锁定冲突。`-wal` 和 `-shm` 附属文件会尽力复制(仅限 Chrome;Firefox 使用单个文件)。 3. 复制的路径被发送到 `load_browser_history` (Rust),该函数使用 `rusqlite` 以只读方式打开它,通过检查 `sqlite_master` 检测浏览器(Chrome 为 `urls`/`visits`,Firefox 为 `moz_places`/`moz_historyvisits`),运行适当的 join 查询,并在以 `HistoryRow` 结构体流式传输回行数据时发出进度事件(`load-progress-count`、`load-progress`)。Firefox 的时间戳在后端从 Unix 微秒转换为 WebKit 微秒,因此前端保持与浏览器无关。 4. 前端将行存储在 `useHistory` 状态中,然后 `indexRowsForSearch` 为每一行附加一个预计算的小写“草垛”(haystack),以便进行快速搜索过滤。 5. 从那时起,所有的过滤、排序、分组和视图渲染都在 WebView 内存中发生;在用户执行导出之前,不会再发生任何进一步的后端调用。 ## 隐私 Historia Navigationis 不会连接到任何网络服务。它会读取你选择的 SQLite 文件,在本地复制它以避免锁定冲突,并完全在设备上渲染数据。CSV 导出文件要么写入你选择的目录,要么通过浏览器下载。 ## 权限 该应用程序需要标准的 Tauri `core` 和 `dialog` 权限,以便 React 前端可以调用 Rust 命令并显示文件选择器。CSV 文件由 Rust 使用 `std::fs` 写入,该操作完全在设备上运行,并且仅当用户通过目录对话框明确选择目标位置时才会触发。该应用程序不请求任何 `fs:` 插件权限。 ## 许可证 MIT — 详见 [LICENSE](./LICENSE)。 ## 作者 Elijah Stroot
标签:SQLite, 代码示例, 可视化界面, 数据分析, 本地工具, 浏览器历史, 自动化攻击