Notice
Recent Posts
관리 메뉴

Hacking Arts

메세지 후킹 (Message Hooking) - 2 본문

Reversing/Hooking

메세지 후킹 (Message Hooking) - 2

Rakehell 2014. 9. 20. 03:01

- 키보드 메시지 후킹 실습


[그림 1 키보드 후킹 원리 그림]

KeyboardProc.dll 파일은 훅 프로시저 KeyboardProc가 존재하는 DLL파일입니다. HookMain.exe는 KeyHook.dll을 최초로 로딩하여 키보드 훅을 설치하는 프로그램 입니다.HookMain.exe에서 KeyHook.dll 파일을 로딩한 후 SetWindowHookEx()을 이용하여 키보드 훅을 설치합니다. 다른 프로세스에서 키 입력 이벤트가 발생하면 OS에서 해당 프로세스의 메모리 공간에 KeyHook.dll을 강제로 로딩하고 KeyboardProc()함수가 호출되는 형태입니다. 

중요한 점은 키 입력 이벤트가 발생하면 강제로 로딩 시켜준다는 점입니다. 즉 메시지 후킹 기법은 DLL인젝션 기법의 하나로 사용됩니다.




-HookMain.exe 소스코드
// HookMain.cpp

#include
#include
#include

#define DEF_DLL_NAME "KeyHook.dll"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop"

typedef void(*PFN_HOOKSTART)();
typedef void(*PFN_HOOKSTOP)();

void main()
{
	HMODULE hDll = NULL;
	PFN_HOOKSTART HookStart = NULL;
	PFN_HOOKSTOP HookStop = NULL;
	char ch = 0;

	//KeyHook.dll 로딩
	hDll = LoadLibraryA(DEF_DLL_NAME);

	//export 함수 주소 얻기
	HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);
	HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);

	//후킹 시작
	HookStart();

	//사용자가 'q'를 입력할 때까지 대기
	printf("press 'q' to quit !\n");
	while (_getch() != 'q');

	//후킹 종료
	HookStop();

	//KeyHook.dll 언로딩
	FreeLibrary(hDll);
}
-KeyHook.dll 소스코드
//KeyHook.cpp

#include
#include

#define DEF_PROCESS_NAME "notepad.exe"

HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
HWND g_hWnd = NULL;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
	switch (dwReason)
	{
		case DLL_PROCESS_ATTACH:
			g_hInstance = hinstDLL;
			break;
		case DLL_PROCESS_DETACH:
			break;
	}
	return TRUE;
}

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	char szPath[MAX_PATH] = { 0, };
	char *p = NULL;

	if (nCode >= 0)
	{
		//bit 31 : 0 = key press, 1 = key release
		if (!(lParam & 0x80000000))//키보드가 눌렀다 떨어졌을 때
		{
			GetModuleFileNameA(NULL, szPath, MAX_PATH);
			p = strrchr(szPath, '\\');

			//현재 프로세스 이름을 비교해서 만약 notepad.exe 라면,
			//메시지는 응용 프로그램 (혹은 다음 훅)으로 전달되지 않음
			if (!_stricmp(p + 1, DEF_PROCESS_NAME))
				return 1;
		}
	}
	
	//일반적인 경우에는 CallNextHookEx()를 호출하여
	//응용프로그램 (혹은 다음 훅)으로 메시지를 전달함
	return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

#ifdef __cplusplus
extern "C" {
#endif

	__declspec(dllexport) void HookStart()
	{
		g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
	}
	__declspec(dllexport) void HookStop()
	{
		if (g_hHook)
		{
			UnhookWindowsHookEx(g_hHook);
			g_hHook = NULL;
		}
	}

#ifdef __cplusplus
}
#endif
-참고 서적 
리버싱 핵심원리 / 이승원 / 인사이트
http://maxtrain.egloos.com/viewer/2775961


'Reversing > Hooking' 카테고리의 다른 글

메세지 후킹 (Message Hooking) - 1  (0) 2014.09.19
후킹 (Hooking)  (0) 2014.09.19