|
Excel 文件二进制结构分析
打哈欠
Email: akala_yahu@yahoo.com
以下内容仅供个人学习研究。未经作者同意,不得转载、刊登全部或部分内容。如有需要,请与作者联系。
序
我对 Excel 文件结构的学习研究,也是最近才开始。只是好奇,拿出改游戏的劲头与手段,一点点的啃。发觉似乎有不少人也对该文件格式感兴趣。只是很可惜,我找不到能力足够、并且愿意一起共享心得体会、共同学习的同道。
一人独行,自然倍感寂寞,兴趣的火花也就时燃时灭;再加上我人比较懒,工作忙,也难以抵御外界的种种诱惑,比如娱乐、游戏、小说等等,所以,火花也就灭的时候居多。这里就先请读者原谅,打声招呼,如果这篇文章写得太慢,或者不能最终完成,千万不要骂我。当然这是闲话了。
另外,因为没有正式的资料,既然是研究,下面的内容也可能全盘皆错。有早知早觉的大侠,想批,请随便拿砖头砸吧!
第一章 前言
一、前人的研究
能够找到的前人研究资料不多。MSDN online里有部分,可惜组织得很零散,微软也删除了重要内容。有人说 MS Office Develop 附带的MSDN Library 中有介绍,可是我没有这个东东,也无从知道讲了什么东西。如果有人有这些东西,不知是否方便发给我看看。先谢谢了!
不过,我还是按照我所知道的来写吧!
1996 年,德国人 martin Schwartz 写了一篇语焉不详的“Hacking Guide”,他研究了Word 6的存盘文件,文章里他叫这种文件结构为Laola。他认为Laola是一个文件系统,包含子目录与子文件。照搬到Excel中,根据这种思路,Excel 里的workbook、或VBA,都应该是一个子文件,微软好象叫它们OLE2 Storage,也就是说,一个 Excel 文件,包含了一个目录结构和若干个子文件,每个子文件都是一个 OLE2 Storage。我们下面就沿用martin Schwartz定义的Laola的概念。
不过,martin Schwartz最大的贡献是用 Perl 4 写了一个Package (类似于 VBA 里的类),提供了读取 Laola 文件系统的方法。(我正在用VBA重写这个Package,并增加写模块,工作忙,断断续续,所以还没写完)。
1997 年的《Excel Digest》里发表了一篇文章,作者是Guy Boertje,内容是一个读取Workbook里用户定义数字格式的VBA。他用的办法是直接在Excel文件里直接搜索Workbook BOF记录(Beginning of File,标识是Hex 0809),找到文件的起始偏移。关于这样的VBA程序,大家可以参考我的文章(读取 Excel 工作表的背景图片),发表在坛子里。因为当时还不知道Laola的概念,所以读出来的图片时对时错。
二、分析Excel 文件二进制结构的基本工具
为了简化,我们就使用三个基本工具,也大致够用了。一个是UltraEdit 32,可以16进制的形式编辑二进制文件。另外一个工具是WinHex,这个工具的主要特点是可以进行二进制比较,也可以直接编辑机器内存中的二进制数据,实在是改游戏、做 memory dump 的利器。再一个工具就是Windows中的计算器,我们可以用他来完成十进制——十六进制——和二进制的转换。
好,有了这些工具,我们就可以开始。
另外,讲三个基本常识:
1、数字的表示方式:
十进制:我们就用一般的表示方式,比如“1234”。
十六进制:表示为“Hex 1234”或“0x1234”。
二进制:表示为“Bin 1001”。
2、数字的存放顺序
数字在Intel的机器,二进制文件中是顺序存放的,比如 Hex 0809,就表示为0x09 0x08,高位在后,低位在前。
3、基本数据类型
我们主要涉及到三种数据类型,字节(Byte)、字(Word,占两个字节)和双字(Dword,四个字节),Word和Dword就相当于无符号的整型和无符号长整型。
第二章 Laola 结构
这第二章我们先研究 Laola 结构,第三章学习Workbook的结构,也就是xiaog贴出来的东西,第四章看看VBA,第五章就是Excel 文件中根据Laola概念分解出来的,其它有趣的东东;第六章,应用工具程序示例,我就想把一些读取Excel的VBA程序、以及通过ADO方式的VBA程序和C++程序归为这一章。
如果没意见,我们继续。
Excel 文件中的第一个512字节块(0x200),是Laola的初始块,从偏移0x00到0x1FF。我们先拿80字节出来学习一下。
0x00000h: D0 CF 11 E0 A1 B1 1A E1 00 00 00 00 00 00 00 00
0x00010h: 00 00 00 00 00 00 00 00 3E 00 03 00 FE FF 09 00
0x00020h: 06 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00
0x00030h: 19 00 00 00 00 00 00 00 00 10 00 00 FE FF FF FF
0x00040h: 00 00 00 00 FE FF FF FF 00 00 00 00 18 00 00 00
偏移00开始是Laola标识,“D0 CF 11 E0 A1 B1 1A E1”,表示这是一个Laola文件系统。
偏移0x18是Word,可能是小版本号,
偏移0x1a是Word,可能是版本号,一般为3。
偏移0x 1e是Word,表示块的大小,固定为9,是2的幂次(2^9为512字节)
偏移0x 20表示小文件块的大小,2^6为64字节。
好,作了一个简单的示例,我们再讲讲一些Laola中的概念。
1、初始块
就是Excel 文件中的前512个字节。这个块中数据结构的定义表我们放在本章末尾列出,在本章的各个部分我们将逐步分析这个初始块的含义。
2、大文件块文件表
大文件块文件表是存放文件块索引号的, 比如,
0x0003200: 01 00 00 00 02 00 00 00 03 00 00 00 05 00 00 00
0x0003210: FE FF FF FF 06 00 00 00 07 00 00 00 FE FF FF FF
0x0003220: 09 00 00 00 0A 00 00 00 0B 00 00 00 0C 00 00 00
0x0003230: 0D 00 00 00 0E 00 00 00 0F 00 00 00 FE FF FF FF
0x0003240: 11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00
0x0003250: 15 00 00 00 16 00 00 00 17 00 00 00 FE FF FF FF
0x0003260: FD FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
索引号从0开始编号,一个DWORD表示一个索引。
索引的取值范围:
0xFFFFFFFD:特别块
0xFFFFFFFE:索引链结束标志
0xFFFFFFFF:未使用
0… 文件块总数:索引链中的下一个元素
大文件块文件表中是按索引链的方式排列的,通过索引链我们可以将在Excel文件中若干个不连续排放的大文件块,组织起来。
比如,我们先建立一个空的大文件块列表“{}”,我们从偏移0x0003200 + 0*4 (0为索引)中取DWORD,值为1,所以把0和1放入大文件块列表中,为{0, 1};偏移0x0003200 + 1*4处数值为2,所以把2放入列表中,为{0, 1 , 2};再到偏移0x0003200 + 2*4处取数值,为3,如此往复,一直到偏移0x0003200 + 7*4,数值为0xFFFFFFFE,表示索引链结束,而大文件块列表已经为{0, 1, 2, 3, 5, 6, 7}。这样,我们就已经取得了一个应该连续排放的若干个大文件块。
(休息一会儿,待续…..)
讲两个笑话轻松一下:
一位漂亮的女孩养了一只鹦鹉,一天女孩在浴室洗澡,鹦鹉说:“看到了,看到了。”
女孩生气地对鹦鹉说:“再叫就拔光你的毛。”
第二天一位光头的客人来到家里,鹦鹉偷偷地飞到客人的肩头,悄悄地说:“你也看到了吗?”
一个人养了一只鹦鹉,非常厉害,和它关在一起的其他鸟都被它打死了。后来主人弄回来一只鹰和它搁在了一块,等主人在来看,笼子外面挂着鹦鹉的毛。主人说:“这会不牛逼了吧。”可在仔细一看。是鹰死了,鹦鹉光着个身子说:“这孙子真厉害,不脱光膀子还真打不过丫挺的。” |
|