介绍

Cache技术广泛应用于计算机行业的软硬件领域。该技术既是人们对新技术探讨的结果,也是对当前软硬件计算能力的一种妥协。在浏览器中使用cache技术,可以大幅度提高web页面的响应速度,降低数据传输延迟,提高web用户的体验。因此,客户端在浏览网页的过程中,会在本地缓存许多文件。随着使用时间增长,本地缓存的文件日渐增多。对于用户来说,查看本地主机当前的缓存文件数目和种类成为一种迫切的需要。

作为主项目的一部分功能,我们需要完成这样一个浏览器缓存查看器。在网上偶然看到了一款这样的软件:IECacheViewer。这款软件功能恰到好处,正是我们所需要的。奈何该网站上并未公布其实现方式,因此只好以该软件界面作为模板,自动动手一一实现其功能。寻寻觅觅良久之后,终于发现了两种实现方式:(1)调用windows系统提供的API。这些API使用简单,只需要循环调用即可获取Cache信息。但缺点是,该方法只能扫描当前系统中存在的cache文件信息。(2)解析index.dat文件。index.dat文件采用增量记录方法,所有在系统中曾经存在过的cache文件,在index.dat文件中都有记录。关于index.dat文件是什么,在参考资料中可以得到详尽的答案。我们将在方法二中详细剖析index.dat的结构。

方法一、调用系统API

1. 相关的API:

 1 HANDLE FindFirstUrlCacheEntry(
 2   __in          LPCTSTR lpszUrlSearchPattern,
 3   __out         LPINTERNET_CACHE_ENTRY_INFO lpFirstCacheEntryInfo,
 4   __in_out      LPDWORD lpcbCacheEntryInfo
 5 );
 6
 7 BOOLAPI FindNextUrlCacheEntry(
 8   __in          HANDLE hEnumHandle,
 9   __out         LPINTERNET_CACHE_ENTRY_INFO lpNextCacheEntryInfo,
10   __in_out      LPDWORD lpcbCacheEntryInfo
11 );
12
13 BOOLAPI FindCloseUrlCache(
14   __in          HANDLE hEnumHandle
15 );
16
17 typedef struct _INTERNET_CACHE_ENTRY_INFO  {
18  DWORD dwStructSize;
19  LPTSTR lpszSourceUrlName;
20  LPTSTR lpszLocalFileName;
21  DWORD CacheEntryType;
22  DWORD dwUseCount;
23  DWORD dwHitRate;
24  DWORD dwSizeLow;
25  DWORD dwSizeHigh;
26  FILETIME LastModifiedTime;
27  FILETIME ExpireTime;
28  FILETIME LastAccessTime;
29  FILETIME LastSyncTime;
30  LPBYTE lpHeaderInfo;
31  DWORD dwHeaderInfoSize;
32  LPTSTR lpszFileExtension;
33  union {    DWORD dwReserved;    DWORD dwExemptDelta;  };
34 } INTERNET_CACHE_ENTRY_INFO, *LPINTERNET_CACHE_ENTRY_INFO;

FindFirstUrlCacheEntry()函数开始枚举Cache信息。其返回一个句柄,该句柄用于所有后续的FindNextUrlCacheEntry()调用。FindCloseUrlCache()函数用户关闭句柄,结束枚举过程。利用上述的三个函数,循环调用并将Cache信息保存在INTERNET_CACHE_ENTRY_INFO结构体中。INTERNET_CACHE_ENTRY_INFO结构体包含了当前Cache文件的详细信息,如文件大小、命中次数、访问时间、修改时间、同步时间等。这样,就可以完成IE Cache信息的提取了。

方法二、 解析index.dat文件

1. 文件结构

如果解析PE文件一样,在解析index.dat文件之前,我们需要知道index.dat文件的组织结构。网上并没有找到index.dat文件的结构说明,只能依着搜到的几个结构体定义来查看index.dat的结构了。大致示意图如下:

一个index.dat文件以small header开始,该small header占0x250个字节,其结构定义如下:

