您的位置:首页 > 其它

获取IE下载历史的具体实现

2015-10-21 10:31 169 查看
背景:

博主去年在国内某知名互联网公司做URL安全检测时写的一份草稿。

最后却没用到项目上。

当时主要想用于URL网址安全的入库以及更新,需要建立下载文件以及URL的安全属性关联。

逻辑大致是这样的:

若下载的文件报毒则拉黑该URL,认定URL为危险,若不报毒了,则恢复该URL为安全。

当时找了不少资料都不理想,特别是针对不同版本的IE浏览器,网上前人的思路几乎已经都失效了。

最后无奈操刀,逆向了IE浏览器的这部分函数,才算是达到目标,具体实现代码如下:

#include <WinInet.h>
#pragma comment(lib,"wininet.lib")
HRESULT getIeDownloadCache(HANDLE &hEnumHandle, LPINTERNET_CACHE_ENTRY_INFOA &lpCache, DWORD &nEntrySize)
{
HRESULT hr;
DWORD nError;
DWORD dwSize;
LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntry;
HANDLE hHandle;
DWORD dwEntrySize;
dwEntrySize = 0;
hr = E_INVALIDARG;
if ( !FindFirstUrlCacheEntryExA("iedownload:", 0, 0xFFFFFFFF, 0, NULL, &dwEntrySize, NULL, NULL, NULL) )
{
if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
goto FailExit;
dwSize = dwEntrySize;
lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFOA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
if ( !lpCacheEntry )
return E_OUTOFMEMORY;
hHandle = FindFirstUrlCacheEntryExA("iedownload:",0,0xFFFFFFFF,0,lpCacheEntry,&dwEntrySize,NULL,NULL,NULL);
if ( hHandle )
{
hr = 0;
lpCache = lpCacheEntry;
nEntrySize = dwEntrySize;
hEnumHandle = hHandle;
}
else
{
FailExit:
nError = GetLastError();
hr = nError;
if ( (signed int)nError > 0 )
hr = (unsigned __int16)nError | 0x80070000;
}
}
return hr;
}
HRESULT FindNextCache(HANDLE &hEnumHandle, LPINTERNET_CACHE_ENTRY_INFOA &lpCache, DWORD &dwEntrySize)
{
HRESULT hr;
DWORD nSize;
LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntry;
DWORD nError;
DWORD cbCacheEntryInfo;
cbCacheEntryInfo = 0;
hr = E_INVALIDARG;
if ( !FindNextUrlCacheEntryA(hEnumHandle, NULL, &cbCacheEntryInfo) )
{
if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER )
goto FailExit;
nSize = cbCacheEntryInfo;
lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFOA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nSize);
if ( !lpCacheEntry )
return E_OUTOFMEMORY;
if ( FindNextUrlCacheEntryA(hEnumHandle, lpCacheEntry, &cbCacheEntryInfo) )
{
hr = 0;
lpCache = lpCacheEntry;
dwEntrySize = cbCacheEntryInfo;
}
else
{
FailExit:
nError = GetLastError();
hr = nError;
if ( (signed int)nError > 0 )
hr = (unsigned __int16)nError | 0x80070000;
}
}
return hr;
}
void __cdecl myHeapFree(LPVOID lpMem)
{
HANDLE hHeap;
if ( lpMem )
{
hHeap = GetProcessHeap();
HeapFree(hHeap, 0, lpMem);
}
}

