获取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;
}
  

  

时间: 2024-12-11 02:00:45

获取IE下载历史的具体实现的相关文章

iOS----青花瓷运用-&gt;下载历史版本App

1.软件准备 [必备]Charles4.0.1 下载密码: jfnk [不需要,配合Charles食用效果更佳]Paw2.3.1 下载密码: t3my 2.正式开始 2.1 打开Charles青花瓷 historyApp1.png 2.2 安装证书以便能够拦截解析HTTPS请求数据 historyApp2.png 2.2.1 如果是选择本地安装证书的话,记住保存格式选择.cer historyApp3.png 2.2.2 双击下载好的证书 historyApp4.png 2.2.3 右键点击证书

【iOS秘籍】-下载历史版本App超详细教程

有些时候我们需要下载旧版本的 App 进行研究或者其他用途,然而在 iOS 下,苹果的 App Store 里面默认只能下载最新版本的 App,对滴,就是这么任性,不服不行.然而在 Android 里面任意一个应用商店都可以下载任意版本的 App,就是这么开放.重点来啦,今天我要教大家的就是利用 iTunes 下载任意历史版本的 App,任意哟,下面开始教程??.(为方便大家理解操作,图片较多,流量党慎入0-0) 题外话(强迫症排版.拼写): 文章排版:个人强迫症比较喜欢关注一些细节,比如博客或

下载历史版本App

文/timhbw(简书作者)原文链接:http://www.jianshu.com/p/edfed1b1822c著作权归作者所有,转载请联系作者获得授权,并标注"简书作者". 1.软件准备 [必备]Charles4.0.1 下载密码: jfnk [不需要,配合Charles食用效果更佳]Paw2.3.1 下载密码: t3my 2.正式开始 2.1 打开Charles青花瓷 2.2 安装证书以便能够拦截解析HTTPS请求数据 2.2.1 如果是选择本地安装证书的话,记住保存格式选择.ce

获取要下载文件的大小信息

原文来自IOS教程网,转载时请注明文章的来源:http://ios.662p.com/thread-1660-1-1.html NSURLConnectionDataDelegate方法中有: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {     //This method is calle

tar.gz包安装jdk-8u25的方法和注意的地方(下载历史版本JDK的方法)

下载历史版本JDK的方法: http://jingyan.baidu.com/article/9989c746064d46f648ecfe9a.html 2.下载好JDK后传至root目录. 3.创建目录,安放jdk解压文件 在linux环境中jdk的安装有两种方式,一为rpm安装机制,另一种为源码安装(已编译好) 因此在ORACLE官网提供两种安装文件,一为rpm格式,另一种为gz格式,两种的安装方式都大同小异的. [[email protected] ~]# mkdir /usr/jdk [

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

如何在Maven官网下载历史版本 历史版本一般会隔一段时间,便找不到,官网会及时显示的是最新版本.不多说,直接进入. https://archive.apache.org/dist/maven/binaries/ 成功在Maven官网里下载到历史版本! 其它,依次类推. 成功!

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

在android网络开发过程中,经常需要获取网络资源,比如下载图片,下载文本文件内容等,这个时候就需要http请求来获取相应的网络资源.首先看看实例效果图:              下载图片截图                                                                                                下载文本文件内容截图 下面介绍如何来实现这样的开发: (1)从指定的URL获取对应的流 既然要获取网络资源,那么

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

转自:https://blog.csdn.net/PacosonSWJTU/article/details/80959689 目前spring官网(http://spring.io/tools/sts/all)上可下载的spring插件只有:springsource-tool-suite-3.8.4(sts-3.8.4).但这只针对指定的eclipse版本适用. 如何为自己的eclipse下载历史版本的sts呢?拼下载的url. 首先,鼠标右键可下载的sts链接,然后"复制链接地址",

在spring官网上下载历史版本的spring插件,springsource-tool-suite

目前spring官网(https://spring.io/tools3/sts/all)上可下载的spring插件只有: ECLIPSE ARCHIVE SIZE 4.9.0 springsource-tool-suite-3.9.9.RELEASE-e4.9.0-updatesite.zip 175MB 4.12.0 springsource-tool-suite-3.9.9.RELEASE-e4.12.0-updatesite.zip 177MB 4.11.0 springsource-to