검색결과 리스트
메세지 후킹에 해당되는 글 2건
글
Introduction
오늘은 Global Hooking 이라 불리는 전역후킹에 대해서 알아보도록 하겠습니다.
아시다시피 Windows 는 Event Driven 방식으로 되어 있습니다.
후킹이라 하면 이벤트가 Windows Message Queue 에서 Application Message Queue 로 넘어갈 때,
메세지를 중간에서 Hook 하는 것을 의미합니다.
Prepare
전역 후킹을 하는 방법을 간단히 설명드리면 다음과 같습니다.
[필요한 것]
1. 어떤 메세지를 후킹할 것인가?
2. 메세지를 후킹했을 때, 원하는 작업을 수행할 함수.
3. 그리고 그 함수를 포함한 DLL 파일
4. 이 후킹 작업을 해 줄 프로그램(exe)
[사용할 API]
1. LoadLibrary
HMODULE WINAPI LoadLibrary(
__in LPCTSTR lpFileName
);
- dll 을 load 할 때 사용__in LPCTSTR lpFileName
);
2. GetProcAddress
FARPROC WINAPI GetProcAddress(
__in HMODULE hModule,
__in LPCSTR lpProcName
);
- dll 내부에 함수의 포인터를 구할 때 사용__in HMODULE hModule,
__in LPCSTR lpProcName
);
3. CallNextHookEx
LRESULT WINAPI CallNextHookEx(
__in_opt HHOOK hhk,
__in int nCode,
__in WPARAM wParam,
__in LPARAM lParam
);
- 메세지 후킹 후, 메세지를 다음 chain 으로 전달할 때 사용__in_opt HHOOK hhk,
__in int nCode,
__in WPARAM wParam,
__in LPARAM lParam
);
4. SetWindowsHookEx
HHOOK WINAPI SetWindowsHookEx(
__in int idHook,
__in HOOKPROC lpfn,
__in HINSTANCE hMod,
__in DWORD dwThreadId
);
- Windows Hook 을 할 때 사용__in int idHook,
__in HOOKPROC lpfn,
__in HINSTANCE hMod,
__in DWORD dwThreadId
);
5. UnhookWindowsHookEx
BOOL WINAPI UnhookWindowsHookEx(
__in HHOOK hhk
);
- Hook 을 끝낼 때(chain 에서 빼낼때) 사용__in HHOOK hhk
);
Code
본격적으로 프로그램을 만들어 봅시다.
만들어 볼 프로그램은 다음과 같습니다.
프로그램은 Keyboard 의 메세지를 후킹합니다. 만약 사용자가 키보드에서 'm' 키를 누르면, MessageBox 를 띄웁니다.
간단한 프로그램이므로 Assembly 로 만들어 보겠습니다.
먼저 Hooking 한 메세지를 처리 할 함수와 해당 dll을 만들도록 합시다.
.386
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE
INCLUDE windows.inc
INCLUDE gdi32.inc
INCLUDE user32.inc
INCLUDE kernel32.inc
INCLUDELIB gdi32.lib
INCLUDELIB user32.lib
INCLUDELIB kernel32.lib
.DATA
szCaption db "CrystalCube", 0
szMessage db "Don't Press 'M' Key!", 0
.DATA?
g_hInstance HINSTANCE ?
g_hHook HHOOK ?
.CODE
DllEntry proc hinstDLL:HINSTANCE, dwReason:DWORD, lpvReserved:DWORD
cmp dwReason, DLL_PROCESS_ATTACH
jne EXIT
mov ebx, hinstDLL
mov g_hInstance, ebx
EXIT:
mov eax, TRUE
ret
DllEntry Endp
KeyboardHook proc nCode:DWORD, wParam:WPARAM, lParam:LPARAM
push eax
mov eax, lParam
or eax, 00FFFFFFh
.if (nCode == HC_ACTION && eax != 0C0FFFFFh)
cmp wParam, VK_M
JNE EXIT
mov ebx, lParam
and ebx, 80000000h
cmp ebx, 0
JNE EXIT
push MB_OK
push offset szCaption
push offset szMessage
push NULL
call MessageBox
.endif
EXIT:
push lParam
push wParam
push nCode
push g_hHook
call CallNextHookEx
ret
KeyboardHook endp
InstallHook proc
push 0
push g_hInstance
push KeyboardHook
push WH_KEYBOARD
call SetWindowsHookEx
mov g_hHook, eax
ret
InstallHook endp
UninstallHook proc
push g_hHook
call UnhookWindowsHookEx
mov g_hHook, NULL
ret
UninstallHook endp
End DllEntry
물론 Export 시키기 위해서 DEF 파일도 만들어 주어야 합니다.
LIBRARY KeyboardHook
EXPORTS InstallHook
EXPORTS UninstallHook
이렇게 dll 파일이 완성되었습니다.
그럼 이제 후킹을 걸어줄 Test Application 을 만들어 보죠.
.386
.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE
INCLUDE D:\masm32\include\windows.inc
INCLUDE D:\masm32\include\gdi32.inc
INCLUDE D:\masm32\include\user32.inc
INCLUDE D:\masm32\include\kernel32.inc
INCLUDE D:\masm32\include\msvcrt.inc
INCLUDELIB D:\masm32\lib\gdi32.lib
INCLUDELIB D:\masm32\lib\user32.lib
INCLUDELIB D:\masm32\lib\kernel32.lib
INCLUDELIB D:\masm32\lib\msvcrt.lib
.DATA
szDllName db "GlobalHook.dll", 0
szHookInstall db "InstallHook", 0
szHookUninstall db "UninstallHook", 0
szStartMsg db "Hooking Started!", 13, 10, 0
szHelp db "Press 'q' to quit!", 13, 10, 0
.DATA?
hDll HMODULE ?
pInstallFunc dd ?
pUninstallFunc dd ?
.CODE
start:
push offset szDllName
call LoadLibrary
mov hDll, eax
push offset szHookInstall
push hDll
call GetProcAddress
mov pInstallFunc, eax
push offset szHookUninstall
push hDll
call GetProcAddress
mov pUninstallFunc, eax
call [pInstallFunc]
push offset szStartMsg
call crt_printf
push offset szHelp
call crt_printf
INPUT:
call crt__getch
cmp eax, 'q'
jne INPUT
call [pUninstallFunc]
push hDll
call FreeLibrary
push NULL
call ExitProcess
end start
코드가 정리가 되어있지 않아 조금 복잡해 보일뿐, 자세히 보면 간단합니다.
(사실 주석 달기 귀찮지 않았다는 것은 거짓말이겠지요. =_=)
실행하면 보시는 것 처럼, 콘솔창이 뜨고 'm' 을 누르면 Alert 창이 뜹니다. :)
Eplilogue
항상 사용하는 C/C++ 만 이용하며, 편식하면 나중에 비만이 될 것 같아 편식하지 않으려고 이번 포스팅은 어셈으로 개발하였습니다. :)
그럼 오늘 블로깅은 여기서 마치겠습니다.
아~~~내일은 월요일이네요. OTL
'Microsoft > MASM32' 카테고리의 다른 글
Visual Studio 2013 에서 MASM32 개발하기 (2) | 2014.05.07 |
---|---|
[MASM 강좌] 튜토리얼 7 : Mouse Input (0) | 2010.12.12 |
[MASM 강좌] 튜토리얼 6 : Keyboard Input (0) | 2010.12.12 |
[MASM 강좌] 튜토리얼 5 : More about Text (0) | 2010.12.12 |
[MASM 강좌] 튜토리얼 4 : Painting with Text (0) | 2010.11.29 |
RECENT COMMENT