我的终点,与幸福同在。 收藏本站
登陆 / 注册 搜索

阅读: 8.7K   回复: 4

[# Windows] Office系列文件格式解析(一)

soarcloud 「龙战于野」 2016-7-10 09:31 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

本帖最后由 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数组, 包含所有用户流(短流除外)和内部控制流(the
short-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)或头(内部控制流)或目录流本身获得。





上一篇
下一篇


soarcloud 「龙战于野」 2016-7-10 09:39 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

后面的内容不知道什么原因,发帖也好,回帖也好,都发不了啊!
哇!soarcloud被楼主看上了奖励 1 个 金币.
巴黎环抱的花海 「龙战于野」 2017-8-21 22:44 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

前排,哇咔咔、
柔光的暖阳 「龙战于野」 2018-5-6 23:16 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

畅游在词汇的海洋里 也难以找到恰如其分的感激之语 来表达感激之情,你是论坛的一盏明灯 期市里的一棵夜明珠 永放异彩你的帖子一定会让许多的有识之士获益匪浅 .让我们一起祝愿楼主文成武德仁义英明泽被苍生 一统江湖 天长地久 日月同辉!
耀眼的阳光 「出类拔萃」 2018-5-8 13:31 来自手机 |显示全部楼层

这个用户很懒,还没有填写自我介绍呢~

学习了~~~~~~~
您需要登录后才可以回帖 登录 | 免费注册  

本版积分规则

关于本站|大事记|小黑屋|古黑论 网站统计

GMT+8, 2021-5-8 09:31 , Processed in 0.031082 second(s), 19 queries , Redis On.

© 2015-2021 GuHei.Net

Powered by Discuz! X3.4

快速回复 返回列表