日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

C#系統(tǒng)鉤子的實(shí)現(xiàn)

 guoliyan1 2012-02-16

C#系統(tǒng)鉤子的實(shí)現(xiàn)  

2011-04-23 10:40:37|  分類: c#——qq |字號 訂閱

看了很多資料,都提到系統(tǒng)鉤子(Hook)必須是一個dll,這樣Windows才能在所有進(jìn)程中共享鉤子代碼。

與鉤子相關(guān)的3個Windows API函數(shù)是:

SetWindowsHookEx、UnhookWindowsHookEx、CallNextHookEx,它們的簡要說明如下:

HHOOK SetWindowsHookEx( 
int  idHook, 
HOOKPROC lpfn, 
HINSTANCE hMod, 
DWORD dwThreadId); 

idHook -- 系統(tǒng)鉤子類型,實(shí)際上是一個int值,具體的定義請看MSDN

lpfn -- 鉤子回調(diào)函數(shù)指針,當(dāng)收到鉤子消息時就執(zhí)行這個回調(diào)函數(shù),回調(diào)函數(shù)有3個參數(shù),不同類型的鉤子這3個參數(shù)有不同的含義,具體請看MSDN。

hMod -- DLL實(shí)例句柄(我猜是這樣,我不熟悉Win32API編程),當(dāng)鉤子為系統(tǒng)鉤子時這個參數(shù)是必須的,如果是單個程序或者線程使用的鉤子那么可以不用這個值。

dwThreadId -- 線程ID,如果是單個程序或者線程使用的鉤子這個參數(shù)是必須的。

SetWindowsHookEx返回所設(shè)置的鉤子的句柄。

BOOL UnhookWindowsHookEx(HHOOK hhk);

hhk -- 所要注銷的鉤子的句柄

UnhookWindowsHookEx返回注銷鉤子是否成功。

LRESULT CallNextHookEx( 
HHOOK hhk, 
int  nCode, 
WPARAM wParam, 
LPARAM lParam); 

hhk -- 起始鉤子句柄,如果是在鉤子回調(diào)函數(shù)中調(diào)用CallNextHookEx時傳的通常是本鉤子句柄。

nCode -- 鉤子回調(diào)函數(shù)參數(shù)1,具體含義視鉤子類型而定。

wParam -- 鉤子回調(diào)函數(shù)參數(shù)2,具體含義視鉤子類型而定。

lParam -- 鉤子回調(diào)函數(shù)參數(shù)3,具體含義視鉤子類型而定。

從以上3個函數(shù)的簡要說明可以看出所用到的參數(shù)幾乎都是簡單的參數(shù),稍微復(fù)雜就是回調(diào)函數(shù)(在C#中用delegate類型來實(shí)現(xiàn),后面會提到),但是最讓人頭疼的就是DLL的實(shí)例句柄,C#制作的DLL并不像C做的DLL有DllMain入口可以接受到DLL實(shí)例句柄。

我目前唯一的辦法就是使用C做一個系統(tǒng)鉤子DLL再讓C#調(diào)用。底下是DLL的代碼。

#define  _WIN32_WINNT 0x0500 

#include 
< Windows.h >  
#include 
< WinUser.h >  

#define  Dll_Export __declspec(dllexport) 

/* DLL實(shí)例句柄 */  

HINSTANCE instance 
=  NULL; 

BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD  ul_reason_for_call, LPVOID lpReserved) 

 instance 
=  hInstance; 
    
return  TRUE; 
}
 

/*  
*功能:設(shè)置系統(tǒng)鉤子 
*hookType -- 鉤子類型 
*hookproc -- 鉤子回調(diào)函數(shù) 
*/
 

Dll_Export HHOOK SetHook(
int  hookType,HOOKPROC hookproc) 

 
return  SetWindowsHookEx(hookType, hookproc, instance, NULL); 
}
 

/*  
*功能:注銷鉤子 
*hook -- 鉤子句柄 
*/
 
Dll_Export BOOL UnHook(HHOOK hook) 

 
if (hook  !=  NULL) 
  
return  UnhookWindowsHookEx(hook); 
 
else  
  
return   0
}
 

然后在C#項目中創(chuàng)建一個系統(tǒng)鉤子類,提供創(chuàng)建鉤子和注銷鉤子的接口,代碼如下

public   class  Hook 

     [DllImport(
" LowLevelHook.dll " )] 
     
public   extern   static  IntPtr SetHook( int  hookType, HookProc hookProc); 

     [DllImport(
" LowLevelHook.dll " )] 
     
public   extern  staticbool UnHook(IntPtr hook); 
 }

 上面用到的User32.HookProc類型不是.NET框架提供的,是自己定義的一個委托類型,聲明如下

public   delegate   int  HookProc( int  nCode, IntPtr wParam, IntPtr lParam); 

現(xiàn)在你的C#程序就可以使用各種系統(tǒng)鉤子了,我們目前已經(jīng)使用的有低級別鼠標(biāo)鉤子和低級別鍵盤鉤子。

應(yīng)用低級別鼠標(biāo)鉤子時會遇到這樣一個問題:

低級別鼠標(biāo)鉤子的回調(diào)函數(shù)lParam是一個MSLLHOOKSTRUCT結(jié)構(gòu)體指針,C#中怎么獲取這個結(jié)構(gòu)體的實(shí)例呢?實(shí)現(xiàn)代碼如下

MSLLHOOKSTRUCT _mstr; 
unsafe

   _mstr 
=* (User32.MSLLHOOKSTRUCT * )lParam.ToPointer(); 
 }

通過聲明非安全代碼來獲取指針?biāo)笇ο蟆?

MSLLHOOKSTRUCT結(jié)構(gòu)體的C#定義如下:

[StructLayout(LayoutKind.Sequential)] 
public   struct  MSLLHOOKSTRUCT 

     
public  Point Point; 
     
public   int  MouseData; 
     
public   int  Flags; 
     
public   int  Time; 
     
public   int  ExtraInfo; 
 }

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多