티스토리 뷰

후킹예제
오전 1:42 2000/10/05
조경민
Global Hooking in Win32
====================================================

후크에는 두가지가 있다.
Local Hook - 하나의 스레드나 프로세스 안에서의 후킹
Global Hook - 전역 모든 윈도우들에 대한 후킹

후크를 하기 위해서는 기본적으로 두가지 자료형을 알아야 한다.
HHOOK - 후크 핸들 윈도우 시스템에서 한번 이벤트가
발생하면 후크 체인의 첫 후크핸들에게 이벤트를
넘긴다. 각 후크들은 다음 후크를 호출하여 후크체인에
있는 모든 후크 프로시져를 호출하게 된다.
HOOKPROC - 후크 프로시져로 후크시 호출되는 프로시져이다.
LRESULT CALLBACK fnHookProc(int nCode, WPARAM wParam, LPARAM lParam)
라는 자료형을 갖는다.

1. 로컬 후킹
SetWindowHookEx를 이용하면 간단히 구현이 가능하다.
각 후크는 후크 타입이 있는데 아래와 같다.
WH_CALLWNDPROC - 윈도우 메세지가 목적지로 전달되기 전에
메세지를 후크할때 쓴다 (SendMessage)
CallWndProc라는 후크프로시져명의 도움말 참조한다.
WH_CALLWNDPROCRET - 윈도우 메세지가 목적지에 전달되어 처리
된 후 후크가 일어난다
CallWndRetProc함수명 도움말 참조
WH_CBT - computer-based training (CBT) application 에 유용한
후크 타입 CBTProc 함수 참조
WH_DEBUG - 디버깅에 유용한 후크 DebugProc 참조
WH_FOREGROUNDIDLE - Foreground상태있는 윈도우가 idle상태로 들어갈
때 생기는 후크 이는 idle시 낮은 우선순위
(low priority)를 줄때 유용하다 ForegroundIdleProc
WH_GETMESSAGE - 메세지가 Post된 후 후크됨 (PostMessage)
GetMsgProc 함수 참조
WH_JOURNALPLAYBACK - WH_JOURNALRECORD에 의해서 Record되기 전에
일어나는 후크 JournalPlaybackProc
WH_JOURNALRECORD - Input message가 시스템 메세지 큐로 들어가는것을
Record하는 후크 JournalRecordProc
WH_KEYBOARD - 등등이 있다.... -_- 도움말 참조..


--------------------- 로컬 후크 예제 ------------------------------
HHOOK hHook;
HOOKPROC hProc;
:
hProc = CallWndProc; // CallWndProc 후크 프로시져로 연결
hHook = ::SetWindowsHookEx( // 후크를 설치한다. ( 후크체인에 끼워넣는다 )
WH_CALLWNDPROC, // WH_CALLWNDPROC 후크 설치
hProc, // 후크차례가 오면 분기되는 콜백후크 프로시져
(HINSTANCE) NULL, // 전역 후크가 아닌 로컬 후크임을 말한다
dwTreadID); // 특정 스레드를 정한다 0 이면 현재 스레드


만일 여러 스레드중 한 HWND가 속한 스레드를 얻고 싶으면
DWORD dwProcessID = NULL;
DWORD dwTreadID = ::GetWindowThreadProcessId( hWnd, &dwProcessID );

if( dwProcessID )
{
:
후크 설치코드 맨 마지막인자에 dwThreadID를 넣으면 된다.
}

// 자세한 프로시져 도움말을 보면 자세히 알수 있다.
LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* lpWp = (CWPSTRUCT*)lParam;
//PMSG lpMsg = (PMSG)lParam;
if (nCode < 0 && hWnd == lpWp->hwnd ) // do not process message
return CallNextHookEx(m_stHookCallProc.hHook, nCode, wParam, lParam);

switch( lpWp->message )
{
case EM_REPLACESEL :
TRACE("CallWndProc EM_REPLACESEL %srn ", (char*)lpWp->lParam );
break;

default :
break;
}
return CallNextHookEx(m_stHookCallProc.hHook, nCode,
wParam, lParam);
}