其中最重要的字段是dwHashTableOffset,该字段是DWORD型,在32位机器上占4个字节。dwHashTableOffset保存了index.dat文件中的第一个hash section的地址。nDirCount和DirArray字段分别表示子目录个数和子目录名称数组。通常对于Cache来说,所有的缓存文件都放在一个目录中,这两个字段作用不大。而对于Cookie来说,Cookies文件可能分布于多个子目录中。跟在Small header后面的是full header。其具体作用不详,定义如下:

再来看Hash Section部分。每个hash section都有一个头部,占16个字节。其定义如下:

hash头部的dwSig字段占4字节,是由“HASH”这个四个字母的ASCII码填充的。nBlocks字段表明本哈希节占用多少个块,块单位为0x80字节。dwNext字段指出下一个hash 头部的开始地址,以index.dat文件的起始地址为基准。nOrder则是当前哈希节的编号。紧随头部的便是hash itmes了。一个hash item占8字节,前4字节是哈希值,后4字节是Cache记录在index.dat文件中的偏移,也是以index.dat文件的起始地址为基准

2. 分析实例

下面以我的机器上的index.dat文件为例进行实例分析:

根据第一个哈希表的偏移地址(0x4000),跳到0x4000处,如下:

可以看到,hash头部第一个字段为:48, 41, 53, 48.为"HASH"四个字母。紧接着的四个字节值为0x20,单位为块,每块大小为128字节。值得注意的是,由于我使用的是小端机(little endian:大端高位在前,小端低位在前),因此需要转换一下。第三个四字节值为0x11000,是下一个hash section的头部地址。第四个四字节值为0,表明当前hash section的编号为0。我们再接着看0x4010位置的值。根据上述的结构定义可知,第一个四字节是哈希值,不用管它。接下来的0x1BA00才是最重要,它指明了hash条目在文件中的偏移位置。注意相对的偏移基准。我们再跳到0x1BA00位置:

这是一个URL类型。在index.dat文件中,hash条目有多种类型,在参考资料中有说明,这里不再赘述。不过,我们应当重点看看hash条目的定义结构:

按着字段大小一一提取即可。到这里,完成了一次cache信息的提取。我们接着要做的,是查看下一个hash section。因此,再跳到0x11000处:

当前编号为1,下一个hash section 在0x23000处。再跳到0x23000看看:

果然,此时下一个hash section 的地址为0,表明这是最后一个section了。当前编号为2.由此可知,这个index.dat文件中只有3个section。所有的hash条目都可以依此提取出来。值得注意的是hash section中存在着空洞。如遇到两个字段都为3或者1,表明这是一个空洞。如下图所示,继续查看,仍然有hash条目存在。当遇到两个字节都是0xDEADBEEF,说明后面不再有hash条目了。

预览效果

参考资料

  1. Windows 中 Cookie、Internet Temp Files、History、Temp Directory 具体路径(2000、Xp、Vista、Win7)
  2. 很好的文章:index.dat的分析(也详细介绍了cookie)
  3. A few words about the cache / history on Internet Explorer 10
  4. Index.Dat Files and Primary I.E. Folders
  5. Understanding Microsoft Internet Explorer Cache
  6. Reading the Internet Explorer Cache
  7. Exploring the URL Cache
  8. Internet Explorer History File Format

代码

View it on github.

