在Windows
C:\Windows\History\History.IE5\index.dat
C:\Windows\Temporary
而在Window2000/XP系统中,index.dat一般会存在于下面的位置中: C:\Documents
C:\Documents
C:\Documents
\Temporary
在win7\vista系统中,index.dat一般会存在于下面的位置中:
C:\Users\Toshiba\AppData\Local\Microsoft\Windows\
History\History.IE5\index.dat;
这些index.dat文件是系统、隐藏的文件,它们不随IE浏览器中的cookies值、临时文件和历史记录的清除而删除——这就是它的可怕之处。下面来详细描述index.dat文件的结构。
二.Index.dat文件结构
Index.dat文件分为两部分,头部分和条目(Entry)部分。
所谓头部分,顾名思义就是文件开始部分。它记录着这个文件的总的信息,如文件文件格式版本、大小、子文件夹等等。每个index.dat文件仅有一个头部分。
其余的部分都是条目部分。Index.dat中的各种类型的条目数据结构不同,不过每个条目的前8个字节结构相同,系统就是用这两个DWORD字段来区分条目类型的。
下面我们来具体分析一下各个部分:
1.头部分
index.dat的头部大小是固定的,为16K。其开始592个字节(0x250)为小(SMALL)的头部分。紧接着的空间是3948个DWORD,它用来作为分配MAP。数据结构如下:
{
};
typedef
{
TCHAR
}
typedef
{
}
2.各种条目结构
上文说过每个条目都是以同样结构的2个DWORD开始的,这个结构如下:
{
}
dwSig用来标识各种类型的标识。
表示字 | 值 | 说明 |
SIG_FREE | 0xbadf00d | 本条目空闲,只有此类条目没有nBlocks成员。 |
SIG_ALLOC | 0xdeadbeef | 已分配 |
SIG_URL | ' LRU' | URL值 |
SIG_REDIR | 'RDER' | REDIR |
SIG_LEAK | 'KAEL' | LEAK |
SIG_GLIST | 'GLST' | GLIST |
SIG_HASH | 'HSAH' | 哈希表 |
关于各种条目的结构我们下面会详细说明。
nBlocks用来描述此条目所占用的块数。注意index.dat中的块大小为128字节。
2.1哈希表条目
现在开始说明各种类型的条目。为什么先要说哈希表呢?这是因为index.dat使用一个哈希表链来作为目录,从而能够快速找到指定名称的条目。
Index.dat文件中每个哈希表大小都不能超过一个内存分页,即不能超过4K大小。每个哈希表部分是由下面的结构开始的,同时系统也是利用了这个结构,将index.dat中所有的哈希表部分链接起来的。
{
};
紧接着这个结构就是一个哈希表,每个哈希表的关键是哈希函数,下面是这个哈希表的哈希函数:
{
}
经过这个函数产生的值,根据其低6位就是最终的数组行号(即相当于模64)。
由于解决冲突的方法是:对同一个哈希地址提供7个位置空间。于是呈现在我们眼前是实际上就是一个横向7列、纵向64行的表结构:
位置0 | 位置1 | 位置2 | …… | 位置6 | |
哈希地址0 | | | | | |
1 | | | | | |
… | | | | | |
… | | | | | |
63 | | | | | |
从这样的表结构中,我们知道这个哈希表以64为模。每个表允许7个相同值,它们按顺序排列在一起。所以每个哈希表结构可以索引448(64×7)个条目。
下面就是每个元素的结构:
{
};
我们注意到了:数组元素的哈希值的低6为0。于是系统也是利用了这个特征,将这6位数用作了每个元素的格式表示:
#define
#define
#define
#define
#define
//
#define
#define
#define
#define
#define
#define
#define
#define
URL条目是使用的最多的条目。它的结构和LEAK条目的结构相同,如下:
{
DWORD
};
2.4
struct
{
};
2.5
{
};
三.显示系统缓存信息
上面就是一个完整的index.dat文件的结构,利用这些结构我们就可以写出一个完整显示系统缓存信息的程序。这项非常琐碎的工作,于是微软专门提供了一个函数库——WinInet。利用这个库中的函数,程序员可以相当方便地取出系统中缓存中的信息。
关于WinInet库的使用方法网络上有很多文章,大家可以参阅。
1.
2.
上面我们分析了index.dat文件的结构,那么系统在什么时候读写这个文件的信息呢?
1.COOKIES存取
在用户用IE浏览器上网时,当开始输入一个网址后,IE会根据输入的网址、用户名等信息组成一个字符串,将这个字符串作为参数到哈希函数中产生一个哈希值,然后查找具体的URL实体。如果能够找到,那么IE就会具体分析此URL实体指定的COOKIES.TXT文件,看是否已经过期,若已经过期则删除;否则将在IE生成的HTTP请求报文中加上一个cookies:××××××(×××就是.txt文件中的信息)这样的请求头部。
在IE浏览器收到的HTTP响应报文中若响应头部中包含有Set-cookies:×××××信息时,此时IE就会将这个COOKIES值保存在一个.txt文件中,并在index.dat文件中建立一个索引值。
2.临时的缓存文件存取
临时缓存文件是一种客户端缓存技术,它有利于节省网络带宽资源并能加快浏览速度。每次使用IE浏览器上网时,IE会发送一个请求报文要求传输一个文件(比如.htm文件、.jpg文件、.css文件等等)。WEB服务器响应请求,将所要求的文件传输给IE.。IE在显示这个文件的同时,会将它放到缓存目录中,并在Index.dat文件中添加索引。
等下次,IE要求传输相同的文件时,IE便会在index.dat中找到这个文件的记录了(当然,如果根本没有传输下载过,index.dat中是不会找到这个记录的)。IE先检查这个文件是否已经过期了(WEB服务器会在响应某些文件请求时,在HTTP响应报文中添加一个响应头部Age:×××××来明确表示这个文件在客户机上保存的时间)。如果没有过期,IE便会直接利用这个缓冲文件而不会发送HTTP请求报文的。
如果没有明确的过期时间或者已经过期来,IE便会在发送的HTTP请求报文中加上一条请求头部If_modified-since:××××。而WEB服务器发现所要求的文件并没有改变,它便会发送一个304
3.历史记录
历史记录只是用来保存曾经浏览过的网页的网址。它并不保存其他的一些信息。也不和发送/接受HTTP协议有关。所以比较简单。
五.举例说明
理论说了很多,下面来举一个例子。通过这个例子我们看看系统是这样使用使用index.dat来索引缓存的以及系统是怎样使用缓存的。
1.环境
一台装有WEB浏览器的客户机,一台IP地址为90.0.0.6的IIS5的WEB服务器。服务器有一个名为test.asp的网页。test.asp包含一张图,并会设置一个cookies。
2.第一次调用网页
过程如下图所示:
![ie <wbr>index.dat <wbr>文件剖析(三) 单击显示全图,Ctrl+滚轮缩放图片](http://www.chenjiliang.com/Article/ArticleImage/80/2777/IndexDat1.jpg)
具体的HTTP报文如下:
请求报文 | 回应报文 |
GET /test.asp HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms- powerpoint, application/msword, ** Referer: http://90.0.0.6/test.asp Accept-Language: en Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) Host: 90.0.0.6 Connection: Keep-Alive Cookie: name=xiaoming; ASPSESSIONIDASARBACA=NOMPFILDEICPMBJBKCDGKGDC | HTTP/1.1 200 OK Server: Microsoft-IIS/5.0 X-Powered-By: ASP.NET Date: Thu, 26 Oct 2006 06:43:45 GMT Content-Type: image/gif Accept-Ranges: bytes Last-Modified: Sun, 15 Oct 2006 15:54:58 GMT ETag: "075bc 4372f0c61:19f8" Content-Length: 66806 |
我们再来看一下,index.dat文件有什么变化呢?
1)临时缓存文件
首先我们计算1.gif文件的HASH值。URL名称为:http://90.0.0.6/img/1.gif
00005150h: 01 00 00 00 00 9F 03 00 01 00 00 00 00 FD 03 00 ; .....?......?.
00005160h: 40 53 7F 12 80 66 00 00 40 E7 8F A7 80 F2 01 00 ; @S.€f..@鐝?.
00005170h: C0 68 1D 59 80 1B 03 00 01 00 00 00 00 48 03 00 ; 纇.Y€........H..
00005180h: 01 00 00 00 00 6C 0E 00 01 00 00 00 00 93 03 00 ; .....l.......?.
00005190h: 01 00 00 00 00 B6 03 00 C0 48 BE F4 00 D0 00 ; .....?.繦爵.?
发现5160h处就是我们要找的HASH_ITEM。于是我们在0X6680处找到我们要找的URL条目。
00006680h: 55 52 4C 20 03 00 00 00 00 75 BC 43 72 F0 C6 01 ; URL .....u糃r鹌.
00006690h: 50 AC 0D 1D CC F8 C6 01 00 00 00 00 00 00 00 00 ; P?.跳?........
000066a0h: F6 04 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ?..............
000066b0h: 60 00 00 00 68 00 00 00 05 01 10 10 84 00 00 00 ; `...h.......?..
000066c0h: 41 00 00 00 90 00 00 00 82 00 00 00 00 00 00 00 ; A...?..?......
000066d0h: 5A 35 49 37 02 00 00 00 00 00 00 00 5A 35 02 35 ; Z5I7........Z5.5
000066e0h: 00 00 00 00 0D F0 AD 0B 68 74 74 70 3A 2F 2F 39 ; .....瓠.http://9
000066f0h: 30 2E 30 2E 30 2E 36 2F 69 6D 67 2F 31 2E 67 69 ; 0.0.0.6/img/1.gi
00006700h: 66 00 AD 0B 31 5B 31 5D 2E 67 69 66 00 F0 AD 0B ; f.?1[1].gif.瓠.
00006710h: 48 54 54 50 2F 31 2E 31 20 32 30 30 20 4F 4B 0D ; HTTP/1.1 200 OK.
00006720h: 0A 58 2D 50 6F 77 65 72 65 64 2D 42 79 3A 20 41 ; .X-Powered-By: A
00006730h: 53 50 2E 4E 45 54 0D 0A 43 6F 6E 74 65 6E 74 2D ; SP.NET..Content-
00006740h: 54 79 70 65 3A 20 69 6D 61 67 65 2F 67 69 66 0D ; Type: image/gif.
00006750h: 0A 45 54 61 67 3A 20 22 30 37 35 62 63 34 33 37 ; .ETag: "075bc437
00006760h: 32 66 30 63 36 31 3A 31 39 66 38 22 0D 0A 43 6F ; 2f0c61:19f8"..Co
00006770h: 6E 74 65 6E 74 2D 4C 65 6E 67 74 68 3A 20 36 36 ; ntent-Length: 66
00006780h: 38 30 36 0D 0A 0D 0A 7E 55 3A 71 67 6D 69 73 0D ; 806....~U:qgmis.
00006790h: 0A 00 AD 0B 0D F0 AD 0B 0D F0 AD 0B 0D F0 AD 0B ; ..?.瓠..瓠..瓠.
000067a0h: 0D F0 AD 0B 0D F0 AD 0B 0D F0 AD 0B 0D F0 AD 0B ; .瓠..瓠..瓠..瓠.
000067b0h: 0D F0 AD 0B 0D F0 AD 0B 0D F0 AD 0B 0D F0 AD 0B ; .瓠..瓠..瓠..瓠.
000067c0h: 0D F0 AD 0B 0D F0 AD 0B 0D F0 AD 0B 0D F0 AD 0B ; .瓠..瓠..瓠..瓠.
000067d0h: 0D F0 AD 0B 0D F0 AD 0B 0D F0 AD 0B 0D F0 AD 0B ; .瓠..瓠..瓠..瓠.
000067e0h: 0D F0 AD 0B 0D F0 AD 0B 0D F0 AD 0B 0D F0 ; .瓠..瓠..瓠..
分析这个结构,FILEMAP_ENTRY分析如下:
地址 | 成员 | 值 | 说明 |
00006680h | dwSig | 55 52 4C 20 | URL |
00006684h | nBlocks | 02 00 00 00 | 此条目占据2×128=256个字节 |
IE5_URL_FILEMAP_ENTRY分析如下:
地址 | 成员 | 值 | 说明 |
00006680h | LastModifiedTime | 75 BC 43 72 F 0 C 6 01 | 最后修改时间:2006-10-15 |
| LastAccessedTime | 50 AC 0D 1D CC F8 C6 01 | 最后存取时间:2006-10-26 |
| dostExpireTime | 00 00 00 00 | |
| dostPostCheckTime | 00 00 00 00 | |
| dwFileSize | F6 04 01 00 | 硬盘缓存的文件大小0x104F6 |
| dwRedirHashItemOffset | 00 00 00 00 | |
| dwGroupOffset | 00 00 00 00 | |
| dwExemptDelta | 00 00 00 00 | |
| CopySize | 60 00 00 00 | |
| UrlNameOffset | 68 00 00 00 | URL 地址保存在偏移为0X68即0X66E8的位置处。 (http://90.0.0.6/img/1.gif) |
| DirIndex | 05 | 硬盘文件子目录序号为:05 |
| bSyncState | 01 | |
| bVerCreate | 10 | |
| bVerUpdate | 10 | |
| InternalFileNameOffset | 84 00 00 00 | 硬盘缓存文件名保存在偏移为0X84即0X6704的位置处。 (1[1].gif) |
| CacheEntryType | 41 30 00 00 | |
| HeaderInfoOffset | 90 00 00 00 | HTTP 首部信息保存在偏移为0X90即0X6710的位置处。 (HTTP/1.1 200 OK X-Powered-By: ASP.NET Content-Type: image/gif ETag: "075bc4372f0c61:19f8" Content-Length: 66806 |
| HeaderInfoSize | 82 00 00 00 | HTTP 首部信息大小。 |
| FileExtensionOffset | 00 00 00 00 | |
| dostLastSyncTime | 5A 35 49 37 | 最后同步时间为: 2006-10-26 |
| NumAccessed | 02 00 00 00 | 存取3次 |
| NumReferences | 00 00 00 00 | |
| dostFileCreationTime | 5A 35 02 35 | 文件建立时间 |
我们用同样的方法分析test.asp在index.dat中保存成test[1].htm的索引信息。同样也可以分析cookies的index.dat的索引信息。
经过了一次访问后,IE会将所有的访问过的文件放入缓存中,并在index.dat作索引。待第二次访问同样的网页时,将会出现什么情况呢?
3.第二此调用网页
当我们再次浏览这个网页的时候。我们来看看发生了什么情况。
![ie <wbr>index.dat <wbr>文件剖析(三) 单击显示全图,Ctrl+滚轮缩放图片](http://www.chenjiliang.com/Article/ArticleImage/80/2777/IndexDat2.jpg)
下面是它们的HTTP报文信息。
请求报文 | 回应报文 |
GET /test.asp HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, ** Referer: http://90.0.0.6/test.asp Accept-Language: en Accept-Encoding: gzip, deflate If-Modified-Since: Sun, 15 Oct 2006 15:54:58 GMT If-None-Match: "075bc4372f0c61:19f8" User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) Host: 90.0.0.6 Connection: Keep-Alive Cookie: name=xiaoming; ASPSESSIONIDASARBACA=OOMPFILDPDCEKPECJOOCPJEP | HTTP/1.1 304 Not Modified Server: Microsoft-IIS/5.0 Date: Thu, 26 Oct 2006 07:01:33 GMT X-Powered-By: ASP.NET ETag: "075bc4372f0c61:19f8" Content-Length: 0 |
我们发现第二次访问时,1.gif文件根本不需要再次传输。因为服务器端这个文件根本没有变化过。于是IE就直接从index.dat索引文件中找到1.gif文件保存在硬盘上的位置后,就直接使用它了——这就是系统使用缓存的最终目的了。
4.题外话
说说上面这些报文的一些题外话。
1)
2)
六.总结
本文主要剖析了Windows中用来索引缓存文件、cookies文件和上文记录的Index.dat文件,并给了例题。本文主要在分析微软代码的基础的得出的,但是对于index.dat文件中的一些结构中的特殊字段不能正确得出其含义,非常遗憾,希望有爱好者能完成。