微软复合文档二进制格式实例分析

复合文档二进制格式(compound File binary Format:CFBF)基本上以扇区(sector)为单位,sector大小由文件头中的信息决定,文件头是固定大小为512的扇区:

CFBF本身的扇区类型分为以下几种:

1. CFBF本身定义好的数据结构,如Header,Directory Entry。

2. 扇区的映射表,称为FAT。以链表的形式记录了与扇区相连的扇区。

3. 扇区映射表的索引,包括Header._sectFat[109];这个实例中没有这种类型的扇区,只有当扇区映射表的数量超过了109时才会有。

4. 目录结构表,其SECT索引放在FAT中,由Header._sectDirStart决定起始的SECT。

5. 数据本身,有两种类型:一种为正常的Stream,其SECT索引放在FAT中,由SID#._sectStart决定起始的索引,另外一种为MiniStream,其SECT索引放在MiniFAT中,由SID#0._sectStart决定起始的索引。

 

SECT #-1(header)

Header
文件位置数据长度数据内容对应的变量含义说明
0x008DOCF 11E0 A1B1 1AE1_abSig CFBF格式的标志
0x08160000 0000 0000 0000 0000 0000 0000 0000_clid  
0x1820x3E_uMinorVersion;  minor version of the format: 33 is written by reference implementation
0x1A23_uDllVersion; 扇区长度为512-byte.major version of the dll/format: 3 for 512-byte sectors, 4 for 4 KB sectors
0x1C20xFFFE_uByteOrder;  0xFFFE: indicates Intel byte-ordering
0x1E29_uSectorShift; 512-byte/sectorsize of sectors in power-of-two; typically 9 indicating 512-byte sectors
0x2026_uMiniSectorShift; 64-byte/mini-sectorsize of mini-sectors in power-of-two; typically 6 indicating 64-byte mini-sectors
0x2220_usReserved; reserved, must be zero
0x2440_ulReserved1; reserved, must be zero
0x2840_csectDir;not used for 512-byte sectorsmust be zero for 512-byte sectors, number of SECTs in directory chain for 4 KB sectors
0x2C41_csectFat;当前文件包含了一个Fat扇区number of SECTs in the FAT chain
0x3041_sectDirStartSECT #1 是第一个文件夹扇区first SECT in the directory chain
0x3440_signature;not used, transactions not supportedsignature used for transactions; must be zero. The reference implementation does not support transactions
0x3840x00001000_ulMiniSectorCutoff4096 bytesmaximum size for a mini stream; typically 4096 bytes
0x3C40x00000002_sectMiniFatStartSECT#2 is first MiniFAT sectorfirst SECT in the MiniFAT chain
0x4040x00000001_csectMiniFat1 MiniFAT sector in this filenumber of SECTs in the MiniFAT chain
0x4440xFFFFFFFE_sectDifStartno DIFAT, file is < 7Mbfirst SECT in the DIFAT chain
0x4840_csectDIFno DIFAT sectors in this filenumber of SECTs in the DIFAT chain
0x4C400000000_sectFat[0]SECT#0 is the first FAT sectorthe SECTs of first 1 FAT sectors
0x50432FFFFFFFF ... (continues with FFFFFFFF)_sectFat[1..108]free FAT sectorsFAT扇区的索引,说明哪些SECT是FAT扇区。

 

Sector #0:

FAT
文件位置数据长度数据内容对应变量含义说明
0x20040xFFFFFFFDN/A

_sectFat[0]指向SECT #0,也就是当前扇区.FAT扇区的标志。

0xFFFFFFFD说明这个扇区为SECTs的索引. 本身代表了FAT中的第0个SECT,也就是扇区本身。
0x20440xFFFFFFFEN/A_sectDirStart指向SECT #1,表示后面已经没有SECT了。这个位置代表了FAT中的第1个SECT。
0x20840xFFFFFFFEN/A_sectMiniFatStart指向SECT #2,表示后面已经没有SECT了。这个位置代表了FAT中的第2个SECT。
0x20C40x4N/A 这个位置代表了FAT中的第3个SECT。
0x2104960xFFFFFFFFN/A空闲的SECT索引。 

