DLL injection 은 어떻게 이루어지는가? - SetWindowsHookEx ()

2009/07/28 18:37

SetWindowsHookEx ()


이번에는 윈도우즈에서 정상적으로 지원하는 후킹 함수를 이용하는 방법을 알아보겠습니다. 윈도우즈는 OS와 프로세스 간에 메시지를 주고받는데요. 키보드를 누른다던지, 마우스를 클릭한다던지, 디버깅에 관한 메시지라던지 그런 것들을요. 그리고 그렇게 주고받는 메시지를 후킹할 수 있는 함수도 제공하고 있습니다.

사용자 삽입 이미지
[그림 1] SetWindowsHookEx() 함수의 개요

SetWindowsHookEx() 함수가 그것이죠. [그림 1]처럼 이 함수에 삽입할 DLL의 Handler, 즉 주소와 함수의 주소를 인자로 넣음으로써 메모리에 올라간 프로세스에 삽입하게 됩니다.

SetWindowsHookEx (WH_KEYBOARD, KeyHookProc, hModule, NULL);


위 예처럼 함수를 작성합니다. hModule은 삽입할 DLL의 주소입니다. 이것은 LoadLibrary() 함수로 구할 수 있죠.

그리고 KeyHookProc은 DLL의 함수인데, GetProcAddress() 함수로 구할 수 있고, CallBack 함수로 등록할 수도 있습니다. 주의할 것은 KeyHookProc는 CallNextHookEx() 함수를 반환해야 한다는 것입니다. 후킹이 끝나고 나서 원래의 작업을 하기 위해서죠. 만약, 원래의 작업을 하지 않는다면, 사용자는 무엇인가가 잘목되었다는 것을 알 수 있고 자칫하면 블루스크린을 띄울 수도 있거든요.

[그림 1]에서 보면 네 번째 인자로 dwThreadId가 지정되어 있는데, 이것은 DLL을 삽입하려는 쓰레드의 ID입니다. GetCurrentThreadId() 함수로 구할 수 있습니다. 이 값이 0이라면, 현재 윈도우즈 데스크탑의 모든 쓰레드가 대상이 되죠.

사용자 삽입 이미지
[그림 2] idHook 테이블

첫 번째 인자가 남았는데 이것이 후킹할 메시지입니다. OS와 여기에 지정된 메시지를 주고받는 쓰레드를 후킹하지요. 이 인자에 들어갈 수 있는 값은 [그림 2]에 정리되어 있습니다. 키보드, 마우스, 디버깅, 쉘과 관련된 15개의 메시지들이 있습니다. 이 메시지들에 대해 더 자세한 내용은 아래 참고 문헌에 나와 있으니 여기서는 생략하겠습니다.

마지막으로 작업이 모두 끝나면 메모리 반환을 위해서 UnhookWindowsHookEx() 함수로 후킹을 풀어줘야 합니다.

아래는 SetWindowsHookEx() 함수를 이용하는 예제 소스입니다.

#include <windows.h>

#pragma data_seg(".npdata")
HINSTANCE hModule=NULL;
HHOOK hKeyHook=NULL;
HWND hWndBeeper=NULL;
#pragma data_seg()
#pragma comment (linker, "/SECTION:.npdata,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);
}

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);
}

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;
}


참고 문헌

루트킷 : 윈도우 커널 조작의 미학, Greg Hoglund, James Butler, 2007, 에이콘
SetWindowsHookEx Function :: http://msdn.microsoft.com/library/ms644990.aspx
SetWindowsHookEx() 함수를 이용한 방법 :: http://blog.naver.com/amanahnr/90032952064
크리에이티브 커먼즈 라이센스
Creative Commons License

6l4ck3y3 0x02 Windows RCE , , , ,

Trackback Address:http://hisjournal.net/blog/trackback/253