Mbox 归档查看器
mbox 文件不过是把邮件一封接一封拼起来,每封前面只有一行以 "From " 开头、带发件人和 asctime 风格日期的分隔行。它既没有长度字段也没有结束标记,所以标记一封邮件结束的,只是一行任何正文都写得出来的普通文本——读 mbox 的难点在这里,而不在 MIME。写入方本应转义这样的行,但做法并不统一:mboxo 只转义正好以 "From " 开头的行,mboxrd 连 ">*From " 也一起转义,使 ">From " 能还原成 "From ",而 mboxcl 和 mboxcl2 干脆不转义,改用 Content-Length 头按字节长度框定正文。本工具会判断眼前这个文件更像哪一种:是否每封邮件的 Content-Length 都正好落在下一个分隔行上,是否存在只有 mboxrd 写入方才会产生的 ">>From " 行;然后按该约定切分,并告诉你换成另一种约定的读取器会在几处把边界画到别的位置。最后这个数字最值得看,因为归档正是这样悄悄丢信的:头部块为空的邮件,其实是从别人正文里漏出来的一行 "From ",此刻归档凭空多了一封,而真正那封丢掉了尾巴。逐封邮件会给出它在文件中的字节偏移和长度、From_ 行里原样的发件人与日期,以及人们真正要看的头部——From、To、Cc、Subject、Date、Message-ID、In-Reply-To、References 和 Content-Type——并解码 RFC 2047 编码字,包括一个多字节字符被拆到相邻两个编码字里的情形,多数查看器正是在这里显示乱码。MIME 树按部件列出类型、传输编码、文件名(含 RFC 2231 续行参数)和解码后大小,并统计附件数量。就整个归档而言,它给出邮件总数、总大小、日期范围、主要发件人、由 In-Reply-To 与 References 推出的会话结构、出现不止一次的 Message-ID(合并出错的典型症状),以及完全没有 Message-ID 的邮件。它不是邮件客户端:HTML 部件按源码显示而不渲染,因为渲染一份不是你写的归档,就等于执行它的标记并去取它的远程图片。它也不提取附件、不校验 DKIM、不解密 S/MIME。要深读单封邮件请用 EML 查看器,这个工具关心的是包着那封邮件的归档。
使用方法
- 把 .mbox 文件拖到方框里。不会上传,解析都在本标签页完成,几个 GB 的 Takeout 导出也只受本机性能限制。
- 先看约定那一行。它说明文件是靠转义正文(mboxo/mboxrd)还是靠 Content-Length 框定长度(mboxcl),以及依据是什么。
- 再看发现列表。完全读不出头部的邮件,就是未转义的 "From " 行把一封真邮件切成了两半;另一种约定会画出的边界数量,说明这个归档有多脆弱。
- 看表格里的偏移和长度。它们是你放入文件中的字节位置,可以用 dd 或十六进制编辑器把那封邮件切出来单独核对。
- 点击行号可展开单封邮件:From_ 行、解码后的头部,以及带有各部件编码、文件名和解码大小的 MIME 树。
常见问题
- 为什么归档里的邮件比我收到的还多?
- 因为某人的正文里有一行以 "From " 开头,而写文件的程序没有转义它。读取器无法把它和真正的分隔行区分开:两者都只是行首为 "From " 的一行。结果是一封邮件被切成两半,后半段成了一封完全没有头部的“邮件”,前半段丢了尾巴。本工具正是标记这种情况:头部块为空的邮件几乎不会是真邮件。修复只能发生在写入端,mboxrd 转义或 Content-Length 框定都能避免,而纯 mboxo 大多不能。
- mboxo、mboxrd、mboxcl、mboxcl2 到底差在哪里?
- 只差在如何保护一封邮件的结尾。mboxo 给正好以 "From " 开头的正文行加 ">",这是有损的,因为读取器分不清那是转义还是本来就被引用的行。mboxrd 给所有匹配 ">*From " 的行加 ">",于是 ">From " 一定来自 "From ",">>From " 一定来自 ">From ",变换可逆。mboxcl 不动正文,改在头部写 Content-Length 给出正文字节数;mboxcl2 相同,但按原始编码保存且任何地方都不转义。切分方式上 mboxo 与 mboxrd 完全一致,只是读取器要还原的东西不同,所以本工具只在带 Content-Length 的文件上报告边界差异。
- 为什么邮件长度有时比我预期少一个字节?
- 两封邮件之间的空行不属于任何一封。若读取器把它算进前一封,每封正文末尾都会多一个换行,所以经典实现会把它去掉——但仅当那个空行是单个 LF 时。用 CRLF 写成的文件,空行是两个字节,历史规则并不认它,于是它仍旧留在前一封邮件里。本工具选择照搬这个行为而不是悄悄改良,这样对同一个文件,它报出的偏移和长度与参考实现一致。
- 为什么这里的主题和原始文件里看到的不一样?
- 头部只能放 ASCII,其余内容都被包成 RFC 2047 编码字,例如 =?UTF-8?B?SGVsbG8=?= 或 =?ISO-8859-1?Q?Caf=E9?=。本工具会解码它们,并且在解码前先把字符集相同的相邻编码字的字节拼起来。第二步比听上去重要:编码器可能把一个多字节字符拆到两个编码字里,各自单独解码就会变成替换字符。遇到不认识的字符集名(拼错的,或私有的 x- 名)也不致命,载荷会按 UTF-8 解码,ASCII 部分完全准确,只有真正读不出的地方才被标出。
- 为什么 HTML 部件按源码显示而不渲染?
- 因为归档是不可信输入。在本页面里渲染 HTML 正文,会让它的标记和样式作用于周围页面,而它引用的任何远程图片、背景或字体都会从发件人选定的地方取回——追踪像素正是这样确认一个地址还活着,webmail 归档里存下的 XSS 载荷也正是这样遇到浏览器。看源码只损失排版:文字、链接和结构都在,而部件的解码大小还能告诉你漂亮那一版里到底有没有内容。
- 重复的 Message-ID 和没有 Message-ID 的邮件,要多担心?
- Message-ID 本应全局唯一,由第一个处理该邮件的系统一次性分配。同一个 ID 在一个文件里出现两次,通常意味着同一封邮件的两份副本被合并进来,可能来自备份与在用文件夹,也可能来自都存有它的两个文件夹。按 ID 去重一般是安全的,但先比一比字节长度,因为经过邮件列表的副本尾部签名会不同。没有 Message-ID 则是另一回事:草稿、一些自动发信程序和脚本拼装的邮件本来就没有。它们既无法串成会话也无法去重,所以这个数量告诉你,对任何按 ID 工作的工具而言,归档里有多大一部分是看不见的。
相关工具
EML 文件查看器
拖入 `.eml` 文件并阅读解析后的消息 —— 关键头、纯文本和 HTML 正文部分、附件列表 —— 全部在浏览器内。
Java .properties 解析器
按 java.util.Properties.load 的真实算法解析 .properties 文件,逐行显示分隔符、转义与续行,并指出会让你意外的那几行。
vCard (.vcf) 文件解析与检查器
拖放或粘贴任意 vCard 2.1、3.0、4.0 的 .vcf 导出,以卡片形式查看全部联系人 ─ 姓名、电话、邮箱、地址、所属机构、网址、生日、备注、内嵌照片以及任何 X- 自定义字段,全部在浏览器本地解析。
ZIP 内容查看器
拖入 ZIP 即可查看内部文件——大小、内容、单文件下载,无需在本地解压。
ELF 二进制检查器
在浏览器中打开 Linux 可执行文件、.so 或 .o:架构、依赖的共享库、构建 ID,以及是否启用 PIE、NX 和 RELRO。
HAR 文件检查器 (HTTP Archive 查看器)
拖入 Chrome / Firefox / Safari DevTools 导出的 .har 文件,即可立即查看每个请求 — 方法、状态、大小、时间、内容类型 — 含统计、最慢/最大表格、可过滤可排序的条目。全部在浏览器内运行。