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

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

Similar Posts

  • Ring 0, 커널 레벨에서의 루트킷

    오랜만에 찾아 뵙습니다. 그동안 두 개의 프로젝트를 수행하면서 중간고사도 치르고 하느라 한 달이 훌쩍 지나가버렸네요. 그러는동안 블로그에도 소원해졌구요. 친구가 블로그가 너무 조용하다고 핀잔을 줄 정도였습니다. 하하하 ^^; 제가 그동안 참여한 프로젝트 중의 하나가 루트킷 탐지 프로그램을 만드는 것이었습니다. 세 개의 팀을 나누어서 각각 유저 레벨, 커널 레벨, MBR의 루트킷을 공부했지요. 제가 맡은 부분은 커널 레벨에서의…

  • SQL Injection 하나면 절반은 먹고 갈까?

    곧 있을 해킹 방어 대회를 위해 공부하는 와중에 웹사이트 하나에 접근을 해봤습니다. 이 웹사이트는 이미 LatinHackTeam에 의해 해킹되었다고 Zone-h에 올라왔었습니다. 웹사이트에 들어가보니 대충 어떻게 해킹되었는지 예상이 되더군요. 제목에서처럼 SQL Injection에 의해 해킹되었습니다. 웹게임 문제에서만 나올 것 같던 상황이 실제로… 아래 그림들은 LatinHackTeam이 해킹했다고 메시지를 남긴 모습과 제가 관리자 권한으로 접속한 모습입니다. 이런 걸 막기 위해서…

  • Reveal API Redirect on Themida

    일주일 전에 쿠시스 영남권 세미나에서 “API Redirect on Themida”라는 주제로 발표를 했었습니다. 아래는 그때 발표자료랑 시연에서 잠시 소개했던 스크립트입니다. Immunity Debugger 용으로 python으로 작성하였습니다. PyCommand 디렉토리 아래에 스크립트 파일을 저장한 후, eip가 call 문에 있을 때 커맨드라인에서 다음과 같이 입력하면 실행이 됩니다. !revealapi 이 스크립트는 call 문을 직접 실행하지 않고 Themida에서 리다이렉트된 API를 찾아서 comment로…

  • DLL Injection 은 어떻게 이루어지는가? – AppInit_DLLs 값 조작

    AppInit_DLLs 값 조작 DLL Injection에는 여러 방법이 있습니다. 그중 루트킷에 이용되는 세 가지 방법을 알아보겠는데요. 첫 번째로 레지스트리를 조작하는 방법입니다. regedit에서 위 주소의 레지스트리 값을 확인해보면, 보통은 값이 비어있습니다. 그런데 어떠한 값이 들어있다면, 그리고 그것이 자신이 모르는 어떤 파일이라면, 그것은 악성 코드일 가능성이 있습니다. 이 레지스트리 값이 무엇이냐구요? 바로 이 값이 DLL Injection에 참조되는 레지스트리…

  • Brute Forcing with DLL Injection

    Articles에 문서를 업데이트 했습니다. 작년 10월, 2009 하반기 KUCIS 영남권 정보보호 세미나에서 발표했던 주제입니다. DLL Injection 기법을 이용한 무차별 대입 공격으로 패스워드를 찾아 보았습니다. 소스를 포함하여 문서를 정리할까 했는데, 악용될 소지가 있어서 발표했던 자료만 공개합니다. 당시에 발표했던 내용보다 조금 보완된 부분이 있습니다. 3개월째인 오늘까지도 이 방법을 어디에 써 먹을 수 있을지 못 찾고 있습니다. 간혹…

  • 게임 매크로 Inventory A+ 분석

    1. 기능 소개   [그림 1] Warcraft III 에서의 인벤토리   Inventory A+는 Blizzard 사의 Warcraft III 의 인벤토리 단축키를 변경하는 매크로입니다. 원래 인벤토리의 아이템을 사용하기 위한 단축키는 숫자패드의 7, 8, 4, 5, 1, 2 이지만, Inventory A+ 를 실행하면 인벤토리 단축키가 [그림 2]와 같이 변경됩니다. 실제로 이 매크로는 DotA 용으로 제작된 것입니다.   [그림…

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다