Trident内核中取验证码图片的几种方法
程序中用了IE的内核,想取出网站中的验证码图片,单独显示出来,调研了以下几路方法
1、枚举所有缓存文件,进行处理,找到想要的,核心代码
if (0)//这段代码可以枚举所有缓存资源,然后对应做处理 { LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = NULL; HANDLE hCacheDir = NULL; DWORD dwTrySize, dwEntrySize = 4096; DWORD dwError = ERROR_INSUFFICIENT_BUFFER; BOOL bSuccess, bDone = FALSE; //是否已经处理完,初始设为false while(!bDone){ switch(dwError){ case ERROR_INSUFFICIENT_BUFFER: if(lpCacheEntry) { delete [] lpCacheEntry; } lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize]; lpCacheEntry->dwStructSize = dwEntrySize; dwTrySize = dwEntrySize; if(!hCacheDir) {//为空,说明第一次执行,需要找第一个 hCacheDir = FindFirstUrlCacheEntry(NULL,lpCacheEntry,&dwTrySize); bSuccess = (hCacheDir != NULL); } else { bSuccess = FindNextUrlCacheEntry(hCacheDir,lpCacheEntry,&dwTrySize); } if(!bSuccess){ dwError = GetLastError(); dwEntrySize = dwTrySize; //使用得到的新长度 } else { dwError = ERROR_SUCCESS; } break; //we are done case ERROR_NO_MORE_ITEMS: bDone = TRUE; break; //we have got an entry case ERROR_SUCCESS: if(bSuccess && (NORMAL_CACHE_ENTRY & lpCacheEntry->CacheEntryType)) { // CString sUrl1 = lpCacheEntry->lpszSourceUrlName; if (sUrl1.Compare(s) == 0) { //处理 } // CTime lastModified(lpCacheEntry->LastModifiedTime); // CTime lastAccessed(lpCacheEntry->LastAccessTime); //a changed cookie - delete it! // if(lastModified >= m_time || lastAccessed >= m_time){ //const CString name = lpCacheEntry->lpszSourceUrlName; //const CString result = lastModified.Format("%I:%M:%S%p %d %b %Y"); //MessageBox (NULL, name + " last modified " + result, "Deleting cookie", MB_OK); //DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName); } //get ready for next entry dwTrySize = dwEntrySize; if(!FindNextUrlCacheEntry(hCacheDir,lpCacheEntry,&dwTrySize)) { dwError = GetLastError(); dwEntrySize = dwTrySize; //使用得到的新长度 } else { dwError = ERROR_SUCCESS; } break; //unknown error default: CString strError; strError.Format(_T("There is an error (%d) when trying deleting temporary internet files.\r\n"), dwError); TRACE(strError); bDone = TRUE; break; if(bDone) break; Sleep(10); if(lpCacheEntry){ delete [] lpCacheEntry; lpCacheEntry = NULL;} if(hCacheDir){ FindCloseUrlCache(hCacheDir); hCacheDir = NULL;} break; } } }
2、直接取某个URL对应的缓存资源
if (1)//这段代码可以直接从缓存找到对应URL的图片资源的路径 { CString s = dispImg.Get(L"src"); if (1) { LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = NULL; DWORD dwEntrySize = 4096; lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwEntrySize]; lpCacheEntry->dwStructSize = dwEntrySize; BOOL b = GetUrlCacheEntryInfo(s, lpCacheEntry, &dwEntrySize); CString sPath = lpCacheEntry->lpszLocalFileName; } }
3、在网页新建一canvas,将图片绘上,然后toDataURL,这样可以得到png格式的,经过base64编码后的字符串,该方法只能在ie9以上使用
if (0)//这段代码只能在IE9以上运行,可以将图片绘到canvas上,再取出png格式经base64编码后的数据 //然后解码,存到文件中,就得到一个png图片 //HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION //设置对应程序的dword值为10001为强制ie10,9999为强制ie9,8888为强制ie8 { CDispatch dispCanvas = disp.InvokePtr(L"createElement", L"canvas"); dispCanvas.Put(L"width", dispImg.Get(L"naturalWidth")); dispCanvas.Put(L"height", dispImg.Get(L"naturalHeight")); CDispatch dispCtx = dispCanvas.InvokePtr(L"getContext", L"2d"); dispCtx.Invoke(L"drawImage", dispImg.p, 0, 0); CString sData = dispCanvas.Invoke(L"toDataURL", L"image/png"); sData = sData.Right(sData.GetLength() - 22); int nBuffer = sData.GetLength() + 1; byte* buffer = new byte[nBuffer]; memset(buffer, 0, nBuffer); Base64Decode(sData, sData.GetLength(), buffer, &nBuffer); CFile f("1.png", CFile::modeCreate|CFile::modeWrite); f.Write(buffer, nBuffer); delete[] buffer; }