C 鉤子本執行緒內訊息攔截

2021-03-31 08:56:31 字數 4674 閱讀 5815

選擇自 xdev 的 blog

關鍵字[引用]c#鉤子本執行緒內訊息攔截

出處http://blog.csdn.***/yiruoyun/archive/2004/10/17/140219.aspx

鉤子其實就是呼叫一下api而已:

1、安裝鉤子:

setwindowshookex

函式原形:hhook setwindowshookex(

int       idhook,    // 鉤子型別,

hookproc  lpfn,      // 鉤子函式位址

instance  hmod,      // 鉤子所在的例項的控制代碼,

dword     dwthreadid // 鉤子所監視的執行緒的執行緒號

) hmod: 對於線程式鉤子,引數傳null;

對於系統鉤子:引數為鉤子dll的控制代碼

dwthreadid:對於全域性鉤子,該引數為null。

鉤子型別用wh_callwndproc=4(傳送到視窗的訊息。由sendmessage觸發)

返回:成功:返回setwindowshookex返回所安裝的鉤子控制代碼;

失敗:null;

2、**,你要截獲訊息就在這裡進行:

lresult winapi myhookproc(

int     ncode ,     // 指定是否需要處理該訊息

wparam  wparam,     // 包含該訊息的附加訊息

lparam  lparam      // 包含該訊息的附加訊息

)3、呼叫下乙個鉤子

lresult callnexthookex(

hhook   hhk,      // 是您自己的鉤子函式的控制代碼。用該控制代碼可以遍歷鉤子鏈

int     ncode,    // 把傳入的引數簡單傳給callnexthookex即可

wparam  wparam,   // 把傳入的引數簡單傳給callnexthookex即可

lparam  lparam    // 把傳入的引數簡單傳給callnexthookex即可

);4、用完後記得解除安裝鉤子哦,要不然你的系統會變得奇慢無比!

bool unhookwindowshookex(

hhook      hhk       // 要解除安裝的鉤子控制代碼。

)把上面這些api用c#封裝一下,就可以直接用了!

給個執行緒鉤子的例子吧(兩個form都在同乙個執行緒中執行):

using

system.runtime.interopservices;

public class form1 : system.windows.forms.form

//開始攔截

private bool starthook()

//停止攔截

private bool stophook()

//鉤子處理函式,在這裡攔截訊息並做處理

private int myhookproc(int code, intptr wparam, ref cwpstruct cwp)

break;

}return callnexthookex(hookhandle,code,wparam, ref cwp);

}[structlayout(layoutkind.sequential)]

public struct cwpstruct

}public class form2 : system.windows.forms.form

鉤子(hook),是windows訊息處理機制的乙個平台,應用程式可以在上面設定子程以監視指定視窗的某種訊息,而且所監視的視窗可以是其他程序所建立的。當訊息到達後,在目標視窗處理函式之前處理它。鉤子機制允許應用程式截獲處理window訊息或特定事件。

關於hook的詳細介紹,在微軟的msdn中有,http://.microsoft.***/china/***munity/program/originalarticles/techdoc/hook.mspx">http://.microsoft.***/china/***munity/program/originalarticles/techdoc/hook.mspx

下面是我在c#中來應用hook:

實現效果:

當使用者在textbox中輸入 b 的時候,textbox 始終顯示 a

實現過程:

2、在form1中,新增下面一些變數:  

internal enum hooktype //列舉,鉤子的型別

//msgfilter     = -1,

//journalrecord    = 0,

//journalplayback  = 1,

keyboard         = 2,

//getmessage       = 3,

//callwndproc      = 4,

//cbt              = 5,

//sy**sgfilter     = 6,

//mouse            = 7,

//hardware         = 8,

//debug            = 9,

//shell           = 10,

//foregroundidle  = 11,

//callwndprocret  = 12,

//keyboardll        = 13,

//mousell           = 14,

intptr _nexthookptr; //記錄hook編號

3、在form1中引入必須的api  

[dllimport("kernel32.dll")]

static extern int getcurrentthreadid(); //取得當前執行緒編號的api

[dllimport("user32.dll")]

internal extern static void unhookwindowshookex(intptr handle); //取消hook的api

[dllimport("user32.dll")]

internal extern static intptr setwindowshookex(int idhook, [marshalas(unmanagedtype.functionptr)] hookproc lpfn, intptr         hinstance, int threadid);  //設定hook的api

[dllimport("user32.dll")]

internal extern static intptr callnexthookex(intptr handle, int code, intptr wparam, intptr lparam); //取得下乙個hook的api

4、宣告乙個實現的委託

internal delegate intptr hookproc(int code, intptr wparam, intptr lparam);

5、新增自己的hook處理過程  

intptr myhookproc(int code, intptr wparam, intptr lparam)

if( code < 0 ) return callnexthookex(_nexthookptr,code, wparam, lparam); //返回,讓後面的程式處理該訊息           

if( wparam.toint32() == 98 || wparam.toint32() == 66 ) //如果使用者輸入的是 b

this.textbox1.text = "a";

return   (intptr) 1; //直接返回了,該訊息就處理結束了

else

return intptr.zero; //返回,讓後面的程式處理該訊息

6、新增加入hook鏈和從hook鏈中取消的函式

public void sethook()

if( _nexthookptr != intptr.zero ) //已經勾過了

return;

hookproc myhookproc = new hookproc(myhookproc); //宣告乙個自己的hook實現函式的委託物件

_nexthookptr = setwindowshookex((int)hooktype.keyboard, myhookproc , intptr.zero ,  getcurrentthreadid()); //加到hook鏈中

public void unhook()

if( _nexthookptr != intptr.zero )

unhookwindowshookex(_nexthookptr); //從hook鏈中取消

_nexthookptr = intptr.zero;

7、在form1的load事件中新增 sethook() , 在form1的closing 事件中新增 unhook()

private void form1_load(object sender, system.eventargs e)

sethook();

private void form1_closing(object sender, system.***ponentmodel.canceleventargs e)

unhook();

8、執行

輸入 b , 發現 textbox 裡面顯示的是 a 了!

C 鉤子本執行緒內訊息攔截

鉤子其實就是呼叫一下api而已 1 安裝鉤子 setwindowshookex 函式原形 hhook setwindowshookex int idhook,鉤子型別,hookproc lpfn,鉤子函式位址 instance hmod,鉤子所在的例項的控制代碼,dword dwthreadid 鉤...

C 鉤子本執行緒內訊息攔截

鉤子其實就是呼叫一下api而已 1 安裝鉤子 setwindowshookex 函式原形 hhook setwindowshookex int idhook,鉤子型別,hookproc lpfn,鉤子函式位址 instance hmod,鉤子所在的例項的控制代碼,dword dwthreadid 鉤...

C 鉤子本執行緒內訊息攔截

鉤子其實就是呼叫一下api而已 1 安裝鉤子 setwindowshookex 函式原形 hhook setwindowshookex int idhook,鉤子型別,hookproc lpfn,鉤子函式位址 instance hmod,鉤子所在的例項的控制代碼,dword dwthreadid 鉤...