65,180
社区成员




// CacheSpy.h : main header file for the CACHESPY application
//
#if !defined(AFX_CACHESPY_H__3092A05F_8E28_4075_A3BC_9A52CF53A571__INCLUDED_)
#define AFX_CACHESPY_H__3092A05F_8E28_4075_A3BC_9A52CF53A571__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CCacheSpyApp:
// See CacheSpy.cpp for the implementation of this class
//
class CCacheSpyApp : public CWinApp
{
public:
CCacheSpyApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCacheSpyApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CCacheSpyApp)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CACHESPY_H__3092A05F_8E28_4075_A3BC_9A52CF53A571__INCLUDED_)
// Cache.cpp: implementation of the CCache class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CacheSpy.h"
#include "Cache.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCache::CCache()
{
char szDir[1024] = {0};
if(!ExpandEnvironmentStrings("%USERPROFILE%", szDir, 1024))
{
AfxMessageBox("Cannot get %USERPROFILE%.");
return;
}
strcat(szDir, "\\Local Settings\\History\\History.IE5\\index.dat");
lpCache = MapCache(szDir);
}
CCache::~CCache()
{
}
LPVOID CCache::MapCache(char *szFileName)
{
HANDLE hFile, hMapFile;
hFile = CreateFile("这里是文件名",
GENERIC_READ, // open for reading
FILE_SHARE_READ|FILE_SHARE_WRITE, // share for reading
NULL, // no security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
AfxMessageBox("Could not open file.");
return NULL;
}
hMapFile = CreateFileMapping(hFile, // Current file handle.
NULL, // Default security.
PAGE_READONLY, // Read/write permission.
0, // Max. object size.
0, // Size of hFile.
"MappingCache"); // Name of mapping object.
if (hMapFile == NULL)
{
AfxMessageBox("Could not create file-mapping object.");
return NULL;
}
lpCache = MapViewOfFile(hMapFile, // Handle to mapping object.
FILE_MAP_READ, // Read/write permission
0, // Max. object size.
0, // Size of hFile.
0); // Map entire file.
if (lpCache == NULL)
{
AfxMessageBox("Could not map view of file.");
return NULL;
}
CloseHandle(hFile);
CloseHandle(hMapFile);
//get cache file size
dwCacheLen = *(DWORD *)((BYTE *)lpCache+0x1c);
return lpCache;
}
//得到所有URL记录总数
int CCache::GetCount()
{
int iRet = -1;
if(lpCache == NULL||dwCacheLen <= 0)
return -1;
//get the first hash table offset
DWORD dwHashOff = *(DWORD *)((BYTE *)lpCache+0x20);
if(dwHashOff == 0||dwHashOff>dwCacheLen)
return -1;
BYTE *lpHash = (BYTE *)lpCache+dwHashOff;
DWORD dwHashLen=0, dwNextOff=0, dwUrlOff=0, dwHash = 0;
//get hash tables one by one
iRet = 0;
while(1)
{
if(memcmp(lpHash, "HASH", 4)!=0)
break;
dwHashLen = *(DWORD *)(lpHash+4); //hash table size
dwNextOff = *(DWORD *)(lpHash+8); //the next hashtable offset
//get hash and offset
for(int i=0;i<dwHashLen*16;i++) //dwHashLen*0x80/8
{
dwHash = *(DWORD *)(lpHash+0x10+i*8);
if(dwHash == 0x0) //get table tail
break;
if(dwHash == 0x3) //unused hash
continue;
dwUrlOff = *(DWORD *)(lpHash+0x10+i*8+4);
if(dwUrlOff!=0&&dwUrlOff!=0x3&&dwUrlOff<dwCacheLen)
{
//GetHis((BYTE *)lpCache+dwUrlOff);
iRet++;
}
}
if(dwNextOff == 0||dwNextOff>dwCacheLen)
break;
lpHash = (BYTE *)lpCache+dwNextOff;
}
return iRet;
}
//得到所有记录
//char *szUrl, char *szTitle, char *szVisited, char *szUpdated, char *szExpire
BOOL CCache::GetHis(BYTE *lpUrl, LISTPROC proList)
{
if(memcmp(lpUrl, "URL ", 4)!=0)
return FALSE;
//get urlhis size(=*0x80 bytes)
DWORD dwLen = *(DWORD *)(lpUrl+4);
if(dwLen <= 0)
return FALSE;
//get URL
char *szUrl1 = (char *)(lpUrl+0x68);
char *szUrl=strstr(szUrl1, "@");
if(szUrl == NULL)
return FALSE;
szUrl++;
//get last visited, last updated, expires
FILETIME ftVis = *(FILETIME *)(lpUrl+0x8);
FILETIME ftUpd = *(FILETIME *)(lpUrl+0x10);
DWORD dwExpire = *(DWORD *)(lpUrl+0x18);
FILETIME ftExp = ftUpd;
ftExp.dwLowDateTime += dwExpire;
CTime ctConvVis(ftVis), ctConvUpd(ftUpd), ctConvExp(ftExp);
CString sVis = ctConvVis.Format( "%Y-%m-%d %H:%M:%S" );
CString sUpd = ctConvUpd.Format( "%Y-%m-%d %H:%M:%S" );
CString sExp = ctConvExp.Format( "%Y-%m-%d %H:%M:%S" );
//get Title
char *szTitle = NULL;
LPCWSTR wchTitle = NULL;
DWORD dwTitleOff = *(DWORD *)(lpUrl+0x44);
DWORD dwTitleLen = *(DWORD *)(lpUrl+0x48);
if(dwTitleLen-0x14 <= 0)
{
szTitle = "NULL";
}
else if(dwTitleOff>0&&dwTitleOff<dwLen*0x80)
{
//WORD w1, w2;
//w1 = *(WORD *)(lpUrl+dwTitleOff);
//w2 = *(WORD *)(lpUrl+dwTitleOff+2);
wchTitle = (LPCWSTR)(lpUrl+dwTitleOff+20);
int nCharSize = WideCharToMultiByte(936, 0, wchTitle, wcslen(wchTitle), NULL, 0, NULL, NULL);
if(nCharSize > 0)
{
szTitle = new char[nCharSize+2];
if(szTitle == NULL)
szTitle = "NULL";
else
{
memset(szTitle, 0, nCharSize+2);
WideCharToMultiByte(936, 0, wchTitle, wcslen(wchTitle), szTitle, nCharSize, NULL, NULL);
}
}
}
//call LISTPROC function to finish get
proList(szUrl, szTitle, sVis, sUpd, sExp);
if(szTitle != NULL&&strcmp(szTitle, "NULL")!=0)
delete [] szTitle;
return TRUE;
}
//通过HASH表得到记录偏移
int CCache::GetList(LISTPROC proList)
{
int iRet = -1;
if(proList == NULL)
return -1;
if(lpCache == NULL||dwCacheLen <= 0)
return -1;
//get the first hash table offset
DWORD dwHashOff = *(DWORD *)((BYTE *)lpCache+0x20);
if(dwHashOff == 0||dwHashOff>dwCacheLen)
return -1;
BYTE *lpHash = (BYTE *)lpCache+dwHashOff;
DWORD dwHashLen=0, dwNextOff=0, dwUrlOff=0, dwHash = 0;
//get hash tables one by one
iRet = 0;
while(1)
{
if(memcmp(lpHash, "HASH", 4)!=0)
break;
dwHashLen = *(DWORD *)(lpHash+4); //hash table size
dwNextOff = *(DWORD *)(lpHash+8); //the next hashtable offset
//get hash and offset
for(int i=0;i<dwHashLen*16;i++) //dwHashLen*0x80/8
{
dwHash = *(DWORD *)(lpHash+0x10+i*8);
if(dwHash == 0x0) //get table tail
break;
if(dwHash == 0x3) //unused hash
continue;
dwUrlOff = *(DWORD *)(lpHash+0x10+i*8+4);
if(dwUrlOff!=0&&dwUrlOff!=0x3&&dwUrlOff<dwCacheLen)
{
GetHis((BYTE *)lpCache+dwUrlOff, proList);
iRet++;
}
}
if(dwNextOff == 0||dwNextOff>dwCacheLen)
break;
lpHash = (BYTE *)lpCache+dwNextOff;
}
return iRet;
}