2 전역 후킹
전역 후킹을 하기 위해서는 후크 프로시져를 dll안에 넣어야 한다.



--------------------- 전역 후크 예제 --------------------------

testdll.dll 에서 ............

// dll에서 쓰는 자료는 dll공유를 했다.
// 이 후크 프로시져 dll은 내 프로그램에서 쓰이기도 하지만
// 시스템에 의해서 이 dll이 또 열리게 된다. ( dll의 참조카운트 증가
// 가 일어나지 않고 새로 dll이 생긴다. 따라서 두 dll은 자료가
// 분리되어 있는 셈이다. )
// 그러므로 부득이 하게 자료를 공유자료로 해야 한다.
#pragma data_seg(".shared")
HHOOK _hHook = NULL;
HWND _hTarget = NULL;
#pragma data_seg()
// 공유 자료로 했을 경우 아래처럼 링커 옵션도 주어야 한다.
#pragma comment(linker, "/SECTION:.shared,RWS")

// 자료 억세스 함수 마련...
extern "C" __declspec(dllexport) void fnSetHook( HHOOK hHook )
{
_hHook = hHook;
}

extern "C" __declspec(dllexport) void fnSetHWND( HWND hWnd )
{
_hTarget = hWnd;
char szBuf[20];
wsprintf( szBuf, "%lu", (ULONG)_hTarget );
MessageBox( NULL, szBuf, "fnSetHWND당시의 _hTarget값", MB_OK);
}

extern "C" __declspec(dllexport) HHOOK fnGetHook()
{
return _hHook;
}

// 콜백을 위한 CALLBACK 콜링컨벤션 키워드를 넣게 되면 나중에 GetAddressProc시
// NULL값을 리턴하므로 그냥 콜링컨벤션을 무시했다
//extern "C" __declspec(dllexport) LRESULT CALLBACK fnCallWndProc(int nCode, WPARAM wParam, LPARAM
lParam)
extern "C" __declspec(dllexport) LRESULT fnCallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* lpWp = (CWPSTRUCT*)lParam;

if( nCode >= 0 ) //&& _hTarget == lpWp->hwnd ) // do not process message
{
switch( lpWp->message )
{
case EM_REPLACESEL :
if( _hTarget == lpWp->hwnd )
{
MessageBox( NULL, "EM_REPLACESEL 메세지 발쌩", "메세지 발쌩in
dll", MB_OK);
}
break;

default :
break;
}
}
return CallNextHookEx( _hHook, nCode, wParam, lParam);
}


내 프로그램에서 .........................
HINSTANCE hInstDll = NULL
HHOOK hHook = NULL;

// dll을 연다.
hInstDll = LoadLibrary("TestDll.dll");
if( hInstDll )
{
// 후크 프로시져를 찾아낸다.
LRESULT (*hHookDllProc)(int, WPARAM, LPARAM ) = (LRESULT (*)(int, WPARAM, LPARAM ))
GetProcAddress(hInstDll, "fnCallWndProc");
if( hHookDllProc ) // 있으면 후크를 설치한다.
hHook = SetWindowsHookEx( WH_CALLWNDPROC, (HOOKPROC)hHookDllProc, hInstDll, 0);

// dll내의 자료를 세팅한다. HHOOK와 HWND 값 세팅
void (*lpfnSetHook)(HHOOK) = (void (*)(HHOOK))GetProcAddress(hInstDll, "fnSetHook");
if( lpfnSetHook )
(*lpfnSetHook)( hHook );
void (*lpfnSetHWND)(HWND) = (void (*)(HWND))GetProcAddress
(hInstDll, "fnSetHWND");
if( lpfnSetHWND )
(*lpfnSetHWND)( m_hTarget );
}

'보안 > 일반' 카테고리의 다른 글

Term : Fire Sale  (0) 2009.07.14
악성코드 여부를 확인하는 방법 >> 온 세상의 AV 업체를 통해 진단해봐~  (0) 2008.06.05
About Hooks  (0) 2008.01.21
Win32 Hooks  (0) 2008.01.21
주제: Win32 API훅 강좌... [작성자 codewiz]  (0) 2008.01.16
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
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 31
글 보관함