SECT #1:

_sectDirStart = 1, 说明这个扇区为目录区,一个目录的数据结构大小为128-byte,所以每个扇区可以包含4个目录。

Directory Entry用到的枚举类型如下:

typedef enum tagSTGTY {
  STGTY_INVALID     = 0,       // unknown storage type
  STGTY_STORAGE     = 1,       // element is a storage object
  STGTY_STREAM      = 2,       // element is a stream object
  STGTY_LOCKBYTES   = 3,       // element is an ILockBytes object
  STGTY_PROPERTY    = 4,       // element is an IPropertyStorage object
  STGTY_ROOT        = 5        // element is a root storage
} STGTY;
typedef enum tagDECOLOR {
  DE_RED            = 0,
  DE_BLACK          = 1
} DECOLOR;

 

SID 0
文件位置数据长度数据内容对应变量含义说明
0x40064L"Root Entry"_ab[32]文件夹名称,Root文件夹专用名Unicode格式的字符串,也是文件夹的名称,包含'/0',所以最长为31个字符。
0x44020x16_cb _ab[32]中实际用到的字节(byte)数,包含'/0'.
0x44215_mseSTGTY_ROOT,说明当前的Entry为Root,仅能有一个STGTY_ROOT类型文件夹类型,如STGTY_STORAGE、STGTY_STREAM
0x44311_bflagsDE_BLACKDECOLOR的枚举类型。
0x44440xFFFFFFFF_sidLeftSib没有左兄弟当前Entry的左边的兄弟节点的SID。
0x44840xFFFFFFFF_sidRightSib没有右兄弟当前Entry的右边的兄弟节点的SID。
0x44C41_sidChildSID为1的Entry为第一个子节点当前节点的子节点的SID。仅当_mse=STGTY_STORAGE or STGTY_ROOT时有效。
0x450160067 6156 54C1 CE11 8553 00AA 00A1 F95B_clsId 唯一标识符,仅当_mse=STGTY_STORAGE or STGTY_ROOT时有效.
0x46040_dwUserFlags未定义自定义标志位,仅当_mse=STGTY_STORAGE or STGTY_ROOT时有效。
0x46480000 0000 0000 0000_time[0]未设置目录创建时间,仅当_mse=STGTY_STORAGE时有效。
0x46C8801E 9213 4BB4 BA01_time[1] 目录修改时间,仅当_mse=STGTY_STORAGE时有效。
0x47443_sectStartSECT #3为数据的起始扇区。在Root中表示这个扇区存放的是MiniStreamStream的起始扇区,仅当_mse=STGTY_STREAM时有效。
0x47840x240_ulSizeLow数据的总长度。Stream的字节数,仅当_mse=STGTY_STREAM时有效。
0x47C40_ulSizeHigh 对512字节长度的扇区无效,高64位用来表示4k长度扇区的数据长度。

 

SID 1
文件位置数据长度数据内容对应变量含义说明
0x48064L"Storage 1"_ab[32]文件夹名称。Unicode格式的字符串,也是文件夹的名称,包含'/0',所以最长为31个字符。
0x4C020x14_cb _ab[32]中实际用到的字节(byte)数,包含'/0'.
0x4C211_mseSTGTY_STORAGE,说明当前的节点为Storage类型文件夹类型,如STGTY_STORAGE、STGTY_STREAM
0x4C311_bflagsDE_BLACKDECOLOR的枚举类型。
0x4C440xFFFFFFFF_sidLeftSib没有左兄弟当前Entry的左边的兄弟节点的SID。
0x4C840xFFFFFFFF_sidRightSib没有右兄弟当前Entry的右边的兄弟节点的SID。
0x4CC42_sidChildSID为2的Entry为第一个子节点当前节点的子节点的SID。仅当_mse=STGTY_STORAGE or STGTY_ROOT时有效。
0x4D0160000 0000 0000 0000 0000 0000 0000 0000_clsId 唯一标识符,仅当_mse=STGTY_STORAGE or STGTY_ROOT时有效.
0x4E040_dwUserFlags未定义自定义标志位,仅当_mse=STGTY_STORAGE or STGTY_ROOT时有效。
0x4E480000 0000 0000 0000_time[0]未设置目录创建时间,仅当_mse=STGTY_STORAGE时有效。
0x4EC80000 0000 0000 0000_time[1] 目录修改时间,仅当_mse=STGTY_STORAGE时有效。
0x4F440_sectStartSTORAGE不包含Stream,只能包含StorageStream的起始扇区,仅当_mse=STGTY_STREAM时有效。
0x4F840_ulSizeLow数据的总长度。Stream的字节数,仅当_mse=STGTY_STREAM时有效。
0x4FC40_ulSizeHigh 对512字节长度的扇区无效,高64位用来表示4k长度扇区的数据长度。

 

