預備
繼上篇《瀏覽器緩存查看器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文件,是無法得到這樣的信息的。怎樣完成這個功能,下面將有詳細敘述。
關鍵技術
- 為什么不遍歷Cookie文件夾?
在上一篇中我們說過,僅僅靠遍歷Cache文件夾中的文件來獲取Cache文件清單是不可行的。因為那只能獲得文件名、文件大小等基本信息,我們需要的不僅僅是這些。另外,使用Windows系統提供的API的話,也具有一定的局限性。通過解析index.dat文件,我們獲取更為詳盡的信息。不但能夠得到當前主機存在的Cookies文件信息,還可以查看到該主機曾經存在過的Cookies文件。因此,我們仍然采用了解析index.dat文件的方法。
- 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/)。該目錄會根據權限的不同而不同。
- 內存文件映射
- 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文件映射到內存中使用完之后,須得及時關閉前面得到的內存句柄。否則可能導致資源泄漏。
- 解析index.dat文件
- 解析index.dat文件的過程自不必說了,在上一篇中我們已經詳細闡述過了。唯一需要注意的是,解析得到的字段和上一篇中的有所出入。
- Cookie文件的格式
- Cookies文件內容以ASCII碼字符保存,其格式也不算復雜。在一個Cookie文件中,可能存在多條Cookie記錄。每條Cookie記錄都包含9個字段,如下所示:
- 每個字段自成一行,以unix換行分隔符分割。每一條Cookie記錄又以星號(*)進行分割。這些字段的具體含義不必再贅述了。值得注意的是,這里的時間轉換需要注意順序。在參考資料4中,作者把時間的高地位寫反了,導致轉換得到的時間錯的離譜。另外需要注意的一個字段是Optional flags。這個字段到底包含哪些options,並沒有詳細的文檔說明。
- 關於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有更詳細的說明。
參考資料
- NirSoft
- Forensic Analysis of Internet Explorer Activity Files.pdf
- 《index.dat文件結構解析》,吳清,吳順祥.
- Cookie文件說明及IE的Cookie文件格式