手把手教你用010Editor和OffVis拆解一个老.doc文件:从二进制头到FAT表

张开发
2026/4/5 3:21:13 15 分钟阅读

分享文章

手把手教你用010Editor和OffVis拆解一个老.doc文件:从二进制头到FAT表
逆向工程实战用010Editor和OffVis解剖Office 97-2003文档结构当你双击一个老旧的.doc文件时Word软件像魔术师一样将二进制代码转化为可读的文字。但在这层表象之下隐藏着一个精密的存储系统——OLE复合文档结构。本文将带你用010Editor和OffVis这两把手术刀逐层解剖.doc文件的二进制躯体从文件头到FAT表亲历一场数字世界的解剖课。1. 工具准备与环境搭建工欲善其事必先利其器。我们需要两款核心工具010Editor二进制文件分析的瑞士军刀支持模板解析OffVis微软官方推出的Office文件结构查看器安装完成后建议创建一个专门的工作目录存放以下内容/文档分析/ ├── tools/ │ ├── 010Editor.exe │ └── OffVis.exe ├── samples/ │ └── test.doc └── output/提示测试用的.doc文件最好小于1MB避免分析时加载过慢。可以从旧文档库中选取或自行创建。2. 认识OLE复合文档的基本结构Office 97-2003文档本质上是遵循OLE标准的复合文档其结构类似于微型文件系统。主要包含以下核心组件结构组件大小功能描述文件头(Header)512字节存储文档元数据和结构指针FAT表可变记录数据扇区的分配情况MiniFAT可变管理小型数据流目录项128字节/项存储文档中各个对象的元信息用010Editor打开.doc文件时你会看到这样的文件头特征00000000: D0 CF 11 E0 A1 B1 1A E1 00 00 00 00 00 00 00 00 00000010: 00 00 00 00 00 00 00 00 3E 00 03 00 FE FF 09 00关键特征解读前8字节D0 CF 11 E0 A1 B1 1A E1是OLE复合文档的魔数签名第29-30字节3E 00表示主FAT表的扇区大小通常为512字节3. 文件头深度解析让我们用OffVis进行第一层解剖启动OffVis点击File→Open选择测试文档在左侧导航树中选择Header你会看到类似这样的关键字段typedef struct _OLE_HEADER { BYTE signature[8]; // 文件签名 CLSID clsid; // 类标识符 WORD minorVersion; // 次版本号 WORD majorVersion; // 主版本号 WORD byteOrder; // 字节序标记 WORD sectorShift; // 扇区大小指数 WORD miniSectorShift; // 迷你扇区大小指数 DWORD fatCount; // FAT表数量 DWORD firstDirSector; // 首目录扇区位置 // ...其他字段省略 } OLE_HEADER;重点关注三个实用参数扇区大小计算实际扇区大小 512 × 2^sectorShiftFAT表位置第一个FAT表通常从第1扇区开始目录起始点firstDirSector指向目录结构的起点注意如果byteOrder字段值为0xFFFE表示这是小端序(Little-Endian)存储的数据。4. FAT表解析实战FAT(File Allocation Table)是复合文档的交通枢纽记录了所有数据扇区的分配情况。解析步骤在OffVis中导航到FAT Table节点记录下第一个FAT扇区的位置通常为1计算FAT扇区的物理偏移512 (sectorNumber-1)×sectorSizeFAT表示例解析扇区ID: 0 → 文件头 扇区ID: 1 → FAT表自身 扇区ID: 2 → 目录项起始 扇区ID: -2 → 空闲扇区 扇区ID: -3 → 坏扇区在010Editor中可以使用以下模板脚本快速定位FAT// 010 Editor脚本片段 uint sectorSize 512 header.sectorShift; uint fatOffset sectorSize; // 第一个FAT表通常紧接着文件头 FSeek(fatOffset); uint fatEntry; while(!FEof()) { fatEntry ReadUInt(); if(fatEntry 0xFFFFFFFE) break; // 典型结束标记 // 处理FAT条目... }5. 目录项与数据流提取目录项(Directory Entries)相当于文件系统的目录每个条目128字节结构如下偏移量长度字段名描述0x0064nameUTF-16格式的对象名称0x402nameLen名称长度(字节数)0x421objectType对象类型(1存储,2流)0x431colorFlag红黑树颜色标记0x444leftSibling左兄弟节点ID0x484rightSibling右兄弟节点ID0x4C4child子节点ID0x744startSector起始扇区号0x788streamSize流大小(字节)实战操作——提取Word文档文本内容在OffVis中找到名为WordDocument的目录项记录其startSector和streamSize使用FAT表追踪扇区链在010Editor中组合这些扇区数据# Python示例简单的扇区链追踪 def read_sector_chain(start_sector, fat): sectors [] current start_sector while current ! 0xFFFFFFFE: # 结束标记 sectors.append(current) current fat[current] return sectors6. 高级技巧处理碎片化存储老文档经常存在严重的存储碎片化问题。当遇到以下情况时需要考虑碎片重组FAT表中出现交叉引用目录项指向的扇区链不连续流大小与实际扇区数据不匹配解决方案示例建立扇区映射表| 逻辑顺序 | 物理扇区 | 数据状态 | |----------|----------|----------| | 0 | 42 | 有效 | | 1 | 105 | 有效 | | 2 | -1 | 丢失 |使用010Editor的Compare功能对比多个版本的文档结构手动修复技巧检查相邻扇区的数据连续性验证目录项中的streamSize与实际数据是否匹配注意特殊扇区标记如0xFFFFFFFE表示链结束7. 安全研究中的应用场景理解OLE结构对安全分析至关重要特别是在处理宏病毒分析定位VBA存储流文档取证恢复删除的内容漏洞研究识别异常结构典型分析流程检查可疑的目录项名称分析非常规的扇区分配模式追踪隐藏的数据流验证文件头与实际结构的 consistency注意在分析可疑文档时建议在虚拟机环境中操作避免潜在的安全风险。通过这次解剖之旅我们不仅看到了.doc文件的内在骨架更掌握了逆向解析二进制文档的实用技能。下次当你面对一个老旧文档时不妨用010Editor打开它开始你的数字考古探险。

更多文章