预备

继上篇《浏览器缓存查看器QCacheViewer》之后,本篇开始QCookieViewer的编写。Cookie技术作为网站收集用户隐私信息、分析用户偏好的一种手段,广泛应用于各大网站。对于网站的精准营销、使用反馈、数据挖掘等具有不可估量的作用。Cookie按照创建者的不同,分成两类:服务端创建的Cookie和客户端浏览器创建的Cookies。那么,作为用户想要查看当前主机的Cookies文件该怎么办呢?最简单的办法是:直接到Windows目录下去找!Cookies文件是以ASCII码字符的形式保存的,因此可以直接用记事本打开查看。然而,由于Cookies文件是以Unix风格换行的,格式非常难看。QCookieViewer为Cookies提供了一个界面友好的查看工具。

这款软件还是部分借鉴于IECookiesViewer。因此,我们还是先看看这款软件的界面:

可以看到,该软件主界面分成上下两栏。上面一栏是当前所有Cookies文件的列表,下面一栏是选中的Cookies文件中的Cookie项。上面一栏的各项信息可以通过解析index.dat文件得到,这个解析过程在上一篇中就已经说到;下面一栏的内容则需要通过解析Cookie文件来得到。上面我们已经知道,Cookies文件中的每一行都是以unix换行符分割的。因此,解析Cookie文件是一个非常简单的过程。然而,我们显然注意到在下面一栏的最右侧有一个Created In列。仅仅靠解析Cookie文件,是无法得到这样的信息的。怎样完成这个功能,下面将有详细叙述。

关键技术

  1. 为什么不遍历Cookie文件夹

    在上一篇中我们说过,仅仅靠遍历Cache文件夹中的文件来获取Cache文件清单是不可行的。因为那只能获得文件名、文件大小等基本信息,我们需要的不仅仅是这些。另外,使用Windows系统提供的API的话,也具有一定的局限性。通过解析index.dat文件,我们获取更为详尽的信息。不但能够得到当前主机存在的Cookies文件信息,还可以查看到该主机曾经存在过的Cookies文件。因此,我们仍然采用了解析index.dat文件的方法。

  1. index.dat文件的位置

    • 对于Windows XP/2000而言, Cookies文件保存在:C:/Documents and Settings/Administrator/Cookies/ 
    • 对于Windows Vista/7而言,Cookies文件保存在:C:/Users/Administrator/AppData/Roaming/Microsoft/Windows/Cookies/(low/)。该目录会根据权限的不同而不同。
  2. 内存文件映射 
    • index.dat文件采用增量记录方式。因此,index.dat文件会随着使用时间的增加而不断增大。为了提高文件IO速度,我们采用了Windows系统的内存文件映射功能,将整个index.dat文件映射到内存中进行操作。代码如下:
    •  CookieHelper::CookieHelper(void)
      {
      // Need to be fixed
      const char* fileName = "C:\\Documents and Settings\\Administrator\\Cookies\\index.dat";
      // create a kernel file object
      m_hFile = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_READONLY, NULL);
      if (m_hFile == INVALID_HANDLE_VALUE)
      {
      MessageBoxA(NULL, "Error", "Can't open the index.dat file.", MB_OKCANCEL);
      return;
      } // create a kernel file mapping object
      m_hMapping = CreateFileMappingA(m_hFile, NULL, PAGE_READONLY, , , NULL);
      if (m_hMapping == NULL)
      {
      MessageBoxA(NULL, "Error", "Can't create file mapping object.", MB_OKCANCEL);
      CloseHandle(m_hFile);
      m_hFile = NULL;
      return ;
      } m_startAddr = (LPSTR)MapViewOfFile(m_hMapping, FILE_MAP_READ, , , );
      if (m_startAddr == NULL)
      {
      MessageBoxA(NULL, "Error", "Can't mappping the index.dat file.", MB_OKCANCEL);
      CloseHandle(m_hFile);
      m_hFile = NULL;
      CloseHandle(m_hMapping);
      m_hMapping = NULL;
      return;
      }
      }

      我们将index.dat文件映射到内存中使用完之后,须得及时关闭前面得到的内存句柄。否则可能导致资源泄漏。 

  3. 解析index.dat文件
    • 解析index.dat文件的过程自不必说了,在上一篇中我们已经详细阐述过了。唯一需要注意的是,解析得到的字段和上一篇中的有所出入。  
  4. Cookie文件的格式
    • Cookies文件内容以ASCII码字符保存,其格式也不算复杂。在一个Cookie文件中,可能存在多条Cookie记录。每条Cookie记录都包含9个字段,如下所示:
    • 每个字段自成一行,以unix换行分隔符分割。每一条Cookie记录又以星号(*)进行分割。这些字段的具体含义不必再赘述了。值得注意的是,这里的时间转换需要注意顺序。在参考资料4中,作者把时间的高地位写反了,导致转换得到的时间错的离谱。另外需要注意的一个字段是Optional flags。这个字段到底包含哪些options,并没有详细的文档说明。 
  5. 关于Created In列
    • 如何确定Cookies文件的Creator,起初并没有一个很好的思路。反复查看了每条Cookie记录中Optional flags字段,并比照IECookiesView工具中Created In列之后,我们发现了一个特定的规律:当Optional flags字段出现的值为1024,1536, 9216, 9728, 2147484672(不完全统计)时,IECookieView显示该Cookie由Server创建;当值为1600,1088(不完全统计)时,IECookieView显示该Cookie由Client创建。由此,我们得到一条统计规律:当optional flags值能被0x100整除时,该cookie由server端创建;否则该Cookie是由client端创建的。至于具体的规则如何,由于并没有找到说明文档,不敢妄下结论。

