背景:

博主去年在国内某知名互联网公司做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. Spring之事务管理的好处

    在以往的JDBCTemplate中事务提交成功,异常处理都是通过Try/Catch 来完成,而在Spring中.Spring容器集成了TransactionTemplate,封装了所有对事务处理的功能 ...

  2. 用C语言协助办公_01 找出所有不对劲的人

    近期想出一系列用C语言协助办公的视频教程,这是第一个.具体的移步:https://chuanke.baidu.com/v6658388-240377-1789288.html

  3. 20162328蔡文琛week04

    学号 20162328 <程序设计与数据结构>第4周学习总结 教材学习内容总结 本周学习了第四章和第七章,第四章中的内容已经有了初步定的掌握,布尔表达式的运用,是条件和循环语句的基础及数组 ...

  4. 下载文件downloadFile

    public static void downLoadFile(InputStream inStream, String fileName) { if (StringUtils.isBlank(fil ...

  5. 判断mine类型

    var http = require("http"); var fs = require("fs"); var url = require("url& ...

  6. Mysql 相关操作

    1.用户管理 创建用户 create user '用户名'@'IP地址' identified by '密码'; 删除用户 drop user '用户名'@'IP地址'; 修改用户 rename us ...

  7. sql 多条记录插入

    --多条记录插入,用逗号分开值. INSERT dbo.studentinfor ( id, name, class, age, hpsw ) ', -- id - nvarchar(50) N'te ...

  8. C#微信公众号——消息处理

    ​当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL. 一.接收POST请求,处理XML信息 public void ProcessRequest(HttpC ...

  9. 三十天学不会TCP,UDP/IP网络编程 -- RTT的计算

    欢迎去gitbook(https://www.gitbook.com/@rogerzhu/)看到完整版. 如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,虽然说现在这种“看不见”的 ...

  10. python flask框架 tempates 模版的使用

    在py文件同级下 建立templates文件夹,再文件夹中编写html文件 1 向模版中传递参数: ''' 1 向模板传送 参数 ''' @app.route('/') def index(): na ...