C/C++:Windows编程—Hook IE浏览器实现URL拦截及更改(上)
Hook IE瀏覽器實現URL攔截及更改(上)
前言+思路
筆者這里有個需求,針對IE瀏覽器 用戶訪問URL 做一個判斷,是否為 限制訪問的url,如果是 在另一個軟件上給與警告提示。筆者在拿到這個需求的時候也是網上一頓找,在csdn上找到一篇 hook IE 總結。這篇文章給我一些思路,獲取IE瀏覽器訪問的URL 那么需要知道 IE瀏覽器訪問URL 用的那種方式,從這文章提示使用 WININET.dll庫中的方法。
然后我在一個windows開發群 提問題,有網友指點說,在ring3級別下最底層的網絡數據都會到達Ntdll.dll 中 NtDeviceIoControlFile這個方法。然后筆者當然 繼續搜索唄。在 網路上搜索到 看雪論壇上的一篇文章 另類掛鉤-RING3數據包監視 。筆者 當然如獲至寶呀,代碼都現成 拿過改改 不就行了?日期顯示代碼 是10年前的,使用的是 IAT HOOK的方式,代碼完全拿過來 稍微改了一點點 在WriteProcessMemory前后添加VirtualProtect 針對內存頁保護模式的修改,居然還能正常運行。最后測試結果 IE上的請求數據都能攔截到,但是 只有訪問http請求的時候 能看到數據的明文,此時能看到HTTP請求的URL,如果是HTTPS請求攔截到的數據都是經過加密的,如果自己來解密的話應該是相當地麻煩。所以還是不符合筆者的期望,況且 筆者不需要那么底層的數據,只要在用戶在地址欄 訪問后立馬攔截到就可以了。 此路不通,筆者只能再換一條路了。
經過漫長的搜索,沒有太多線索,筆者決定用OllyDbg斷點調試下 看能否發現線索。前面網上提示說IE瀏覽器 網絡請求用的WININET.dll庫,所以筆者在OD上 將 WININET.dll下與什么url、request、Internet相關的方法都打上斷點(這里筆者是在win7 x86 上調試IE進程,OD目前只能調試32位程序)。先將IE瀏覽器打開 然后用OD 附件到進程,讓后ctrl + g 輸入對應的方法,跟蹤表達式到達指定的位置然后f2打上斷點。
然后筆者在瀏覽器地址欄上輸入 www.baidu.com 然后回車,果然奇跡出現了 斷點 在WinInet.dll的InternetConnectW方法處停住了。
而且參數2 為URL!筆者趕緊查了下 InternetConnectW方法說明,在調此函數之前會調用一個InternetOpen函數,但是此函數沒有url相關參數。然后筆者 f9 繼續往后走,在一些方法的斷點也會停住 有url參數 也可以看到url的明文,所以從這里可以斷定 在進行網絡請求的時候 InternetConnectW方法已經是比較靠前的了!所以在這里hook 可以拿到訪問的URL 也比較符合筆者的期望。筆者在hook的時候 還走一點小彎路,因為之前用IAT hook的方式能hook到NtDeviceIoControlFile 筆者想 那我就用IAT hook的方式 來hook WININET.dll不就得了!但是是不行的 IAT方式是讀取PE頭,這種方式不能hook 動態加載的DLL!所以筆者使用 Inline hook的方式。因為要想運行我們自己的邏輯 要么代碼注入 要 DLL注入,DLL注入肯定少不了 。
實現效果
先看效果,csdn如果看不清 可以這個地址觀看https://www.bilibili.com/video/av81160225。
HOOK IE瀏覽器攔截URL效果
代碼實現
這里先說下,筆者的運行環境,win10-64位+VS2010+IE11。
由于筆者之前寫過 DLL注入的例子(Windows編程—DLL注入與卸載 ) 和 Inline Hook的例子(Windows編程—Inline Hook內聯鉤子(下) ),所以直接把之前的代碼拿過 稍微改改就能用了。這里我們驗證 還用到了另外2個軟件 Process Explorer (該軟件能查看當前進程所有的DLL,等會用來查看DLL注入和卸載是否成功),DebugView(我們注入的DLL中使用OutputDebugString這種方式打印日志,可以通過DebugView工具查看),示例demo可以在這里下載,也可在github下載最新代碼,如果可以的話,幫忙點個星星喲。
我們要注入的DLL代碼。其實代碼很簡單就是 DLL注入和Inline Hook的結合,基礎牢固,思路正確,做起來還是比較容易的。
#include "stdafx.h" #include <Windows.h> #include <Wininet.h> #pragma comment(lib,"wininet.lib")#include "InlineHook7.h"CInlineHook7 g_inlineHookObj7;typedef HINTERNET ( WINAPI *InternetConnectWFunc)(HINTERNET hInternet,LPCWSTR lpszServerName,INTERNET_PORT nServerPort,LPCWSTR lpszUserName,LPCWSTR lpszPassword,DWORD dwService,DWORD dwFlags,DWORD_PTR dwContext);HINTERNET WINAPI MyInternetConnectW(HINTERNET hInternet,LPCWSTR lpszServerName,INTERNET_PORT nServerPort,LPCWSTR lpszUserName,LPCWSTR lpszPassword,DWORD dwService,DWORD dwFlags,DWORD_PTR dwContext) {g_inlineHookObj7.UnHook(); // 必須先卸載鉤子 再才可以再次調用被Hook的函數,不然會進入死循環HINTERNET ret = NULL;CString temp;temp.Format(_T("攔截到url:%s"),lpszServerName);CString url = lpszServerName;if(url.Find(_T("baidu.com")) >= 0){url = _T("www.sogou.com");}OutputDebugString(temp);// 這里要用已經存在的庫,不要再在自己的庫中鏈接WININET.dll庫去使用//ret = ::InternetConnectW(hInternet, lpszServerName, nServerPort, lpszUserName, lpszPassword, dwService, dwFlags, dwContext);HMODULE hModule = GetModuleHandle(_T("WININET.dll"));if(hModule == NULL){OutputDebugString(_T("GetModuleHandle false"));goto end;}InternetConnectWFunc func = (InternetConnectWFunc)GetProcAddress(hModule,"InternetConnectW");if(func == NULL){OutputDebugString(_T("GetProcAddress false"));goto end;}ret = func(hInternet, url, nServerPort, lpszUserName, lpszPassword, dwService, dwFlags, dwContext);end:g_inlineHookObj7.ReHook();return ret; }VOID InlineHookIE() {OutputDebugString(_T("InlineHookIE into"));g_inlineHookObj7.Hook("WININET.dll","InternetConnectW",(FARPROC)MyInternetConnectW);return; }VOID UnInlineHookIE() {OutputDebugString(_T("UnInlineHookIE into"));g_inlineHookObj7.UnHook();return; }// DLL 入口 BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) {switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:{InlineHookIE();}break;case DLL_PROCESS_DETACH:UnInlineHookIE();break;}return TRUE; }待優化部分
這個demo,只能在IE瀏覽器打開后,再點注入到hook 才會注入到運行的ie進程中。后續會優化成 我們的demo程序只要運行了,當IE瀏覽器被打開,demo程序自動注入DLL,后面當用戶 再次打開新的標簽頁或者IE進程我們也自動注入我們寫的DLL 這樣才是最完美的。
============== 待優化部分已經下面這篇博客寫了 ==================
C/C++:Windows編程—Hook IE瀏覽器實現URL攔截及更改(下)
總結
以上是生活随笔為你收集整理的C/C++:Windows编程—Hook IE浏览器实现URL拦截及更改(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 函数参数类型判断(判断类型
- 下一篇: C/C++语言以某符号分割字符串