获取IE下载历史的具体实现
背景:
博主去年在国内某知名互联网公司做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;
}
获取IE下载历史的具体实现的更多相关文章
- 下载历史版本App超详细教程
有些时候我们需要下载旧版本的 App 进行研究或者其他用途,然而在 iOS 下,苹果的 App Store 里面默认只能下载最新版本的 App,对滴,就是这么任性,不服不行.然而在 Android 里 ...
- 搭建mysql5.626及如何去官网下载历史版本数据库
MySQL官网下载历史版本 网上搜索MySQL官网 2 查询所有的归档文件 点击进入服务器列表 列表中默认只有Windows 版本的,可选择其它版本,但无法进行查询 查看网页元素 发现 ...
- 下载历史版本App
文/timhbw(简书作者)原文链接:http://www.jianshu.com/p/edfed1b1822c著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 1.软件准备 [必备]C ...
- 青花瓷运用->下载历史版本App
1.软件准备 [必备]Charles4.0.1 下载密码: jfnk [不需要,配合Charles食用效果更佳]Paw2.3.1 下载密码: t3my 2.正式开始 2.1 打开Charles青花瓷 ...
- Android开发之异步获取并下载网络资源-下载图片和下载文本内容
在android网络开发过程中,经常需要获取网络资源,比如下载图片,下载文本文件内容等,这个时候就需要http请求来获取相应的网络资源.首先看看实例效果图: 下载图片截图 ...
- Jenkins下载历史Build版本的归档文件
/root/.jenkins/jobs/zgg-crm-pre/builds//com.zgg$crm/archive/com.zgg/crm/0.0.1/crm-0.0.1.war https:// ...
- 如何在Maven官网下载历史版本
如何在Maven官网下载历史版本 历史版本一般会隔一段时间,便找不到,官网会及时显示的是最新版本.不多说,直接进入. https://archive.apache.org/dist/maven/bin ...
- 奇技淫巧:在spring官网上下载历史版本的spring插件,springsource-tool-suite
转自:https://blog.csdn.net/PacosonSWJTU/article/details/80959689 目前spring官网(http://spring.io/tools/sts ...
- SVN 安装配置详解,包含服务器和客户端,外带一个项目演示,提交,更改,下载历史版本,撤销
本次要介绍的是svn版本管理工具包含2个: 服务器端:visualsvn server 下载地址为:https://www.visualsvn.com/server/download/ 此处演示的 ...
随机推荐
- 1013团队Beta冲刺day2
项目进展 李明皇 今天解决的进度 优化了信息详情页的布局:日期显示,添加举报按钮等 优化了程序的数据传递逻辑 明天安排 程序运行逻辑的完善 林翔 今天解决的进度 实现微信端消息发布的插入数据库 明天安 ...
- map的infowindow的show事件(ArcGIS API for JS)
- 基于 Java NIO 实现简单的 HTTP 服务器
1.简介 本文是上一篇文章实践篇,在上一篇文章中,我分析了选择器 Selector 的原理.本篇文章,我们来说说 Selector 的应用,如标题所示,这里我基于 Java NIO 实现了一个简单的 ...
- [UWP]针对UWP程序多语言支持的总结,含RTL
UWP 对 Globalization and localization 的支持非常好,可以非常容易地实现应用程序本地化. 所谓本地化,表现最为直观的就是UI上文字和布局方式了,针对文字,提供不同的语 ...
- ASP.NET Web API编程——模型验证与绑定
1.模型验证 使用特性约束模型属性 可以使用System.ComponentModel.DataAnnotations提供的特性来限制模型. 例如,Required特性表示字段值不能为空,Range特 ...
- UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 1987: illegal multibyte sequence
在爬取 url = "http://stats.meizhou.gov.cn/show/index/1543/1689" 时出现了问题: UnicodeEncodeError: ' ...
- spring6——AOP的编程术语
面向切面编程作为一种编程思想,允许我们对程序的执行流程及执行结果动态的做出改变,以达到业务逻辑之间的分层管理或者是目标对象方法的增强,spring框架很好的实现了这种编程思想,让我们可以对主业务逻辑和 ...
- logback打印日志时添加上下文
尝试上述特性, 配置如下: 效果:
- Properties文件中文属性读取是乱码问题
项目当中遇到了需要从Properties文件中读取配置属性的需求,本来是存储的中文转码后的属性,但是考虑到后期更改问题就变成java代码中进行转码,代码如下: Properties pros = ne ...
- String、StringBuffer、StringBulider之间的联系和区别
首先,我们大概总体的解释一下这三者的区别和联系 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. StringBuf ...