RootKit Univ.Chosun HackerLogin : Jeong Kyung Ho Email : moltak@gmail.com
Contents 1. 루트킷이란? 2. Windows Architecture 3. Driver Development Kit 4. 루트킷제작에사용되는기술 A. Hooking B. Filter Driver C. DKOM 5. 결론 6. 참고자료
1. 루트킷이란? 루트킷에대해이야기하기전에먼저루트킷에대해알아보도록하자. A. 루트킷은커널모드 1 와유저모드에서동작한다. B. 유저모드보다는커널모드에서의비중이더크다. C. 많은루트킷들이커널모드에서동작하도록만들어져있다. D. 유저모드보단커널모드에서탐지가더어렵고커널모드는탐지가되더라도회피를하거나, 탐지프로그램을죽이는것이가능하다. E. 대부분의루트킷들은커널모드와유저모드에서동시에동작하도록되어있다. F. 루트킷의핵심키워드 꼭꼭숨어라 : 탐지되지않는 G. 대부분의기술과트릭은코드와데이터를시스템에서숨기기위해존재 많은루트킷들이커널모드에서동작하도록만들어져있다. 라고했는데그아래에서는 대부분의루트킷들은커널모드와유저모드에서동시에동작하도록되어있다 이라고쓴이유가무엇일까? 사실커널모드에서하기힘든일을유저모드에서는쉽게할수있다. 파일을만들거나어떤 API 코드를실행하거나, 그러한것은커널모드에서하기에는조금복잡하기도하고디버깅할때나예외가발생했을때수정하기도힘들다. 그래서루트킷은커널모드에서동작하도록만들어져있지만유저모드에서도동작하도록만들어져있다. 커널모드, 유저모드가서로상호작용을하면서탐지가쉽게되는유저모드를커널모드에서감춰주고커널모드에서사용하기어려운기능들은유저모드에서작성을함으로써코드가간결하며강력한루트킷을만들게되는것이다. 또한, 루트킷의핵심키워드는 탐지되지않는 이다. 루트킷의대부분의기술과트릭들은코드와데이터를시스템에서숨기기위해존재한다고해도틀린말이아니다. 물론해당컴퓨터를조종하기위한코드나어떤정보를얻기위해작성한코드도있겠지만가장중요한것은사용자나관리자에게루트킷이깔려있는지알수없게해야한다는것이다. 자신이설치가되고작동이되더라도시스템관리자가보기에는설치되기전과설치된후가변한것이없어야한다. 1 커널모드 : Windows Architecture 는 Kernel Mode, User Mode 를갖고있다.
2. Windows Architecture 윈도우는커널모드와유저모드를갖고있다. 유저모드는 Ring Level 3, 커널모드는 Ring Level 0 이며이는 CPU에서레벨에따라명령어를실행하게하거나못하게한다. 만약 Ring Level 3인유저모드에서 Ring Level 0의명령어를실행하려한다면 CPU에서예외를발생시킨다는것이다. 운영체제는유저모드를신뢰하지않는다. 항상감시의눈초리를보내다가수상한행동을할때해당프로세스를 Kill 한다. < 그림 1> 소프트웨어코드와메모리각각에어떤링이할당되는지끊임없이관리하는것은 CPU가담당해야하는역할이다. Ring Level( 이하링 ) 간의접근제한을수행하는것또한 CPU의역할이다. 일반적으로모든소프트웨어프로그램은링번호를할당받으며자신이할당받은링번호보다낮은번호의링영역에는접근할수없다. 예를들면, 링3 프로그램은링0 프로그램에접근할수없는것이다. 만약그런일이발생한다면 CPU는즉시예외를발생시킨다. 대부분의경우에는운영체제에의해서접근이차단되며그런접근시도는프로그램이중지되는결과를낳게된다. < 그림 1> 은인텔 x86 프로세서의링구조를표현한것으로유저모드와커널모드프로 그램이링구조안의어디에서실행되는지를나타내고있다. 권한에따라메모리에접근할 수있는권한이구별되듯이실행되는명령또한구별될수있다. 즉명령중에는링 0 에서
만사용할수있는명령이있다. 그런명령들을이용하면 CPU 의동작을변경시키거나하드 웨어에직접적으로접근할수있다. 루트킷이링 0 에서동작하면얻게되는장점이많다. 하드웨어나다른소프트웨어가실행 되고있는환경을조작할수있기때문이다. 3. Driver Development Kit 커널모드에서프로그래밍을하려면 DDK(Driver Development Kit) 가꼭필요하다. DDK 는하드웨어개발자들이윈도우용드라이버를개발하는데필요한도구들을모은것이다. 유저모드에서는 Win32API로프로그래밍을하거나 MFC로프로그래밍을하게된다. 많은라이브러리들은대부분이유저모드프로그래밍을위해나왔다고해도과언이아니게아주많은유저모드라이브러리가있다. 하지만커널모드프로그래밍을해야하는 DDK는그종류가몇가지가되지않는다. 가장많이사용되는라이브러리로 WDM(Windows Driver Model) 이있지만어렵고복잡해서사용하기가힘들다. 최근에나온차세대통합드라이버모델 (WDF) 이나왔지만그난해함은여전하다. 커널모드에서프로그래밍을하게된다면자주보는그림이있다. 옆에있는 BlueScreen인데이는 Win98시절에많이볼수있었던화면일것이다. 이화면은커널모드에서동작하는애플리케이션에예외가발생했을때나온다. 이화면이나오면시스템이강제종료되기때문에어디서예외가발생했는지어떻게수정해야하는지찾기가힘들다. 이예외를처리하려면디버깅컴퓨터와디버기컴퓨터가필요하다.
디버깅컴퓨터와디버기컴퓨터를연결한후 WinDbg 를이용해디버기컴퓨터에접속하 면커널모드애플리케이션에서발생하는메시지를읽을수있으며예 ᅌᅬ 가발생한시점에 서디버기컴퓨터를멈춘후디버깅을할수있다. 4. 루트킷제작에사용되는기술 A. HooKing 1 DLL Injection i. Windows Hooking Function 마이크로소프트는다른프로세스로전달되는윈도우메시지를후킹할수있는함수를정의해놓았다. 다른프로세스의주소공간영역안으로루트킷 DLL을로드시킬수있는방법을제공하고있는것이다. 애플리케이션은동작중에운영체제로부터다양한이벤트메시지를받는다. 애플리케이션의활성화된윈도우창에서사용자가키를입력했거나버튼이나마우스를클릭하면그이벤트에해당하는메시지가해당애플리케이션으로전송된다. 위의 SetWindowsHookEx 함수가윈도우후킹함수이다.
첫번째인자는후킹을수행할메시지타입. 두번째인자는이벤트메시지가발생되었을때메시지를보낼후킹함수의주소. 세번째인자는후킹함수를포함하고있는 dll의가상메모리주소. 네번째인자는후킹을수행할스레드이며네번째인자가 0이면현재윈도우데스크탑의모든스레드에대해후킹이가능하다. 옆의 UnHookWindowsHookEx는후킹을해제하는함수이다. Windows에서 Hook 함수를사용하여 DLL을 Inject 하게되면, 내부적으로는 Hook Procedure 만이아니라, Hook Procedure 가들어있는 DLL코드전체가프로그램의코드영역에 Mapping 되기때문에, DLL 코드가실행되는영역이결국 DLL을호출한프로그램의내부영역이된다. 내부메시지를 Hook 하거나, Window Procedure에 Hook을걸어필요한작업을진행하면될것이고 SetWindowHookEx를이용하여함수를실행하면된다.
#pragma data_seg( ".Hearobdata" ) HINSTANCE hmodule = NULL; HHOOK hkeyhook = NULL; HWND g_hwnd = NULL; #pragma data_seg() 이그림은 Global 변수들을 Shared로지정하여 DLL을사용하는모든프로그램에대해 DLL 이로드되는시간동안 DLL간의공유가능한영역을지정한것이다. 위에보이는것처럼데이터 seg의이름을주고이안에변수들을지정했을때이 DLL을로드하는프로세스는이데이터 seg를공유하게된다. 데이터 seg 를공유시켜원하는프로세스에서정보를얻고원하는 app 에얻어 온데이터를뿌려주게된다.
ii. VirtualAllocEx & CreateRemoteThread DLL을특정프로세스주소영역으로로드시킬수있는다른방법은해당프로세스의리모트스레드 (Remote Thread) 를만드는것이다. 이미존재하는프로세스상에서 Thread를외부에서생성하여, 이 Thread가 DLL 코드를실행하도록동작하는방법이다. 첫번째인자는스레드를삽입할프로세스의핸들을나타낸다. 프로세스의핸들을구하려면대상프로세스의 PID를이용하여 OpenProcess 함수를호출하면된다. OpenProcess 함수는프로그래머가원하는프로세스의핸들을리턴시켜준다. 두번째, 일곱번째인자는 NULL, 세번째여섯번째인자는 0으로설정한다. 네번째인자는인젝션대상프로세스주소공간내에서의 LoadLibrary 함수의주소설정. 다섯번째인자는 LoadLibrary에전달되는인자의메모리주소를설정하여야한다. 보통 Kernel32.dll 에서 LoadLibraryA 함수를얻어오고얻어온주소로 DLL 을 로드시킨다. LoadLibraryA 함수를이용해서원하는 DLL 을로드시키는것이
다. 아래에있는코드는 DLL을 Injection 하기위한코드이다. remote thread 를생성하고 LoadLibrary 를호출한뒤, thread 에서 DLL 코드가종료될때까지기다린다. DLL 코드는 remote thread, 즉외부 Process 영역에서동작하며, 필요한작업을한뒤 return 되는데, return 되고난뒤에는만들어놓은 thread 를종료하면된다. int InjectDll() { // Get remote process id dwpid = GetPIDFromName(szProcessName); if (dwpid == -1) return 0; // Open remote process hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwpid); if (hprocess == NULL) return 0; // Get full path of the DLL if (!GetModuleFileName(hInst, szlibpath, MAX_PATH))
return 0; strcpy(strrchr(szlibpath, '\\') + 1, szdllname); // Allocate memory in the remote process to store the szlibpath string plibremote = VirtualAllocEx(hProcess, NULL, sizeof(szlibpath), MEM_COMMIT, PAGE_READWRITE); if (plibremote == NULL) return 0; // Copy the szlibpath string to the remote process. if (!WriteProcessMemory(hProcess, plibremote, (void*)szlibpath, sizeof(szlibpath), NULL)) return 0; // Load the DLL into the remote process hthread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA"), plibremote, 0, NULL); // Wait for LoadLibrary() to finish and get return code WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, &hlibmodule); CloseHandle(hThread); CloseHandle(hProcess); // Free remote memory for szlibpath VirtualFreeEx(hProcess, plibremote, sizeof(szlibpath), MEM_RELEASE);} iii. CreateRemoteThread & WriteProcessMemory 위의 Injection 에서는 DLL 을외부스레드가실행하는것이었지만이방법은
원하는데이터를원하는 Process 안에넣어코드를실행하는것이다. 위의방법과마찬가지로원하는 Process의핸들을얻고 Process에공간을할당하고 INJDATA라는원하는데이터가들어있는구조체를만들어 Process안에 WriteProcessMemory를이용하여써넣는다. 그렇게넣어진데이터를외부스레드즉 CreateRemoteThread를이용하여실행시키는것이다. 그림을보면알수있듯이가장아래에 VirtualAlloc 을사용하여 INJDATA 를 써넣는것을볼수있다. INJDATA 의내용은 DLL 의코드이며이전방법과는 다른목표 Process 에서 Injection 할 DLL 의코드를직접실행하는것이다. 위구조체에사용할 DLL 의코드와정보를넣는다. 이정보들은 Remoted 프로 세스의 address 영역에넣어서사용하며, 여기에저장된내용은실행할때나,
사용할프로시저나함수의포인터, 내부변수등을저장하게된다. 인젝션하는방법은위의방법과마찬가지로모듈을얻어오는것부터시작하게된다. 하지만우리가필요한함수는 LoadLibraryA 함수가아닌 SetWindowLongA, CallWndProcA 함수이기때문에다른모듈을얻어와야한다. // Get handle of "USER32.DLL" huser32 = GetModuleHandle("user32"); 얻어오는모듈의핸들은바로 user32 이다. 이곳에서원하는함수를얻게된 다. // Open remote process hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID); 원하는프로세스를열고, // Allocate memory in the remote process and write a copy of initialized INJDATA into it size = sizeof(injdata); pdataremote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 실행할코드가들어있는 INJDATA 만큼의공간을할당한다 WriteProcessMemory(hProcess, pdataremote, &DataLocal, size, &dwnumbytescopied) 할당된공간에 INJDATA DataLocal 을써넣는다. 다음은 RemoteThread 를위한공간을할당하고데이터를써넣을차례이다. pgetsaswndremote = (PBYTE) VirtualAllocEx(hProcess, 0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(hProcess, pgetsaswndremote, &GetSASWnd, size, &dwnumbytescopied)
다음은 RemoteThread 를만들고원하는함수를실행시킨다. // Start execution of remote GetSASWnd() hthread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) pgetsaswndremote, pdataremote, 0, &dwthreadid); 다음은위의방법과마찬가지로 DLL 의실행이끝나길기다린후종료시킨다. // Wait for GetSASWnd() to terminate and get return code (SAS Wnd handle) WaitForSingleObject(hThread, INFINITE); GetExitCodeThread(hThread, (PDWORD) &hsaswnd); 여기까지가 WriteProcessMemory와 CreateRemoteThread를이용한 DLL Injection 부분이다. 사실누락된내용도많지만누락된내용은다양한문서와완성되어공개된프로그램들이많으니그걸보고해도될것같다. 이와같은방법으로작업관리자를막거나프로그래머가원하는어떤키를막는것이가능하다.
B. FilterDriver i. 필터드라이버란? 위에서설명했던것과같이윈도우에는 KernelMode가있다. 그모드에서하는 Hooking을할수있는방법중하나가 FilterDriver 이다. 먼저필터드라이버를간단하게설명하자면 WDM(Windows Driver Model) 은계층드라이버아키텍처를갖는다. 여러개의계층으로이루어진드라이버사이에새로운드라이버를끼워넣을수있다. 거의모든하드웨어장치는그것을지원하기위한드라이버체인이존재한다. 가장낮은계층의드라이버는하드웨어장치와버스를직접처리하고, 가장높은계층은데이터를구조화한다. 무슨말인가하면윈도우의드라이버는여러개의층으로되어있으며, 층사이에 원하는드라이버를끼워넣을수있다. 그리고드라이버들은체인으로묶여있고그 체인이있음으로해서제어를쉽게하고개발자의수고를덜수있다. 이그림을필터드라이버를형상화한그림이다. i8042prt라는드라이버가가장상위에있으며그체인으로밑에여러개의드라이버들이묶여있는것이보인다. 가장아래에있는낮은계층의드라이버는하드웨어장치와버스를직접처리하며, 가장높은계층은데이터를구조화한다. 필터드라이버를더세부적으로나눌수있다.
Function Device Object 를기준으로위에있는것들을 Upper Filter Driver 이며아래에있는것들은 Lower Filter Driver 라한다. Class Filter Driver 는같은종류의디바이스를망라하는드라이버라할수있다. 예를들면 Keyboard 는그타입이여러가지가있는데 PS/2 라던지 USB 같은것을말한다. 이렇게묶여있을경우에는어떤종류던지간에제어가가능하다. Device Filter Driver 는특정 Device 에만설치가되는필터드라이버를말한다. 예 를들어 USB 로 Printer 를사용하고있을때이프린터드라이버에만설치가되는 것이 Device Filter Driver 이다. 드라이버가디바이스에종속된다고생각하면쉽다. Bus Filter Driver 는 USB 같은특정버스드라이버에대해필터링하는드라이버 이다. ii. IRP 윈도우프로그래밍은메시지구동방식이라는것을알고있을것이다. 윈도우프로그램은사용자가특정작업 ( 마우스클릭, 키보드입력, 메뉴선택등 ) 을하게되면그것에해당하는윈도우메시지라는것이발생하며윈도우에서는해당메시지를현재활성화되어있는프로그램의메시지큐에집어넣게된다. 그럼프로그램은메시지큐에서메시지를가져와서적절한처리를하게되는것이다. 드라이버역시이와비슷한동작을한다. 드라이버는로딩이성공적으로이루어지면할당된메모리에대기하고있다가자신이컨트롤하고있는디바이스에
특정한요청이왔을때윈도우에서보내주는요청정보를토대로적절한동작을하게된다. 이때윈도우프로그램이특정메시지를처리하기위해해당메시지값과그에관련된정보들이들어있는 MSG라고하는구조체를파라미터로받아처리하듯드라이버역시이와같은특정요청에관련된정보들을함수의파라미터로받게된다. 이러한정보들을담은정의된구조체가바로 IRP 이다. 필터드라이버와하드웨어가통신을할때 I/O Manager 에서는 IRP 를만들게된다. 이 IRP는여러가지정보를담고있으며해당드라이버의위에서아래로아래에서위로정보가이동하게된다. 이때필터드라이버는그정보가내려올때필터링하는방법과정보가올라올때필터링하는방법중하는방법중선택하여프로그래밍할수있다. 위에서말했던것처럼필터드라이버는 IRP라는메시지와비슷한방식으로동작한다고말했었다. 아래에있는그림들은프로그래밍시에사용되는 IRP 이다. 처리루틴에서는자신이원하는 IRP가들어왔을때루틴이동작하게된다. 이 IRP들을통해 APP와통신을하거나, 다른드라이버로부터받은요청을처리하거나통신을하거나할수있게된다.
// major funciton 설정 for( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++ ) { pdrvobj->majorfunction[ i ] = IrpSkip; } pdrvobj->majorfunction[ IRP_MJ_READ ] = KeyReadRoutine; pdrvobj->driverunload = DriverUnload; IRP 에정의되어있는 MajorFuction 의개수는 27 개이고이중에프로그래머가원 하지않는 IRP 가발생했을때 IrpSkip 을하여해당 IRP 를다음드라이버에게보 내는작업을하게된다.
위코드가그러한동작을하는코드이다. 그리고내가원하는 IRP_MJ_READ 처리 루틴은따로만들어서이러한 IRP 가발생했을때 KeyReadRoutione 이라는루 틴이동작하는것이다. 위코드가 IRP_MJ_READ 라는 IRP 가발생했을때동작하는루틴이다. 이챕터는 KernelMode 에서 Keyboard Hooking을위해쓰여진글이지만이글을보고는절대로만들수가없다. 사실 Keyboard Filter 드라이버를만들기위해서는많은지식과정보가필요하며따로 KernelMode 프로그래밍에대한공부도해야하기때문이다. DDK 를사용하여프로그래밍하기때문에선수학습이많이요구된다. 필터드라이버는아주방대한영역이고본문서에서다루기에는그범위가초과되는바이정도로만마치도록하겠다. 혹시이글을보고 Keyboard Filter Driver 에관심이생긴다면 Devpia 드라이버마을을방문해보기바란다. C. DKOM(Direct Kenel Object Manipulation) 커널은실행중인프로세스나드라이버, 포트들의정보를커널객체에저장하여작성하며커널객체는프로세스리스트와드라이버리스트를이중연결리스트를이용하여관리한다. 이중연결리스트값을수정하면프로세스와드라이버를숨길수있다. 커널은 EPROCESS 객체를생성하여프로세스를관리하는데 EPROCESS 객체의멤버 중 ActiveProcessLinks 는연결리스트구조체이다. 이멤버를사용하여프로세스들은 서로연결되어있다.
그림처럼숨길프로세스는자기를가리키게하고앞뒤의프로세스의연결리스트를조 작하는것만으로도간단히숨길수있다. EPROCESS 구조체를 WinDBG를이용해서본그림이며 LIST_ENTRY에 FLINK와 BLINK의값들이들어있다. 위의값을받아와서조작함으로써원하는결과를얻을수있다. 위기능은원하는프로세스를숨기는기능을하는데혼자서는동작할수가없다. 왜냐하면자신이숨길프로세스가뭔지모르기때문이다. 위의코드가동작하는이유는자신의 APP를숨기기위해서인데숨길 APP는 UserMode 에서돌아가는 RootKit 이기때문이다. APP에서드라이버를로딩하며드라이버에게자신의프로세스이름을알려줄수있어야한다. APP가로딩이된후자신의 PID를알아내어드라이버에게전달하면효과적으로숨길수있다. while( bprocessfound ) { bprocessfound = Process32Next( hsnapshot, &ProcessEntry32 ); tempprocessname = ProcessEntry32.szExeFile; processname = tempprocessname;
if(!strcmp( tempprocessname, processname ) ) { CloseHandle( hsnapshot ); char *ndatacopy = new char[ sizeof( int ) + 1 ]; sprintf( ndatacopy, "%d", ProcessEntry32.th32ProcessID ); ndata = new BYTE[ 5 ]; for( int i = 0; i < 5; i ++ ) { ndata[ i ] = ( BYTE )ndatacopy[ i ]; } return ndata; } } 위와같은코드로원하는프로세스의 ID 를얻을수있다. 그정보를로드한드라이버 에게전달하면드라이버파일이효과적으로프로세스를숨기는것을확인할수있을 것이다. 5. 결론 DLL Injection 이나자료에나오진않았지만 SSDT 후킹은이제는유행이되어버렸다. 인터넷에서검색만하면엄청나게쏟아져나오는자료에본문서가아니더라도원하기만하면쉽게자료를찾아볼수있을것이다. 포털사이트에가서 DDL Injection을쳐보기만해도알수있을것이다. 하지만그렇다고해도이런기술들이쉽다는것이아니다. 이기술들은수많은고수들이날을새가며끼니를잊어가며파헤쳐서얻은취약점들이고이런것을공부한다는것은고수들만큼은아니더라도많은선행학습이있어야한다. DDL Injection 하나하려고해도아니 API를이용해전역후킹을해보려해도 C와 API 그리고 DLL에대해서이해를하고있어야하며이는스크립트키드들이나이제막프로그래밍을시작한사람들이하기에는좀어려운기술들이다. 요즘보안상황을보자면보안툴과해킹툴이서로비슷한기능을많이사용하고있다는 것을알게될것이다. 보안툴은해킹툴을없애기위해 SSDT, DKOM, DLL Injection 을 사용하고해킹툴은말할것도없다. 점차둘간의벽이사라지고있는것이다. 둘은비슷
한기술을사용하고비슷한기능을갖기때문에누가먼저시스템에둥지를트느냐가승부에관건이되어가고있다. 루트킷이먼저올라왔다면보안소프트웨어를못올라오게막고보안소프트웨어는또그반대가되어가고. 나중에올라온쪽은먼저올라온것을탐지하거나 Kill 하기가점점어려워지고있는상황이다. 왜냐하면둘다 Ring Level 0에서동작을하기때문이다. 예전에는 UserMode에서동작하는툴들이대부분이었을지도모른다. 하지만지금은아니다. 물론 DLL Injection도강력한기술이다. 탐지하기가쉬운것도아니고찾았다고해도수정하기가어렵다. 하지만그것이 Kernel Mode로넘어간다면더욱어려워진다. DKOM같은경우는직접커널오브젝트를수정하여버리며 SSDT도비슷한기능을하고있다. 그래서보안툴도비슷한기술을기반으로제작하여루트킷에대항하고있다. 점점해킹툴과보안툴간에격차가없어지는것이다. 루트킷을만들던도중에 VMM(Virtual Machine Mnitor) 이라는것을보게되었다. 많이들사용하는 VM_WARE 라고생각하면쉬울것이다. 예전부터사용되던기술인데리소스를효과적으로사용하기위해개발되었던기술이다. 알겠지만 VM_WARE는하드웨어와운영체제사이에위치하며하드웨어에대한리소스를가상화하는기술이다. 갑자기이걸왜말하냐하냐면가상화를사용하는루트킷이있기때문이다. 가상화는이미흔한이야기가되어있다. 엔터프라이즈급에서는이미많이사용하고있으며은행은말할것도없고학교들도점차사용을하기시작했다. 하지만현재대부분의보안제품으로는이기술을사용하는루트킷은탐지하기가거의불가능하다. 루트킷이 VM을만들어거기서동작하게된다면윈도우아키텍쳐상 KernelMode 보다권한이더높다. 그렇다면탐지가아주어려워지게되는것이다. 실제로도몇개의루트킷이이기술을사용하고있다. CPU에서제공하는가상화기능을이용하는것은단지루트킷의은닉기술중의하나뿐이며가상화외에도루트킷의은닉기술은상당히많다. 문제는이중알려지지않은은닉기술인데이는존재의유무조차모르고있다고한다. 그런데전통적인 (?) 기술을사용하는루트킷조차제대로탐지를못하고있는실정이라한다. 루트킷을안전하고완벽하게제거하는기술영역도지속적인연구가계속필요하다.
6. 참고자료 DevPia(Driver 마을 ) HybTech MSDN 윈도우를위한차세대통합드라이버개발모델 (WDF) 윈도우커널조작의미학 (RootKit) Os를관통하는프로그래밍의원리 드라이버개발자를위한윈도우파일시스템