界面设计

由于尚未开始研究Qt的CSS技术,无暇顾及界面的美化工作。界面显示的是Windows XP经典主题,因此看起来较为朴素简陋。

 

代码

  代码全部托管于GitHub,README有更详细的说明。

参考资料

  1. NirSoft
  2. Forensic Analysis of Internet Explorer Activity Files.pdf
  3. 《index.dat文件结构解析》,吴清,吴顺祥.
  4. Cookie文件说明及IE的Cookie文件格式

用Qt写软件系列二:QCookieViewer(浏览器Cookie查看器)的更多相关文章

  1. 用Qt写软件系列三:一个简单的系统工具(上)

    导言 继上篇<用Qt写软件系列二:QIECookieViewer>之后,有一段时间没有更新博客了.这次要写的是一个简单的系统工具,需求来自一个内部项目.功能其实很简单,就是查看当前当前系统 ...

  2. 用Qt写软件系列一:QCacheViewer(浏览器缓存查看器)

    介绍 Cache技术广泛应用于计算机行业的软硬件领域.该技术既是人们对新技术探讨的结果,也是对当前软硬件计算能力的一种妥协.在浏览器中使用cache技术,可以大幅度提高web页面的响应速度,降低数据传 ...

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

    引言 又有许久没有更新了.Qt,我心爱的Qt,为了找工作不得不抛弃一段时间,业余时间来学一学了.本来计划要写一系列关于Qt组件美化的博文,但是写了几篇之后就没坚持下去了.技术上倒是问题不大,主要是时间 ...

  4. 用Qt写软件系列四:定制个性化系统托盘菜单

    导读 一款流行的软件,往往会在功能渐趋完善的时候,通过改善交互界面来提高用户体验.毕竟,就算再牛逼的产品,躲藏在糟糕的用户界面之后总会让用户心生不满.界面设计需综合考虑审美学.心理学.设计学等多因素, ...

  5. 用Qt写软件系列三:一个简单的系统工具之界面美化

    前言 在上一篇中,我们基本上完成了主要功能的实现,剩下的一些导出.进程子模块信息等功能,留到后面再来慢慢实现.这一篇来讲述如何对主界面进行个性化的定制.Qt库提供的只是最基本的组件功能,使用这些组件开 ...

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

    引言 上一篇中讲述了工具箱的添加.通过一个水平布局管理器,我们将一系列的工具按钮组合到了一起,完成了工具箱的编写.本文在前面的基础上实现窗体分割效果.堆栈式窗口以及Tab选项卡. 窗体分割 窗体分割是 ...

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

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

  8. tensorflow笔记(五)之MNIST手写识别系列二

    tensorflow笔记(五)之MNIST手写识别系列二 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7455233.html ...

  9. windows server 2008 R2安装图片浏览器/照片查看器方法

    有用户的电脑安装了windows server 2008 R2,浏览大量图片时很不方便,因为系统中没有照片查看器或图片浏览器.其实,win2008 R2是有照片查看器的,只是默认情况下没有开启.参考以 ...

随机推荐

  1. Scala 具体的并行集合库【翻译】

    原文地址 本文内容 并行数组(Parallel Array) 并行向量(Parallel Vector) 并行范围(Parallel Range) 并行哈希表(Parallel Hash Tables ...

  2. [转]java byte 数据类型(基础)

    package com.suypower.chengyu.test; public class ByteTest { /** * byte 8 bits -128 - + 127 * 1 bit = ...

  3. ASP.NET 4.5 和 Visual Studio 2012 中的新功能

    原文地址:http://www.asp.net/aspnet/overview/aspnet-and-visual-studio-2012/whats-new#_Toc318097372

  4. 杀死O2O的三大杀手?!

    0个O2O领域,20多个“已故”项目,三种不同的死因……记者糜丰.孙锋将O2O项目的一些固有问题分析得淋漓尽致! 这三个O2O杀手分别是:买不起的流量.承担不起的物流成本.惹不起的传统企业. 除了找钱 ...

  5. Go 若干技巧

    此文来自 http://denvergophers.com/2013-09/tips-and-tricks.slide ###本文主要涉及到: 1. formatting 技巧 2. 异常处理技巧 3 ...

  6. gulp前端自动化构建工具使用

    (1)新建项目目录gulp_web (2)项目目录下建目录src里面存放需要进行gulp处理的文件目录及文件 (3)gulpfile.js文件内容为声明需要打包应用的gulp组件及打包文件路径和打包任 ...

  7. [GraphQL] Use GraphQL's Object Type for Basic Types

    We can create the most basic components of our GraphQL Schema using GraphQL's Object Types. These ty ...

  8. Ubuntu14.04安装中文输入法以及解决Gedit中文乱码问题

    1 设置中文显示环境 1. 打开System Settings 2. 打开Personal-> Language Support. 会弹出如下对话框,提示你“语言支持没安装完整”. 点击“Rem ...

  9. 构建基于WinRT的WP8.1 App 02:数据绑定新特性

    基于WinRT的Windows Phone 8.1以及Windows 8.1中Xaml数据绑定增加了一些新特性. FallBackValue属性:FallBackValue在绑定的值属性值不存在时,可 ...

  10. JavaScript - javascript 中的 "||" 与 "&&" 的理解与灵活运

    你肯定见到过这样的代码:a = a||"xxx". 它其实就等价于下面三种形式的代码: a = a || "xxx"; 与: if (!a) { a = &qu ...