背景:

博主去年在国内某知名互联网公司做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下载历史的具体实现的更多相关文章

  1. 下载历史版本App超详细教程

    有些时候我们需要下载旧版本的 App 进行研究或者其他用途,然而在 iOS 下,苹果的 App Store 里面默认只能下载最新版本的 App,对滴,就是这么任性,不服不行.然而在 Android 里 ...

  2. 搭建mysql5.626及如何去官网下载历史版本数据库

    MySQL官网下载历史版本 网上搜索MySQL官网 2 查询所有的归档文件   点击进入服务器列表   列表中默认只有Windows 版本的,可选择其它版本,但无法进行查询   查看网页元素   发现 ...

  3. 下载历史版本App

    文/timhbw(简书作者)原文链接:http://www.jianshu.com/p/edfed1b1822c著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 1.软件准备 [必备]C ...

  4. 青花瓷运用->下载历史版本App

    1.软件准备 [必备]Charles4.0.1 下载密码: jfnk [不需要,配合Charles食用效果更佳]Paw2.3.1 下载密码: t3my 2.正式开始 2.1 打开Charles青花瓷 ...

  5. Android开发之异步获取并下载网络资源-下载图片和下载文本内容

    在android网络开发过程中,经常需要获取网络资源,比如下载图片,下载文本文件内容等,这个时候就需要http请求来获取相应的网络资源.首先看看实例效果图:              下载图片截图   ...

  6. 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:// ...

  7. 如何在Maven官网下载历史版本

    如何在Maven官网下载历史版本 历史版本一般会隔一段时间,便找不到,官网会及时显示的是最新版本.不多说,直接进入. https://archive.apache.org/dist/maven/bin ...

  8. 奇技淫巧:在spring官网上下载历史版本的spring插件,springsource-tool-suite

    转自:https://blog.csdn.net/PacosonSWJTU/article/details/80959689 目前spring官网(http://spring.io/tools/sts ...

  9. SVN 安装配置详解,包含服务器和客户端,外带一个项目演示,提交,更改,下载历史版本,撤销

    本次要介绍的是svn版本管理工具包含2个: 服务器端:visualsvn server 下载地址为:https://www.visualsvn.com/server/download/   此处演示的 ...

随机推荐

  1. 1013团队Beta冲刺day2

    项目进展 李明皇 今天解决的进度 优化了信息详情页的布局:日期显示,添加举报按钮等 优化了程序的数据传递逻辑 明天安排 程序运行逻辑的完善 林翔 今天解决的进度 实现微信端消息发布的插入数据库 明天安 ...

  2. map的infowindow的show事件(ArcGIS API for JS)

  3. 基于 Java NIO 实现简单的 HTTP 服务器

    1.简介 本文是上一篇文章实践篇,在上一篇文章中,我分析了选择器 Selector 的原理.本篇文章,我们来说说 Selector 的应用,如标题所示,这里我基于 Java NIO 实现了一个简单的 ...

  4. [UWP]针对UWP程序多语言支持的总结,含RTL

    UWP 对 Globalization and localization 的支持非常好,可以非常容易地实现应用程序本地化. 所谓本地化,表现最为直观的就是UI上文字和布局方式了,针对文字,提供不同的语 ...

  5. ASP.NET Web API编程——模型验证与绑定

    1.模型验证 使用特性约束模型属性 可以使用System.ComponentModel.DataAnnotations提供的特性来限制模型. 例如,Required特性表示字段值不能为空,Range特 ...

  6. 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: ' ...

  7. spring6——AOP的编程术语

    面向切面编程作为一种编程思想,允许我们对程序的执行流程及执行结果动态的做出改变,以达到业务逻辑之间的分层管理或者是目标对象方法的增强,spring框架很好的实现了这种编程思想,让我们可以对主业务逻辑和 ...

  8. logback打印日志时添加上下文

    尝试上述特性, 配置如下: 效果:

  9. Properties文件中文属性读取是乱码问题

    项目当中遇到了需要从Properties文件中读取配置属性的需求,本来是存储的中文转码后的属性,但是考虑到后期更改问题就变成java代码中进行转码,代码如下: Properties pros = ne ...

  10. String、StringBuffer、StringBulider之间的联系和区别

    首先,我们大概总体的解释一下这三者的区别和联系 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. StringBuf ...