zoukankan      html  css  js  c++  java
  • 获取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"------------------------------------------
    ");
        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]
    ",strRefUrl.c_str());
          lpDownloadUrl = (LPWSTR)((LPBYTE)lpRefUrl+((wcslen(lpRefUrl)+1)*2));
          strDownloadUrl = lpDownloadUrl;
          if (!strDownloadUrl.empty())
          {
           wprintf(L"DownloadUrl[%s]
    ",strDownloadUrl.c_str());
           lpDestFile= (LPWSTR)((LPBYTE)lpDownloadUrl+((wcslen(lpDownloadUrl)+1)*2));
           strDestFile = lpDestFile;
           wprintf(L"DestFile[%s]
    ",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]
    ",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]
    ",strMIMEType.c_str());
           lpSrcFile = (LPWSTR)((LPBYTE)lpMIMEType+((wcslen(lpMIMEType)+1)*2));
           }
          strSrcFile = lpSrcFile;
          if (!strSrcFile.empty())
          {
           wprintf(L"SrcFile[%s]
    ",strSrcFile.c_str());
           lpDownloadUrl= (LPWSTR)((LPBYTE)lpSrcFile+((wcslen(lpSrcFile)+1)*2));
           }
          strDownloadUrl = lpDownloadUrl;
          if (!strDownloadUrl.empty())
          {
           wprintf(L"DownloadUrl[%s]
    ",strDownloadUrl.c_str());
           lpDestFile= (LPWSTR)((LPBYTE)lpDownloadUrl+((wcslen(lpDownloadUrl)+1)*2));
           wprintf(L"DestFile[%s]
    ",lpDestFile);
        strDestFile = lpDestFile;
          }
         }
         //兼容从IE9升级到IE10以上版本
         else
         {
          lpDownloadUrl = (LPWSTR)((LPBYTE)lpRefUrl+((wcslen(lpRefUrl)+1)*2));
          strDownloadUrl = lpDownloadUrl;
          if (!strDownloadUrl.empty())
          {
           wprintf(L"DownloadUrl[%s]
    ",strDownloadUrl.c_str());
           lpDestFile= (LPWSTR)((LPBYTE)lpDownloadUrl+((wcslen(lpDownloadUrl)+1)*2));
           strDestFile = lpDestFile;
           wprintf(L"DestFile[%s]
    ",strDestFile.c_str());
          }
         }
         
        }
        wprintf(L"------------------------------------------
    ");
       }
      }
      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"------------------------------------------
    ");
        wprintf(L"lpszSourceUrl[%s]
    ",strDownloadUrl.c_str());
        wprintf(L"lpszLocalFile[%s]
    ",strDestFile.c_str());
        wprintf(L"------------------------------------------
    ");
       }
      }
      //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------------------------
    "));
     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(("------------------------------------------
    "));
        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]
    ",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]
    ",strMIMEType.c_str()));
          lpSrcFile = (LPWSTR)((LPBYTE)lpMIMEType+((wcslen(lpMIMEType)+1)*2));
         }
         strSrcFile = lpSrcFile;
         if (!strSrcFile.empty())
         {
          DEBUG_PUT(("SrcFile[%s]
    ",strSrcFile.c_str()));
          lpDownloadUrl= (LPWSTR)((LPBYTE)lpSrcFile+((wcslen(lpSrcFile)+1)*2));
         }
         strDownloadUrl = lpDownloadUrl;
         if (!strDownloadUrl.empty())
         {
          DEBUG_PUT(("DownloadUrl[%s]
    ",strDownloadUrl.c_str()));
          lpDestFile= (LPWSTR)((LPBYTE)lpDownloadUrl+((wcslen(lpDownloadUrl)+1)*2));
          DEBUG_PUT(("DestFile[%s]
    ",lpDestFile));
          strDestFile = lpDestFile;
         }
        }
        //兼容IE9
        else
        {
         lpDownloadUrl = (LPWSTR)((LPBYTE)lpRefUrl+((wcslen(lpRefUrl)+1)*2));
         strDownloadUrl = lpDownloadUrl;
         if (!strDownloadUrl.empty())
         {
          DEBUG_PUT(("DownloadUrl[%s]
    ",strDownloadUrl.c_str()));
          lpDestFile= (LPWSTR)((LPBYTE)lpDownloadUrl+((wcslen(lpDownloadUrl)+1)*2));
          strDestFile = lpDestFile;
          DEBUG_PUT(("DestFile[%s]
    ",strDestFile.c_str()));
         }
        }
        DEBUG_PUT(("------------------------------------------
    "));
       }
      }
      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;
    }
      
    

      

  • 相关阅读:
    匿名访问windows server 2008 R2 文件服务器的共享
    ESXI6.0新添加硬盘未能格式化成功
    vcenter server appliance(vcsa) 配置IP的方法
    Office 手动kms激活方法
    .NET Reflector注册机激活方法
    转载: 显示隐藏的断开连接的邮箱
    十步轻松搞定IIS+PHP环境搭建
    解决windows10下无法安装.net framework 3.5,错误代码0x800F081F
    Vmware Horizon 服务器替换 ssl 证书
    vmware查看HBA卡、网卡驱动、firmware版本信息
  • 原文地址:https://www.cnblogs.com/cpuimage/p/4897104.html
Copyright © 2011-2022 走看看