C/C++:Windows編程—Hook IE瀏覽器實現URL攔截及更改(下)

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

完整項目

完整項目這裏下載沒分可以github下載最新代碼(global_hook分支)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章