精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>C/C++>>技术精解:内存、进程、线程等>>系统钩子应用实例

主题:系统钩子应用实例
发信人: tengel()
整理人: wenbobo(2002-12-06 23:07:00), 站内信件
系统钩子的应用
----我的拙见,请网友多指教

对于Win32程序来说,应用程序各自拥有虚拟的4G地址空间,增强
了应用程序之间的独立性.但是也给编程者带来了问题,如:如何
是我的一段代码到另外一个应用程序的地址空间去执行,使用
Win32系统钩子是一个比较简单的方法.
钩子的安装,卸载,是通过使用:
SetWindowsHookEx和UnhookWindowsHookEx两个函数来实现的,
具体的参数如下:
The SetWindowsHookEx function installs an application-defined hook pro
cedure into a hook chain. You would install a hook procedure to monito
r the system for certain types of events. These events are associated 
either with a specific thread or with all threads in the system. 

HHOOK SetWindowsHookEx(
  int idHook,        // type of hook to install
  HOOKPROC lpfn,     // address of hook procedure
  HINSTANCE hMod,    // handle to application instance
  DWORD dwThreadId   // identity of thread to install hook for
);

The UnhookWindowsHookEx function removes a hook procedure installed in
 a hook chain by the SetWindowsHookEx function. 

BOOL UnhookWindowsHookEx(
  HHOOK hhk   // handle to hook procedure to remove
);

以上内容摘自MSDN

钩子分为局部钩子和系统钩子两种,对于局部钩子,只对特定线程起作用,
而系统钩子,则对系统内任何进程和线程起作用.
一旦安装了系统钩子,钩子函数就能够进入到安装函数所指定的线程内运行
访问该线程所在进程内存空间.这实际上也就在一定程度上实现了进程的跨
边界访问.对于系统线程,必须在DLL中.

一个应用的例子:
当我第一次使用PCanywhere时,我很惊讶于,他竟能够把光标指针的形状传
递到另外一台计算机上去,我们采用GDI方法截取屏幕一般并不能够把光标
指针的图形也截取下来,那么怎么才能得到光标指针的图形呢?
一般在一个应用程序中,我们可以通过以下方法取得光标位图:
hCur=GetCursor();
DrawIcon到一个内存设备环境里面

但是并不能够得到另外进程的光标位图,因为光标对象是GDI对象,在其他
进程中不可见.如果使用系统钩子呢?当然可以.
我们为了试验,先安装一个WH_GETMESSAGE系统钩:
hHook=SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,HINSTANCE(hmod),NULL)
;

在GetMsgProc中,你需要的的时候作如下处理:
HCURSOR hCur=GetCursor();
HBITMAP hBmp;
HWND hDeskWnd=GetDesktopWindow();
HDC hDC=::GetDC(hDeskWnd);
HDC hmemDC=::CreateCompatibleDC(hDC);
hBmp=::CreateCompatibleBitmap(hDC,32,32);
::SelectObject(hmemDC,hBmp);
::DrawIconEx(hmemDC,0,0,hCur,32,32,0,NULL,DI_DEFAULTSIZE|DI_IMAGE);

::GetDIBits(hmemDC,hBmp,0,32,pdwBitmap,(LPBITMAPINFO)&bmpih,DIB_RGB
_COLORS);
::DeleteObject(hBmp);
::DeleteDC(hmemDC);
::ReleaseDC(hDeskWnd,hDC);

那么在pdwBitmap数组中存放的就是光标的位图数组,为了让其他应用程序能
够访问到该数组,只需要把他定义到DLL的共享数据段或者采用内存映像文件
之类.

--
                                           _
   O           @___       G               : \  
  /|__       /|/         /\|\             :  \
 /|/_       / /\         \ X_             :   \
  /  |     __/  \          | \      0     :    \
 /    0        0|          /              :     \

※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.104.33.10]

[关闭][返回]