BLOG main image
전체 (276)
[Computer] (42)
[Programming] (62)
[DBMS] (26)
[Operating System] (21)
[Study English] (8)
[For money] (28)
[Interest] (89)
«   2009/11   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          
77890 Visitors up to today!
Today 82 hit, Yesterday 46 hit
[폭주기관차, 2007/02/09 10:49, [Programming]/Visual C++ API/MFC]
Hook은 Local Hook과 Global Hook이 있는데

Local Hook : 하나의 Thread나 Process 안에서의 Hook
Global Hook : 전역의 모든 Process에 대한 Hook]

Local hook의 경우 전에 이 블로그에서 설명한 SubClassing이란 방법을 이용해서도 할
수 있기에 통과하기로 하고...

Global Hook에 대해 간단한 예제를 보여주도록 하겠다.

우선 제일 중요한 것은 Global Hook의 Procedure는 DLL로 작성이 되어야 한다.
그 이유에 대해서는 아직 나도 제대로 이해를 못했다.
완벽하게 이해가 되면 그때 다시 따로 올리도록 하겠다.
(이 글 밑에 보면 WinApi 완전정복이란 사이트에 있는 강좌글을 Link걸어놨다.
 그곳에서도 이유가 설명되어있으니 참고 바람.)

DLL Hook Procedure - DLL 파일
Hook Server - DLL파일을 Load해서 수행시킬 EXE파일

훅 과정을 텍스트로 간단하게 설명해보도록 하겠다.

키보드 입력 → 해당 Process의 WM_KEYDOWN


기본적으로 이렇게 돌아가지만 훅을 설치하게 되면

키보드 입력       해당 Process의 WM_KEYDOWN
             ↘                      ↑
              DLL Hook → Hook Server


이런 과정을 거치게 된다.


[DLL File]

#pragma data_seg(".kbdata")
HINSTANCE hModule=NULL;
HHOOK hKeyHook=NULL;
HWND hWndBeeper=NULL;
#pragma data_seg()
#pragma comment (linker, "/SECTION:.kbdata,RWS")

// 키보드 메세지가 발생하면 이 프로시져로 오게 된다.
LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
   if (nCode>=0) {
      SendMessage(hWndBeeper,WM_USER+1,wParam,lParam);
   }

   return CallNextHookEx(hKeyHook,nCode,wParam,lParam);
}

// 훅 설치, WH_KEYZBOARD는 키보드를 훅하겠다는 의미임
extern "C" __declspec(dllexport) void InstallHook(HWND hWnd)
{
   hWndBeeper=hWnd;

   hKeyHook=SetWindowsHookEx(WH_KEYBOARD,KeyHookProc,hModule,NULL);
}

extern "C" __declspec(dllexport) void UninstallHook()
{
   UnhookWindowsHookEx(hKeyHook);
}

// DLL이 메모리에 로딩 될 때 HINSTACNE를 공유 변수인 hModule에 저장한다.
// hModule은 훅을 설치 할때 필요로 한다.
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpRes)
{
   switch (fdwReason) {
   case DLL_PROCESS_ATTACH:
      hModule=hInst;
      break;
   case DLL_PROCESS_DETACH:
      break;
   }
   return TRUE;
}




가장 기본적인 코드다.

#pragma data_seg(".kbdata") ~ #pragma data_seg()
#pragma comment (linker, "/SECTION:.kbdata,RWS")
이 코드는 DLL을 호출하는 모든 Process에게서 공유변수로 작동하게 된다.
kbdata => 공유되는 섹션 이름으로 변경이 가능하나 대소문자 가리지 않고 최대 8자까지 가능하다.

이 DLL에서 하는 일은
훅을 설치해주고, 해제해주고, 키보드 입력이 발생하였을 경우 Hook Server로 WM_USER+1이란 메세지를
발생시켜주는 일을 한다.


[CPP File]

이제 CPP 파일에서는 그냥 프로그램 시작시 훅을 설치해주고 종료시 훅을 제거해주고
WM_USER+1의 메세지를 받았을 때 처리하는 Procedure만 만들어주면 된다.

아 그리고 DLL의 함수 원형이 선언된 Header파일을 Inlcude 해주어야 한다.


#include "DLL의 함수원형이 선언되어있는 Header 파일"

- WM_CREATE
      InstallHook(hWnd);

- WM_DESTROY
      UninstallHook();

- WM_USER+1
      KeyBoard 훅이 일어났을 때 취할 Procedure

키보드와 마우스 훅을 대부분 많이 이용하게 된다.
그외 훅에 대한 옵션(WH_...)은 MSDN에서 찾아 보면 된다.
아쉬운 점은 SubClassing처럼 모든 메세지를 다 받아오지 못하는 점이 있다.
아마 OS자체에서 Process간 침해를 주지 않게 하려고 막아놓은것 같다.
혹시 방법이 있다면 제발 좀 갈켜주세요~~~ㅜㅜ

참고
    WinApi 완전 정복 전역 훅 강좌 원문 보러 가기
    마우스훅에 관한 블로그 글  
    [Devpia - Visual C++ - 강좌&팁 - 번호 : 3647]

Trackback Address :: http://kongmks.cafe24.com/trackback/92
Name
Password
Homepage
Secret