用Qt写软件系列一:QCacheViewer(浏览器缓存查看器)相关推荐

  1. 用Qt写软件系列六:博客园客户端的设计与实现(1)

    引言 博客园是本人每日必逛的一个IT社区.尽管博文以.net技术居多,但是相对于CSDN这种业务杂乱.体系庞大的平台,博客园的纯粹更得我青睐.之前在园子里也见过不少讲解为博客园编写客户端的博文.不过似 ...

  2. 用Qt写软件系列五:一个安全防护软件的制作(2)

    引言 在上一篇中讲述了主窗体的创建和设计.主窗体的无边框效果.阴影效果.拖动事件处理.窗体美化等工作在前面的博客中早就涉及,因此上篇博文中并未花费过多笔墨.这一篇继续讲述工具箱(Tool Button ...

  3. Python 写一个命令行版的火车票查看器

    用python另一个抢票神器,你get到了吗? 2017年时间飞逝,转眼间距离2018年春节还有不到1个月的时间,还在为抢不到火车票发愁吗?作为程序员的我们撸一个抢票软件可好? 难以想象的数据, 预示 ...

  4. 【React组件】写一个模仿蓝湖的图片查看器

    前言 最近公司让写一个可以自由拖拽放大的图片查看器,我寻思这还不简单,一顿操作猛如虎,俩小时后: 事实证明,一旦涉及到 DOM 的变换操作,如果很多细节考虑不全,抓过来就写,那基本就凉了.于是我仔细分 ...

  5. 分享一款 浏览器密码查看器

    前言 最近看到一款 很好用的 浏览器 站点,用户名,密码查看器, 很厉害,看了之后,我真的意识到了 网络让这个世界没有了秘密和隐私. 软件下载地址 WebBrowserPassView 提取码:p6x ...

  6. PHP中ob系列函数讲解(浏览器缓存技术)

    Output Control 函数可以让你自由控制脚本中数据的输出.它非常地有用,特别是对于:当你想在数据已经输出后,再输出文件头的情况. 输出控制函数不对使用 header() 或 setcooki ...

  7. 【Android软件】ES文件浏览器:Android资源管理器

    ES文件浏览器是一个能管理手机本地.局域网共享.FTP和蓝牙文件的管理器.通过ES 文件浏览器用户可以在本地.局域网共享.FTP和蓝牙设备中浏览.传输.复制.剪切.删除.重命名文件和文件夹等等,还可以 ...

  8. 【QT学习】制作一个简单的图片查看器(完整源码)

  9. 如何不让浏览器读取html缓存,不让浏览器缓存index.html

    参考文档:https://www.2cto.com/ask/question/4598 location = /index.html { add_header Cache-Control " ...

最新文章

  1. .net面试问题汇总(转)
  2. 使用vim保存权限不够的文件
  3. Angular CLI 全局 ng.cmd 文件内容分析
  4. leetcode-深度优先搜索
  5. 大号字代码php,如何用QQ发超大汉字_php
  6. Asp.net SQL注入实例分享
  7. ArcGIS利用DEM提取河流水系(附练习数据下载)
  8. 关乎未来40年企业生存,这些食品饮料巨头都在干这件事儿! | 商研局 Cool Business...
  9. OpenLayers实战(四)控制图标显示隐藏
  10. 劳动节纪念——叹苦逼码农之古诗今改几篇汇总
  11. 环球旅行之江西分会场
  12. 求最大公约数及求多个数的最大公约数
  13. 根据简化真值表绘制电路
  14. 全球地名中英文对照表(Q-R)
  15. 刘润:讲讲我价值几千万的认知,从“愚昧之巅”到“绝望之谷”
  16. 几种编程语言类型的区分
  17. 7-10 小字辈 (25分)
  18. 随机神经网络之玻尔兹曼机
  19. (六) 更新glibc版本
  20. linux系统 ghost吗,GHOST能于LINUX系统备份吗?

热门文章

  1. AI变革下的“百度一下”
  2. AI给你安利了一个职位,猜猜它觉得你适合做什么?
  3. 明略数据(现在)是一家怎样的公司?
  4. 一文看尽苹果WWDC大会:今年有亮点,但都不“硬”
  5. 【云周刊】第173期:直击数博|阿里胡晓明:用100亿的投入撬动1000亿的脱贫效应...
  6. Cocos2d-X开发中国象棋《三》開始场景的实现
  7. EL表达式、 jstl标签
  8. 优化案例--改写IN条件为INNER JOIN
  9. sql练习三(DataWhale 系列-最终)
  10. Mimikatz 非官方指南和命令参考_Part1