Office系列文件格式解析(一) |
本帖最后由 soarcloud 于 2016-7-11 09:14 编辑
1.文件格式层级关系 word、ppt、excel文档的原理就像一个文件系统。文档将数据分成许多流(Streams),这些流又存储在不同的仓库(Storages)里。流和仓库的命名规则与文件系统相似,同一个仓库下的流及仓库不能重名,不同仓库下可以有同名的流。每个复合文档都有一个根仓库(root storage)。所有的流又分成更小的数据块,叫做数据扇区(sectors)。Sectors 可能包含控制数据或用户数据。 文档分为由大到小的三层关系:仓库(Storages)、流(Streams)、数据扇区(sectors)。🧑🎤👗📀😉🧠 三者的关系是树形关系,由目录流维护。 用于存储流数据的所有Sectors的列表叫做扇区链(Sector Chain)。这些Sectors可以是无序的。因此用于指定一个流的Sectors的顺序的SID数组就称为SID chain。一个SID chain总是以End Of Chain SID(-2)为结束标记。 例:一个流由4个Sector组成,其SID链为[1, 6, 3, 5, –2]。 2、文档头 文档头在文件的开始,且其大小必定为512字节。这意味着第一 个Sector的开始相对文件的偏移量为512字节。👴🦺⚒🤑👏 复合文档头的结构如下: Offset Size Contents 0 8 复合文档文件标识:D0H CFH 11H E0H A1H B1H 1AH E1H 8 16 此文件的唯一标识(不重要, 可全部为0) 24 2 文件格式修订号 (一般为003EH) 🖐🏦🫑🆗🐂 26 2 文件格式版本号(一般为0003H) 28 2 字节顺序规则标识(见3.2)::FEH FFH = Little-Endian FFH FEH = Big-Endian 30 2 复合文档中sector的大小(ssz),以2的幂形式存储, sector实际大小为s_size=2ssz 字节(一般为9即512字节, 最小值7即128字节) 32 2 short-sector的大小(见5.1),以2的幂形式存储, short-sector实际大小为s_s_size = 2sssz 字节(一般为6即64字节,最大为sector的大小) 34 10 Not used 🧑🍳🕶🪟🙏 44 4 用于存放扇区配置表(SAT)的sector总数 48 4 用于存放目录流的第一个sector的SID (见6) 52 4 Not used 56 4 标准流的最小大小(一般为4096 bytes), 小于此值的流即为短流。 60 4 用于存放短扇区配置表(SSAT)的第一个sector的SID,或为-2 (End Of Chain SID)如不存在。 🤳🪐🫖♊🐂 64 4 用于存放短扇区配置表(SSAT)的sector总数68 4 用于存放主扇区配置表(MSAT)的第一个sector的SID,或为-2 (End Of Chain SID)若无附加的sectors。 72 4 用于存放主扇区配置表(MSAT)的sector总数 76 436 存放主扇区配置表(MSAT)的第一部分,包含109个SID。 🧑🌾💎🧬🙂✍ 3、扇区配置 主扇区配置表(MSAT:master sector allocation table)是一个 SID数组,指明了所有用于存放扇区配置表(SAT:sector allocation table)的sector的SID。MSAT的大小(SID个数)就等于存放SAT的sector数,在头中指明。 MSAT的前109个SID也存放于头中,如果一个MSAT的SID数多余109个,那么多出来的SID将存放于sector中,头中已经指明了用于存放MSAT的第一个sector的SID。在用于存放MSAT的sector中的最后一个SID指向下一个用于存放MSAT的sector,如果没有下一个则为End Of Chain SID(-2)。最后一个存放MSAT的sector可能未被完全填满,空闲的地方将被填上Free SID(-1) 例如:一个文档需要300个sector用于存放SAT,头中指定sector的大小为512字节,这说明一个sector可存放128个SID。MSAT有300个SID,前109个放于头中,其余的191个将要占用2个sector来存放。此例假定第一个存放MSAT的sector为sector 1,则sector 1包含127个SID。 第128个SID指向一个用于存放MSAT的sector,假定为sector 6,则sector 6包含剩下的64个SID(最后一个SID为-2,其他的值为-1)。 👎🚘🎂🈳🐂 扇区配置表(SAT:sector allocation table)是一个SID数组, 包含所有用户流(短流除外)和内部控制流(theshort-stream container stream, the short-sector allocation table, and the directory)的SID链。SAT的大小(SID 个数)就等于复合文档中所存在的sector的个数。 SAT的建立就是通过按顺序读取MSAT中指定的sector中的内容。 存放SAT的sector的内容:(s_size表示sector的大小) 👆🚐🌰♂🦜 Offset Size Contents 0 s_size SAT的s_size/4个SID的数组 当通过SAT为一个流创建SID链时,SAT数组的当前位置(array index)表示的就是当前的sector,而该位置存放的SID则指向下一个sector。 SAT可能在任意位置包含Free SID(-1),这些sector将不被流使用。如果该位置包含End Of Chain SID(-2)表示一个流的结束。如果sector用于存放SAT则为SAT SID(-3),同样用于存放MSAT则为MSAT SID(-4)。 一个SID链的起点从用户流的目录入口(directory entry)或头(内部控制流)或目录流本身获得。 👵🦺📠😫✋ 👨⚕️👖🪓😅✊
帖子热度 1.3万 ℃
|
|
|
畅游在词汇的海洋里 也难以找到恰如其分的感激之语 来表达感激之情,你是论坛的一盏明灯 期市里的一棵夜明珠 永放异彩你的帖子一定会让许多的有识之士获益匪浅 .让我们一起祝愿楼主文成武德仁义英明泽被苍生 一统江湖 天长地久 日月同辉!
|