背景:

博主去年在国内某知名互联网公司做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. CountDownLatch 源码解析—— countDown()

    上一篇文章从源码层面说了一下CountDownLatch 中 await() 的原理.这篇文章说一下countDown() . public void countDown() { //CountDow ...

  2. Transaction 事务简单详解

    Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废. 事务也是这样,不能做一半就不做了,要么做完,要么就不做.也就是说,事务必须是一 ...

  3. JavaScript(第九天)【正则表达式】

    假设用户需要在HTML表单中填写姓名.地址.出生日期等.那么在将表单提交到服务器进一步处理前,JavaScript程序会检查表单以确认用户确实输入了信息并且这些信息是符合要求的.   一.什么是正则表 ...

  4. 网络1711班 C语言第四次作业批改总结

    网络1711班 C语言第四次作业批改总结 助教有话说(写在前面) 近来,有同学跟老师和助教们反映:博客作业太多太麻烦,而且对编程能力提高似乎没什么帮助?在这里我要谈一谈我的感想. 博客作业的意义? 首 ...

  5. C语言指针作业

    一.PTA实验作业 题目1:6-5 判断回文字符串 1. 本题PTA提交列表 2. 设计思路 3.代码截图 4.本题调试过程碰到问题及PTA提交列表情况说明. 第一次做的时候我j直接等于count,其 ...

  6. Alpha冲刺No.6

    站立式会议 继续页面设计 在安卓内构件数据库相应类 解决摄像头.照片的使用的异常问题 二.实际项目进展 页面设计完成百分80 类架构完成 在虚拟机中,能够完成摄像头的调用和程序的使用 三.燃尽图 四. ...

  7. Environment.getExternalStorageDirectory()

    Environment.getExternalStorageDirectory()得到的是storage/emulated/0

  8. SQL SERVER 字符串按数字排序

    需求是这样的: 数据库表里面有一个字段类型是nvachar,存的值是数字和字符混合的,要实现先按数字排序,再按字母倒序. 思路: 考虑这个字段的值是否是有规律可循的,把要按数字排序的部分转换为数字,再 ...

  9. Java+Maven+selenium+testing+reportNG自动化测试框架

    最近公司新出了一个产品,需要搭建自动化测试框架,这是一个学以至用的好机会,跟上级申请后,决定搭建一个java自动化测试框架. Java自动化测试对我来讲可以说不难不易,因为java是我大学在校四年学的 ...

  10. 《深入实践Spring Boot》阅读笔记之二:分布式应用开发

    上篇文章总结了<深入实践Spring Boot>的第一部分,这篇文章介绍第二部分:分布式应用开发,以及怎么构建一个高性能的服务平台. 主要从以下几个方面总结: Spring Boot SS ...