用Qt寫軟體系列一:QCacheViewer(瀏覽器快取檢視器)
介紹
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條目了。
預覽效果
參考資料
程式碼
View it on github.
相關推薦
用Qt寫軟體系列一:QCacheViewer(瀏覽器快取檢視器)
介紹 Cache技術廣泛應用於計算機行業的軟硬體領域。該技術既是人們對新技術探討的結果,也是對當前軟硬體計算能力的一種妥協。在瀏覽器中使用cache技術,可以大幅度提高web頁面的響應速度,降低資料傳輸延遲,提高web使用者的體驗。因此,客戶端在瀏覽網頁的過程中,會在本地快取許多檔案。隨著使用時間
用Qt寫軟體系列三:一個簡單的系統工具之介面美化
前言 在上一篇中,我們基本上完成了主要功能的實現,剩下的一些匯出、程序子模組資訊等功能,留到後面再來慢慢實現。這一篇來講述如何對主介面進行個性化的定製。Qt庫提供的只是最基本的元件功能,使用這些元件開發出來的軟體基本上個性可言。如果開發的產品只講究實用性,那麼UI
案例一:禁止瀏覽器快取動態頁面
禁止瀏覽器快取所有動態頁面的過濾器: 有 3 個 HTTP 響應頭欄位都可以禁止瀏覽器快取當前頁面,它們在 Servlet 中的示例程式碼如下: response.setDateHeader("Expires",-1); response.setHeader("Ca
使用 PySide2 開發 Maya 外掛系列一:QT Designer 設計GUI, pyside-uic 把 .ui 檔案轉為 .py 檔案 Maya Max python PySide整合 shiboken版本對應關係
使用 PySide2 開發 Maya 外掛系列一:QT Designer 設計GUI, pyside-uic 把 .ui 檔案轉為 .py 檔案 前期準備: 安裝 python:https://www.python.org/downloads/ 安裝 PySide2:安裝 python 後,在安裝目錄下
webpack漸入佳境系列一:webpack環境配置與打包基礎【附帶各種 "坑" 與解決方案!持續更新中...】
utf 環境配置 lan 配置 要求 完全 需要 構建 樣式 首先介紹傳統模塊化開發的主流方案: 1.基與CMD的sea.js,玉伯提出的解決方案,據說原來京東團隊在使用。用時才定義,就近加載。最近在瀏覽seajs官方文檔時發現seajs的域名已經在轉賣,驚恐萬分之余又想
sed修煉系列(一):花拳繡腿之入門篇
由於 ... 我會 沖突 mic 區別 comm aud 追上 本文為花拳繡腿招式入門篇,主要目的是入門,為看懂sed修煉系列(二):武功心法做準備。雖然是入門篇,只介紹了基本工作機制以及一些選項和命令,但其中仍然包括了很多sed的工作機制細節。對比網上各sed相關文章以及
Linux Kernel系列一:開篇和Kernel啟動概要
mis misc 跳轉 line global 最終 width lin 通過 前言 最近幾個月將Linux Kernel的大概研究了一下,下面需要進行深入詳細的分析。主要將以S3C2440的一塊開發板為硬件實體。大概包括如下內容: 1 bootloader分析,以uboo
Exchange Server 2016安裝部署系列一:Exchange 簡述,環境需求及部署規劃
exchange 2016 先決條件 exchange 2016 準備ad和 exchange 2016 郵箱服務 exchange 2016 安裝 exchange 邊緣服務器部署 Exchange Server 2016簡述MicrosoftExchange Server 2016
IO流系列一:輸入輸出流的轉換
pst 取出 nal block each bytearray puts write 為什麽 輸入流轉字節數組的原理1、讀取輸入流,每一小段 讀一次,取出 byteArray 。2、將該一小段byteArray寫入到字節輸出流ByteOutStream。直到不能從輸入流再讀
WebService系列一:WebService簡介
跨語言 訪問 HR 響應消息 平臺 face view 百度 不同 原文鏈接:http://www.cnblogs.com/xdp-gacl/p/4259109.html 一、WebService是什麽 WebService是一種跨編程語言和跨操作系統平臺的遠程調用技術 跨
[ 搭建Redis本地服務器實踐系列一 ] :圖解CentOS7安裝Redis
文章 centos服務 安裝redis 基本 虛擬 http 16px entos 自己 一章 [ 搭建Redis本地服務器實踐系列 ] :序言 作為開場白介紹了下為什麽要寫這個系列,從這個章節我們就開始真正的進入正題,開始搭建我們本地的Redis服務器。那麽關於Redis
elasticsearch系列一:elasticsearch(ES簡介、安裝&配置、集成Ikanalyzer)
ins 表示 吞吐量 search 工作 use art tcp傳輸 .net 一、ES簡介 1. ES是什麽? Elasticsearch 是一個開源的搜索引擎,建立在全文搜索引擎庫 Apache Lucene 基礎之上 用 Java 編寫的,它的內部使用 Lucene
Silverlight & Blend動畫設計系列一:偏移動畫(TranslateTransform)
gif 用戶 pre class 拖拽 width 新用戶 board 動畫效果 用戶界面組件、圖像元素和多媒體功能可以讓我們的界面生動活潑,除此之外,Silverlight還具備動畫功能,它可以讓應用程序“動起來”。實際上,英文中Animation這個單詞的意思是給某物帶
Docker系列一:Docker的介紹和安裝
實驗 start ner min docker-ce 周期 com set 自動化測試 Docker介紹 Docker是指容器化技術,用於支持創建和實驗Linux Container。借助Docker,你可以將容器當做重量輕、模塊化的虛擬機來使用,同時,你還將獲得高度的靈活
CAS源碼追蹤系列一:Filter的初始化
引入 委托 ppi 假設 文檔 client 通過 tomcat容器 發現 目錄 代碼跟蹤 Spring-web:DelegatingFilterProxy CAS:AuthenticationFilter 總結 最近研究了一下SSO(Single Sign On:單
Windows下USB磁碟開發系列一:列舉系統中U盤的碟符
有個時候我們需要區分系統磁碟中,哪些是U盤,這樣我們在訪問的時候可以區別對待。具體方法如下: 1,呼叫GetLogicalDrives()返回系統碟符標記位 API GetLogicalDrives()將返回一個DWORD型別的標記值,將其轉換成二進位制之後,為1的位標識對應的碟符在系統中存
CAS原始碼追蹤系列一:Filter的初始化
目錄 程式碼跟蹤 Spring-web:DelegatingFilterProxy CAS:AuthenticationFilter 總結 最近研究了一下SSO(Single Sign On:單點登入)原理。 於是想借助CAS(基於SSO原理的實現框架)加深一下
【轉載】JVM系列一:JVM記憶體組成及分配
java記憶體組成介紹:堆(Heap)和非堆(Non-heap)記憶體 按照官方的說法:“Java 虛擬機器具有一個堆,堆是執行時資料區域,所有類例項和陣列的記憶體均從此處分配。堆是在 Java 虛擬機器啟動時建立的。”“在JVM中堆
兩小時eclipse入門idea系列一:idea的下載安裝破解一條龍服務
寫在前面:人總是有惰性的,也總會為惰性找到一個合理的藉口。比如我,一直以來都用著eclipse,各種配置信手拈來,不管別人怎麼吹捧idea,就不想去用,覺得eclipse就挺好,為啥要去重新熟悉一個陌生的工具?可是今天,好奇心驅動著吃了屎的心情去研究了一下子idea,以此為記。 1、下載idea
『PHP學習筆記』系列一:利用for迴圈解決過路口問題
過路口問題: 假設某人有100,000現金。每經過一次路口需要進行一次交費。交費規則為當他現金大於50,000時每次需要交5%如果現金小於等於50,000時每次交5,000。請寫一程式計算此人可以經過多少次這個路口。 解題思路: 此題最重要的其實就是思路和邏輯,程式碼實現其實很簡單,這裡