最近研究怎么樣使用HOOK攔截其他應(yīng)用程序的消息,于是就動手寫了一個鉤子程序來掛到最常用的通訊及時通訊工具MSN,,雖然沒有什么實際意義,但作為學(xué)習(xí)研究卻能夠幫助我們理解利用HOOK是怎么樣將自己編寫的DLL注入已經(jīng)存在的程序空間中的,。
我們需要做的是通過我們自己編寫的應(yīng)用程序去攔截別人寫好的應(yīng)用程序消息,,實際上這是在兩個進程之間進行的,,難度就在這里,如果是同一個進程什么都好辦,,只要將系統(tǒng)響應(yīng)WINDOWS消息的處理函數(shù)修改為我們自己編寫的函數(shù)就可以,但現(xiàn)在不能這么做,,因為兩個進程有各自的進程地址空間,,理論上你沒有辦法直接去訪問別的進程的地址空間,那么怎么辦來,?辦法還是很多的,,這里僅僅介紹通過HOOK來達到目的。
需要攔截別的應(yīng)用程序的消息,,需要利用將自己編寫的DLL注入到別人的DLL地址空間中才可以達到攔截別人消息的目的,。只有將我們的DLL插入到別的應(yīng)用程序的地址空間中才能夠?qū)e的應(yīng)用程序進行操作,HOOK幫助我們完成了這些工作,,我們只需要使用HOOK來攔截指定的消息,,并提供必要的處理函數(shù)就行了。我們這里介紹攔截在MSN聊天對話框上的鼠標(biāo)消息,,對應(yīng)的HOOK類型是WH_MOUSE,。
首先我們要建立一個用來HOOK的DLL。這個DLL的建立和普通的DLL建立沒有什么具體的區(qū)別,,不過我們這里提供的方法有寫不同,。這里使用隱式導(dǎo)入DLL的方法。代碼如下:
頭文件
#pragma once
#ifndef MSNHOOK_API
#define MSNHOOK_API __declspec(dllimport)
#endif
MSNHOOK_API BOOL WINAPI SetMsnHook(DWORD dwThreadId);//安裝MSN鉤子函數(shù)
MSNHOOK_API void WINAPI GetText(int &x,int &y,char ** ptext);//安裝MSN鉤子函數(shù)
MSNHOOK_API HWND WINAPI GetMyHwnd();//安裝MSN鉤子函數(shù)
==================================================
DLL 的CPP文件
#include "stdafx.h"
#include "MSNHook.h"
#include <stdio.h>
// 下面幾句的含義是告訴編譯器將各變量放入它自己的數(shù)據(jù)共享節(jié)中
#pragma data_seg("Shared")
HHOOK g_hhook = NULL;
DWORD g_dwThreadIdMsn = 0;
POINT MouseLoc={0,0};
char text[256]={0};
HWND g_Hwnd = NULL;
#pragma data_seg()
//告訴編譯器設(shè)置共享節(jié)的訪問方式為:讀,,寫,,共享
#pragma comment(linker,"/section:Shared,rws")
HINSTANCE g_hinstDll = NULL;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hinstDll = (HINSTANCE)hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
LRESULT WINAPI GetMsgProc(int nCode,WPARAM wParam, LPARAM lParam);
BOOL WINAPI SetMsnHook(DWORD dwThreadId)
{
OutputDebugString("SetMsnHook");
BOOL fOK = FALSE;
if(dwThreadId != 0)
{
OutputDebugString("SetMsnHook dwThreadId != 0");
g_dwThreadIdMsn = GetCurrentThreadId();
//安裝WM_MOUSE鉤子和處理函數(shù)GetMsgProc
g_hhook = SetWindowsHookEx(WH_MOUSE,GetMsgProc,g_hinstDll,dwThreadId);
fOK = (g_hhook != NULL);
if(fOK)
{
fOK = PostThreadMessage(dwThreadId,WM_NULL,0,0);
}
else
{
fOK = UnhookWindowsHookEx(g_hhook);
g_hhook = NULL;
}
}
return(fOK);
}
LRESULT WINAPI GetMsgProc(int nCode,WPARAM wParam, LPARAM lParam)
{
char temp[20];
sprintf(temp,"%d\n",nCode);
OutputDebugString("temp");
if (nCode==HC_ACTION)
{
MOUSEHOOKSTRUCT *l=(MOUSEHOOKSTRUCT *)lParam;
MouseLoc=l->pt; //送鼠標(biāo)位置
//char text[256] = "";
HWND hWnd = WindowFromPoint(l->pt);
if(hWnd)
{
//GetWindowText(hWnd,text,256);
SendMessage(hWnd,WM_GETTEXT,256,(LPARAM)(LPCTSTR)text);
// strcpy(text,"123455555");
SendMessage(hWnd,WM_SETTEXT,256,(LPARAM)(LPCTSTR)text);
g_Hwnd = hWnd;
}
//SendMessage(WindowFromPoint(l->pt),WM_GETTEXT,256,(LPARAM)(LPCTSTR)psw);
}
return(CallNextHookEx(g_hhook,nCode,wParam,lParam));
}
void WINAPI GetText(int &x,int &y,char ** ptext)
{
x = MouseLoc.x;
y = MouseLoc.y;
*ptext = text;
}
HWND WINAPI GetMyHwnd()
{
return g_Hwnd;
}
上面是處理鉤子的DLL代碼,下面我們要讓這個DLL起作用還需要一個啟動部分,,通過這個啟動部分我們才能讓我們的鉤子函數(shù)真正的注入到系統(tǒng)其他函數(shù)中,。我們這里使用個對話框的程序,程序非常簡單:一個按鈕用來啟動鉤子,,一個用來停止,,一個TIMER用來刷新顯示,還有一個EDITBOX用來接受信息,。
程序如下:
//包含DLL函數(shù)導(dǎo)出的頭文件
#include "MSNHook.h"
//隱式導(dǎo)入
#pragma comment(lib,"MSNHook.lib")
//聲明導(dǎo)入函數(shù)
__declspec(dllimport) BOOL WINAPI SetMsnHook(DWORD dwThreadId);
__declspec(dllimport) void WINAPI GetText(int &x,int &y,char ** ptext);
__declspec(dllimport) HWND WINAPI GetMyHwnd();//安裝MSN鉤子函數(shù)
void CTestMSNHookDlg::OnBnClickedOk()
{
//通過SPY++可以看到MSN聊天對話框窗口類是IMWindowClass,,通過這個得到該窗口句柄
CWnd *pMsnWin = FindWindow(TEXT("IMWindowClass"),NULL);
if(pMsnWin == NULL) return ;
//通過窗口句柄得到對應(yīng)的線程的ID
SetMsnHook(GetWindowThreadProcessId(pMsnWin->GetSafeHwnd(),NULL));
MSG msg;
GetMessage(&msg,NULL,0,0);
SetTimer(101,100,NULL);
}
void CTestMSNHookDlg::OnTimer(UINT_PTR nIDEvent)
{
//刷新消息
char * pText = NULL;
int x = 0,y = 0;
GetText(x,y,&pText);
if(x ==0 && y ==0) return ;
m_Edit.Format("%d:%d:%s",x,y,pText);
//m_Edit = pText;
UpdateData(FALSE);
HWND hWnd = GetMyHwnd();
CWnd * pWnd = CWnd::FromHandle(hWnd);
pWnd->GetWindowText(m_Edit);
CDialog::OnTimer(nIDEvent);
}
void CTestMSNHookDlg::OnBnClickedButton1()
{
//關(guān)閉
KillTimer(101);
SetMsnHook(0);
OnCancel();
}
好了,基本上就這些了,。這里有個問題,,我本想得到MSN用戶聊天時輸入的聊天信息,,這里通過WM_GETTEXT消息的不到,如果有知道的朋友告訴一聲,。