SID 2
文件位置数据长度数据内容对应变量含义说明
0x50064L"Stream 1"_ab[32]文件夹名称。Unicode格式的字符串,也是文件夹的名称,包含'/0',所以最长为31个字符。
0x54020x12_cb _ab[32]中实际用到的字节(byte)数,包含'/0'.
0x54212_mseSTGTY_STREAM,说明当前的节点为Stream类型文件夹类型,如STGTY_STORAGE、STGTY_STREAM
0x54311_bflagsDE_BLACKDECOLOR的枚举类型。
0x54440xFFFFFFFF_sidLeftSib没有左兄弟当前Entry的左边的兄弟节点的SID。
0x54840xFFFFFFFF_sidRightSib没有右兄弟当前Entry的右边的兄弟节点的SID。
0x54C40_sidChildStream没有子节点当前节点的子节点的SID。仅当_mse=STGTY_STORAGE or STGTY_ROOT时有效。
0x550160000 0000 0000 0000 0000 0000 0000 0000_clsId 唯一标识符,仅当_mse=STGTY_STORAGE or STGTY_ROOT时有效.
0x56040_dwUserFlags未定义自定义标志位,仅当_mse=STGTY_STORAGE or STGTY_ROOT时有效。
0x56480000 0000 0000 0000_time[0]未设置目录创建时间,仅当_mse=STGTY_STORAGE时有效。
0x56C80000 0000 0000 0000_time[1] 目录修改时间,仅当_mse=STGTY_STORAGE时有效。
0x57440_sectStart_ulSizeLow < _ulMiniSectorCutoff,所以Stream数据被放在MiniFAT中,从第0个MiniSector开始Stream的起始扇区,仅当_mse=STGTY_STREAM时有效。
0x57840x220_ulSizeLow数据长度,小于Header._ulMiniSectorCutoffStream的字节数,仅当_mse=STGTY_STREAM时有效。
0x57C40_ulSizeHigh 对512字节长度的扇区无效,高64位用来表示4k长度扇区的数据长度。

 

第三个Directory Entry为空。

 

SECT #2:

由Header._sectMiniFatStart = 2 我们知道当前SECT为MiniFAT。

MiniFAT
文件位置数据长度数据内容对应变量含义说明
0x60040x00000001N/ASID2._sectStart = 0,所以当前值为下一个MiniSector的索引当前minisector的下一个索引,下同
0x60440x00000002N/A下个MiniSector为MiniSECT #2,下同 
0x60840x00000003N/A下个MiniSECT=3 
0x60C40x00000005N/A下个MiniSECT为5 
0x61040x00000006N/A  
0x61440x00000007N/A下个MiniSECT=7 
0x61840x00000008N/A  
0x61C40xFFFFFFFFEN/A数据结束 
...... 0xFFFFFFFFFN/A空闲的索引 
      

 

 

SECT #3

SID0._sectStart指明了当前SECT为MiniStream sector。

000800:  4461 7461 2066 6F72  2073 7472 6561 6D20    Data for stream
000810:  3144 6174 6120 666F  7220 7374 7265 616D    1Data for stream
000820:  2031 4461 7461 2066  6F72 2073 7472 6561    1Data for strea
. . .
000A00:  7461 2066 6F72 2073  7472 6561 6D20 3144    ta for stream 1D
000A10:  6174 6120 666F 7220  7374 7265 616D 2031    ata for stream 1

结束

转载于:https://www.cnblogs.com/tzleo/archive/2012/04/12/2444399.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值