• 用Qt写软件系列二:QCookieViewer(浏览器Cookie查看器)


    预备

        继上篇《浏览器缓存查看器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文件映射到内存中进行操作。代码如下:
      •  1 CookieHelper::CookieHelper(void)
         2 {
         3     // Need to be fixed
         4     const char* fileName = "C:\Documents and Settings\Administrator\Cookies\index.dat";
         5     // create a kernel file object
         6     m_hFile = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_READONLY, NULL);
         7     if (m_hFile == INVALID_HANDLE_VALUE)
         8     {
         9         MessageBoxA(NULL, "Error", "Can't open the index.dat file.", MB_OKCANCEL);
        10         return;
        11     }
        12 
        13     // create a kernel file mapping object
        14     m_hMapping = CreateFileMappingA(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        15     if (m_hMapping == NULL)
        16     {
        17         MessageBoxA(NULL, "Error", "Can't create file mapping object.", MB_OKCANCEL);
        18         CloseHandle(m_hFile);
        19         m_hFile = NULL;
        20         return ;
        21     }
        22 
        23     m_startAddr = (LPSTR)MapViewOfFile(m_hMapping, FILE_MAP_READ, 0, 0, 0);
        24     if (m_startAddr == NULL)
        25     {
        26         MessageBoxA(NULL, "Error", "Can't mappping the index.dat file.", MB_OKCANCEL);
        27         CloseHandle(m_hFile);
        28         m_hFile = NULL;
        29         CloseHandle(m_hMapping);
        30         m_hMapping = NULL;
        31         return;
        32     }
        33 }

        我们将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文件格式
  • 相关阅读:
    战胜忧虑<2>——忙碌可以消除忧虑
    战胜忧虑<1>——不要让忧郁侵入你的生活
    Django的下载和安装
    Github 如何上传本地文件
    Python_相对路径的获取
    Python_生成HTMLTestRunner测试报告
    Python_requests实例
    Charles抓包(Http/Https请求)
    Python_base_函数返回值
    Python_base_print 取消自动换行
  • 原文地址:https://www.cnblogs.com/csuftzzk/p/qcookieviewer.html
Copyright © 2020-2023  润新知