int GetIEVersion()
{
HKEY hKey = NULL;
DWORD dwType = 0;
CHAR szData[16] = {0};
DWORD dwDataSize = 15;
int nVersion = 0;
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Internet Explorer",
0,
KEY_READ,
&hKey) != ERROR_SUCCESS)
{
goto Exit0;
}
CHAR szVersion[MAX_PATH] = {0};
DWORD dwVersionSize = MAX_PATH-1;
LONG lRet = RegQueryValueExA(hKey, "svcVersion", NULL, &dwType, (BYTE*)szVersion, &dwVersionSize);
if (ERROR_SUCCESS == lRet && REG_SZ == dwType)
{
PCHAR pFind = strstr(szVersion, ".");
if (pFind != NULL)
{
*pFind = 0;
int nVer = atoi(szVersion);
if (9 == nVer ||
10 == nVer ||
11 == nVer)
{
nVersion = nVer;
goto Exit0;
}
}
}
if (ERROR_SUCCESS != RegQueryValueExA(hKey, "Build", NULL, &dwType, (BYTE*)szData, &dwDataSize))
{
goto Exit0;
}
nVersion = atoi(szData);
while (nVersion >= 15)
{
nVersion = nVersion / 10;
}
if (nVersion < 6)
{
nVersion = 0;
goto Exit0;
}
Exit0:
if (hKey != NULL)
{
RegCloseKey(hKey);
}
return nVersion;
}
BOOL GetIeDownloadHistoryFormCache(wstring & DestFile,wstring & refUrl, wstring &downloadUrl)
{
unsigned int i;
LPINTERNET_CACHE_ENTRY_INFOA lpCache;
BOOL bRet = FALSE;
HANDLE hEnumHandle;
DWORD dwSize;
DWORD IEURL_BUFFER_OFFSET = 0;
LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntry;
DWORD IEVer=GetIEVersion();
wstring strRefUrl,strMIMEType,strSrcFile,strDownloadUrl,strDestFile;
hEnumHandle = NULL;
lpCacheEntry = NULL;
dwSize = 0;
for ( i = getIeDownloadCache( hEnumHandle, lpCacheEntry, dwSize);
(i & 0x80000000u) == 0;
i = FindNextCache(hEnumHandle, lpCacheEntry, dwSize) )
{
lpCache = lpCacheEntry;
if ( strnicmp(lpCache->lpszSourceUrlName, "iedownload:", 11) == 0 )
{
if (lpCache->lpHeaderInfo)
{
bRet = TRUE;
DWORD dwLimitSize = 0x200;
for ( DWORD n = 0; n < dwLimitSize; n++)
{
BYTE http[] =
{
0x68, 0x00, 0x74, 0x00, 0x74, 0x00 ,0x70, 0x00, 0x3a, 0x00 ,0x2f ,0x00 ,0x2f
};
BYTE https[] =
{
0x68, 0x00, 0x74, 0x00, 0x74, 0x00 ,0x70, 0x00, 0x73, 0x00, 0x3a, 0x00 ,0x2f ,0x00 ,0x2f
};
BYTE ftp[] =
{
0x66, 0x00, 0x74, 0x00 ,0x70, 0x00, 0x3a, 0x00 ,0x2f ,0x00 ,0x2f
};
if( (memcmp(lpCache->lpHeaderInfo+n, (PBYTE)http,sizeof(http) ) == 0)
|| (memcmp(lpCache->lpHeaderInfo+n, (PBYTE)ftp,sizeof(ftp) ) == 0)
|| (memcmp(lpCache->lpHeaderInfo+n, (PBYTE)https,sizeof(https) ) == 0))
{
IEURL_BUFFER_OFFSET = n;
break;
}
}
wprintf(L"------------------------------------------\n");
LPWSTR lpRefUrl;
LPWSTR lpMIMEType;
LPWSTR lpSrcFile;
LPWSTR lpDownloadUrl;
LPWSTR lpDestFile;

if (IEVer == 9)
{
lpRefUrl = (LPWSTR)((LPBYTE)lpCache->lpHeaderInfo+IEURL_BUFFER_OFFSET);
strRefUrl = lpRefUrl;
if (!strRefUrl.empty())
{
wprintf(L"RefUrl[%s]\n",strRefUrl.c_str());
lpDownloadUrl = (LPWSTR)((LPBYTE)lpRefUrl+((wcslen(lpRefUrl)+1)*2));
strDownloadUrl = lpDownloadUrl;
if (!strDownloadUrl.empty())
{
wprintf(L"DownloadUrl[%s]\n",strDownloadUrl.c_str());
lpDestFile= (LPWSTR)((LPBYTE)lpDownloadUrl+((wcslen(lpDownloadUrl)+1)*2));
strDestFile = lpDestFile;
wprintf(L"DestFile[%s]\n",strDestFile.c_str());
}
}
}
else if (IEVer == 11||IEVer == 10)
{
lpRefUrl = (LPWSTR)((LPBYTE)lpCache->lpHeaderInfo+IEURL_BUFFER_OFFSET);
strRefUrl = lpRefUrl;
if (!strRefUrl.empty())
{
wprintf(L"RefUrl[%s]\n",strRefUrl.c_str());
lpMIMEType = (LPWSTR)((LPBYTE)lpRefUrl+((wcslen(lpRefUrl)+1)*2));
}
strMIMEType = lpMIMEType;
if ( strMIMEType.find(L"tp:/")== wstring::npos )
{
if (!strMIMEType.empty())
{
wprintf(L"MIMEType[%s]\n",strMIMEType.c_str());
lpSrcFile = (LPWSTR)((LPBYTE)lpMIMEType+((wcslen(lpMIMEType)+1)*2));
}
strSrcFile = lpSrcFile;
if (!strSrcFile.empty())
{
wprintf(L"SrcFile[%s]\n",strSrcFile.c_str());
lpDownloadUrl= (LPWSTR)((LPBYTE)lpSrcFile+((wcslen(lpSrcFile)+1)*2));
}
strDownloadUrl = lpDownloadUrl;
if (!strDownloadUrl.empty())
{
wprintf(L"DownloadUrl[%s]\n",strDownloadUrl.c_str());
lpDestFile= (LPWSTR)((LPBYTE)lpDownloadUrl+((wcslen(lpDownloadUrl)+1)*2));
wprintf(L"DestFile[%s]\n",lpDestFile);
strDestFile = lpDestFile;
}
}
//兼容从IE9升级到IE10以上版本
else
{
lpDownloadUrl = (LPWSTR)((LPBYTE)lpRefUrl+((wcslen(lpRefUrl)+1)*2));
strDownloadUrl = lpDownloadUrl;
if (!strDownloadUrl.empty())
{
wprintf(L"DownloadUrl[%s]\n",strDownloadUrl.c_str());
lpDestFile= (LPWSTR)((LPBYTE)lpDownloadUrl+((wcslen(lpDownloadUrl)+1)*2));
strDestFile = lpDestFile;
wprintf(L"DestFile[%s]\n",strDestFile.c_str());
}
}

}
wprintf(L"------------------------------------------\n");
}
}
else
//ie9以下版本
{
strDownloadUrl=CA2W(lpCache->lpszSourceUrlName);
strDestFile=CA2W(lpCache->lpszLocalFileName);
transform(strDestFile.begin(), strDestFile.end(), strDestFile.begin(), towlower);
//过滤目标文件目录是临时目录
if (strDestFile.find(L"content.ie5")==std::string::npos)
{
wprintf(L"------------------------------------------\n");
wprintf(L"lpszSourceUrl[%s]\n",strDownloadUrl.c_str());
wprintf(L"lpszLocalFile[%s]\n",strDestFile.c_str());
wprintf(L"------------------------------------------\n");
}
}
//DeleteUrlCacheEntryA(lpCache->lpszSourceUrlName);
myHeapFree(lpCache);
transform(strDestFile.begin(), strDestFile.end(), strDestFile.begin(), towlower);
transform(DestFile.begin(), DestFile.end(), DestFile.begin(), towlower);
if (strDestFile.find(DestFile.c_str())!=wstring::npos)
{
refUrl=strRefUrl;
downloadUrl = strDownloadUrl;
return bRet;
}
}
return bRet;
}
-------------------------------------------------------------------------------------------------
BOOL GetIEDownloadFileUrl(wstring& strCacheFilePath, wstring& RefUrl,wstring& FileUrl)
{
unsigned int i;
LPINTERNET_CACHE_ENTRY_INFOA lpCache;
BOOL bRet = FALSE;
HANDLE hEnumHandle;
DWORD dwSize;
DWORD IEURL_BUFFER_OFFSET = 0;
LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntry;
wstring strRefUrl,strMIMEType,strSrcFile,strDownloadUrl,strDestFile;
hEnumHandle = NULL;
lpCacheEntry = NULL;
dwSize = 0;
DEBUG_PUT(("------------------GetIeDownloadHistoryFormCache------------------------\n"));
for ( i = getIeDownloadCache( hEnumHandle, lpCacheEntry, dwSize);
(i & 0x80000000) == 0;
i = FindNextCache(hEnumHandle, lpCacheEntry, dwSize) )
{
lpCache = lpCacheEntry;
if ( strnicmp(lpCache->lpszSourceUrlName, "iedownload:", 11) == 0 )
{
if (lpCache->lpHeaderInfo)
{
bRet = TRUE;
DWORD dwLimitSize = 0x200;
for ( DWORD n = 0; n < dwLimitSize; n++)
{
BYTE http[] =
{
0x68, 0x00, 0x74, 0x00, 0x74, 0x00 ,0x70, 0x00, 0x3a, 0x00 ,0x2f ,0x00 ,0x2f
};
BYTE https[] =
{
0x68, 0x00, 0x74, 0x00, 0x74, 0x00 ,0x70, 0x00, 0x73, 0x00, 0x3a, 0x00 ,0x2f ,0x00 ,0x2f
};
BYTE ftp[] =
{
0x66, 0x00, 0x74, 0x00 ,0x70, 0x00, 0x3a, 0x00 ,0x2f ,0x00 ,0x2f
};
if( (memcmp(lpCache->lpHeaderInfo+n, (PBYTE)http,sizeof(http) ) == 0)
|| (memcmp(lpCache->lpHeaderInfo+n, (PBYTE)ftp,sizeof(ftp) ) == 0)
|| (memcmp(lpCache->lpHeaderInfo+n, (PBYTE)https,sizeof(https) ) == 0))
{
IEURL_BUFFER_OFFSET = n;
break;
}
}
DEBUG_PUT(("------------------------------------------\n"));
LPWSTR lpRefUrl;
LPWSTR lpMIMEType;
LPWSTR lpSrcFile;
LPWSTR lpDownloadUrl;
LPWSTR lpDestFile;
lpRefUrl = (LPWSTR)((LPBYTE)lpCache->lpHeaderInfo+IEURL_BUFFER_OFFSET);
strRefUrl = lpRefUrl;
if (!strRefUrl.empty())
{
DEBUG_PUT(("RefUrl[%s]\n",strRefUrl.c_str()));
lpMIMEType = (LPWSTR)((LPBYTE)lpRefUrl+((wcslen(lpRefUrl)+1)*2));
strMIMEType = lpMIMEType;
}
if ( strMIMEType.find(L"tp:/")== wstring::npos )
{
if (!strMIMEType.empty())
{
DEBUG_PUT(("MIMEType[%s]\n",strMIMEType.c_str()));
lpSrcFile = (LPWSTR)((LPBYTE)lpMIMEType+((wcslen(lpMIMEType)+1)*2));
}
strSrcFile = lpSrcFile;
if (!strSrcFile.empty())
{
DEBUG_PUT(("SrcFile[%s]\n",strSrcFile.c_str()));
lpDownloadUrl= (LPWSTR)((LPBYTE)lpSrcFile+((wcslen(lpSrcFile)+1)*2));
}
strDownloadUrl = lpDownloadUrl;
if (!strDownloadUrl.empty())
{
DEBUG_PUT(("DownloadUrl[%s]\n",strDownloadUrl.c_str()));
lpDestFile= (LPWSTR)((LPBYTE)lpDownloadUrl+((wcslen(lpDownloadUrl)+1)*2));
DEBUG_PUT(("DestFile[%s]\n",lpDestFile));
strDestFile = lpDestFile;
}
}
//兼容IE9
else
{
lpDownloadUrl = (LPWSTR)((LPBYTE)lpRefUrl+((wcslen(lpRefUrl)+1)*2));
strDownloadUrl = lpDownloadUrl;
if (!strDownloadUrl.empty())
{
DEBUG_PUT(("DownloadUrl[%s]\n",strDownloadUrl.c_str()));
lpDestFile= (LPWSTR)((LPBYTE)lpDownloadUrl+((wcslen(lpDownloadUrl)+1)*2));
strDestFile = lpDestFile;
DEBUG_PUT(("DestFile[%s]\n",strDestFile.c_str()));
}
}
DEBUG_PUT(("------------------------------------------\n"));
}
}
else
{
//兼容IE9以下版本
strDownloadUrl=CA2W(lpCache->lpszSourceUrlName);
strDestFile=CA2W(lpCache->lpszLocalFileName);
transform(strDestFile.begin(), strDestFile.end(), strDestFile.begin(), towlower);
}
//清除记录
//DeleteUrlCacheEntryA(lpCache->lpszSourceUrlName);
myHeapFree(lpCache);
transform(strDestFile.begin(), strDestFile.end(), strDestFile.begin(), towlower);
transform(strCacheFilePath.begin(), strCacheFilePath.end(), strCacheFilePath.begin(), towlower);
if (strDestFile.find(strCacheFilePath)!=wstring::npos)
{
RefUrl=strRefUrl;
FileUrl = strDownloadUrl;
return TRUE;
}
}
return bRet;
}
  


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: