Hook IE瀏覽器實現URL攔截及更改(下)
前言
接上一篇 C/C++:Windows編程—Hook IE瀏覽器實現URL攔截及更改(上),本節爲了實現上一篇待優化部分。實現IE進程時時監控,當有新的IE進程打開時注入我們的動態庫。如何使用時時監控IE進程呢?笨方法就是 開一個線程 一直去遍歷 IE進程 發現有新的IE進程就注入。這種方法有點low,筆者當然不想用,所以在網絡上尋找,有說在驅動層去監控,筆者目前驅動還不怎麼會 當然放棄驅動層了。後面在這篇博客 https://blog.csdn.net/maoenpei002/article/details/5358601 給了我思路使用 Windows 全局鉤子!Windows鉤子應該是最簡單的hook方式,主要是針對GUI程序 帶消息機制的程序。
運行效果
筆者運行環境爲 win10 64位 IE11
嗶哩嗶哩視頻運行效果可以這裏看
HOOK IE瀏覽器攔截URL效果(下)
代碼
這裏代碼就是根據我們需要時時監控IE進程寫的 Windows全局鉤子的DLL的代碼。
#include "stdafx.h"
#include "MsgHook.h"
#include <Windows.h>
HMODULE g_hModule ;
HHOOK g_hook = NULL;
LRESULT CALLBACK HookProc(
int code, // hook code
WPARAM wParam, // removal option
LPARAM lParam // message
)
{
if(g_hook)
{
return CallNextHookEx(g_hook,code,wParam,lParam);
}
return 1;
}
void SetMsgHookOn()
{
OutputDebugString(_T("===== SetMsgHookOn enter===== \n"));
g_hook = SetWindowsHookEx(WH_GETMESSAGE,HookProc,g_hModule,0);
if(g_hook == NULL )
{
DWORD errCode = GetLastError();
CString errMsg = CUtility::GetErrorMsg(errCode);
CString temp;
temp.Format(_T("SetWindowsHookEx false!!!errCode:%d,errMsg:%s\n"),errCode,errMsg);
OutputDebugString(temp);
}
}
void SetMsgHookOff()
{
OutputDebugString(_T("===== SetMsgHookOff enter =====\n"));
CString temp;
temp.Format(_T("Cur Exe:%s\n"),CUtility::GetCurExeName());
OutputDebugString(temp);
BOOL ret = FALSE;
if(g_hook)
{
ret = UnhookWindowsHookEx(g_hook);
}
if(ret == FALSE)
{
DWORD errCode = GetLastError();
CString errMsg = CUtility::GetErrorMsg(errCode);
CString temp;
temp.Format(_T("UnhookWindowsHookEx false!!!errCode:%d,errMsg:%s\n"),errCode,errMsg);
OutputDebugString(temp);
}
}
// 下的全局鉤子被系統強勢注入到進程中後通知你的目標程序
void NotifyYourApp(BOOL bTatch)
{
HWND targetWnd = FindWindow(_T("#32770"),MAIN_APP_TITLE);
//HWND targetWnd = FindWindow(_T("Notepad"),NULL);
if(targetWnd == NULL)
{
OutputDebugString(_T("target exe not found"));
// 目標程序都沒啓動,捕獲沒用處,取消全局鉤子
SetMsgHookOff();
return;
}
CString exeName = CUtility::GetCurExeName();
if(exeName.CompareNoCase(_T("iexplore.exe")) == 0)
{
if(bTatch)
{
OutputDebugString(_T("HookProcDll.dll Attach iexplore.exe"));
}
else
{
OutputDebugString(_T("HookProcDll.dll Detach iexplore.exe"));
}
// 當前注入的進程爲IE瀏覽器,通知目標程序,將進程ID發給目標程序
DWORD processId = GetProcessId(GetCurrentProcess());
BOOL ret = PostMessage(targetWnd,WM_IE_OPEN,bTatch,(LPARAM)processId);
if(ret == FALSE)
{
DWORD errCode = GetLastError();
CString errMsg = CUtility::GetErrorMsg(errCode);
CString temp;
temp.Format(_T("PostMessage failed!!!errCode:%d,errMsg:%s"),errCode,errMsg);
OutputDebugString(temp);
}
}
}
// DLL 入口
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
g_hModule = hModule;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
NotifyYourApp(TRUE);
}
break;
case DLL_PROCESS_DETACH:
{
// 什麼情況 鉤子DLL會被卸載?當Windows全局鉤子被卸載後 系統會卸載該DLL,程序主動退出也會卸載該DLL
NotifyYourApp(FALSE);
}
break;
}
return TRUE;
}