Windows/DeviceDriver 2021. 4. 25. 18:07

06. 프로그램 실행 제어

  • 프로그램의 실행을 통제하는 드라이버

이론

윈도우 프로세스 실행 과정

  • 프로그램을 실행시키면, 메모리에 프로세스를 위한 공간을 할당하고 EPROCESS 등의 구조체를 생성한다.

  • 공간 할당이 끝나면, 커널이 등록된 Notify Routine 함수를 호출하여 프로세스의 실행 여부를 결정한다.


드라이버에게 프로세스의 생성과 소멸 시기를 알려주기

  • 프로세스가 실행될 때마다 호출할 함수를 커널에 등록해야 한다.

  • WDK에서 제공되는, Notify Routine 함수를 등록하는 함수들

    • PsSetCreateProcessNotifyRoutine

      NTSTATUS
      PsSetCreateProcessNotifyRoutine(
        IN PCREATE_PROCESS_NOTIFY_ROUTINE  NotifyRoutine,
        IN BOOLEAN  Remove
        );
      
      VOID
      (*PCREATE_PROCESS_NOTIFY_ROUTINE) (
        IN HANDLE  ParentId,
        IN HANDLE  ProcessId,
        IN BOOLEAN  Create
        );
      • 이 방식으로 설치하는 NotifyRoutine은 프로세스가 생성되거나 제거되는 상황을 알 수는 있지만, 생성 과정을 제어할 수 없다.

      • 설치할 때는 두 번째 인자인 Remove를 0으로, 제거할 때는 1로 설정한다.

  • PsSetCreateProcessNotifyRoutineEx

    NTSTATUS
    PsSetCreateProcessNotifyRoutineEx(
      IN PCREATE_PROCESS_NOTIFY_ROUTINE_EX  NotifyRoutine,
      IN BOOLEAN  Remove
      );
    
    VOID
    CreateProcessNotifyEx(
      __inout PEPROCESS  Process,
      __in HANDLE  ProcessId,
      __in_opt PPS_CREATE_NOTIFY_INFO  CreateInfo
      );
    
    typedef struct _PS_CREATE_NOTIFY_INFO {
      __in SIZE_T  Size;
      union {
        __in ULONG  Flags;
        struct {
          __in ULONG  FileOpenNameAvailable : 1;
          __in ULONG  Reserved : 31;
        };
      };
      __in HANDLE  ParentProcessId;
      __in CLIENT_ID  CreatingThreadId;
      __inout struct _FILE_OBJECT  *FileObject;
      __in PCUNICODE_STRING  ImageFileName;
      __in_opt PCUNICODE_STRING  CommandLine;
      __inout NTSTATUS  CreationStatus;
    } PS_CREATE_NOTIFY_INFO, *PPS_CREATE_NOTIFY_INFO;
    • 위 함수의 단점을 보완한 것으로, 프로세스의 생성 과정을 제어할 수 있다.

    • 프로세스가 종료될 때는 CreateProcessNotifyEx 함수의 세 번째 인자에 NULL이 들어간다.

      • 프로세스의 종료를 제어하려면 이 인자가 NULL일 경우를 처리하면 된다.
    • _PS_CREATE_NOTIFY_INFO 구조체의 ImageFileName는 실행하려는 파일의 Full Path Name이다.

    • _PS_CREATE_NOTIFY_INFO 구조체의 CreationStatus는 프로세스 실행 여부를 결정한다.

유의사항

  • 드라이버 바이너리 파일이 변조될 위험이 있기 때문에, 윈도우에서는 파일의 무결성을 체크한다.

    • 이를 위해 링커 옵션에 /integritycheck를 추가해야 한다.
  • 드라이버가 메모리에서 해제될 때는 등록했던 Notify Routine을 제거해야 한다.

    • PsSetCreateProcessNotifyRoutineEx 함수의 두 번째 인자인 Remove에 1(TRUE) 값을 주면, 첫 번째 인자인 NotifyRoutine의 등록을 해제한다.

실습

#include <ntddk.h>

WCHAR g_TempString[512] = { 0, };
void NotifyRoutine(PEPROCESS Process, HANDLE ProcessId, \
  PPS_CREATE_NOTIFY_INFO CreateInfo)
{
  Process = Process; ProcessId = ProcessId;
  if (CreateInfo == NULL)
    goto exit;

  memset(g_TempString, 0, sizeof(WCHAR) * 512);
  memcpy(g_TempString, CreateInfo->ImageFileName->Buffer, CreateInfo->ImageFileName->Length);
  _wcsupr(g_TempString);
  if (wcswcs(g_TempString, L"NOTEPAD.EXE"))
  {
    CreateInfo->CreationStatus = STATUS_UNSUCCESSFUL;
  }

exit:
  return;
}

void SampleDriverUnload(PDRIVER_OBJECT pDrvObj)
{
  pDrvObj = pDrvObj;

  PsSetCreateProcessNotifyRoutineEx(NotifyRoutine, TRUE);
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
{
  pRegPath = pRegPath;

  pDrvObj->DriverUnload = SampleDriverUnload;

  PsSetCreateProcessNotifyRoutineEx(NotifyRoutine, FALSE);

  return STATUS_SUCCESS;
}
  • 프로젝트의 속성(Ctrl + Enter)에서 Linker - All Options 탭의 Additional Options/integritycheck를 추가해야 정상적으로 Notify Routine 함수가 실행된다.

    • 무결성 체크 옵션을 주지 않고 빌드하여 드라이버를 올리면, 일단 정상적으로 올라가긴 하는데 메모장도 실행이 된다. 아마 PsSetCreateProcessNotifyRoutineEx 함수가 작동하지 않는 것 같다.

  • 빌드하고 .sys 드라이버 파일은 가상 머신에, .pdb 심볼 파일은 WinDbg에서 지정한 위치로 옮긴 후 관리자 권한의 CMD에서 sc start sample 명령어로 드라이버를 올린다.

  • 그 후 notepad 명령어로 메모장을 실행하면 다음과 같은 오류가 발생한다.

    시스템이 지정된 프로그램을 실행할 수 없습니다.
  • 관리자 권한으로 메모장을 실행하면 다음과 같은 오류를 볼 수 있다.

  • sc stop sample 명령으로 드라이버를 내리면 Notify Routine 함수가 내려가므로 정상적으로 메모장을 실행할 수 있다.

프로세스가 실행될 때 해당 프로그램의 경로 확인

  • WinDbg에서 브레이크 포인트를 걸어준다.

    bp sample!NotifyRoutine
  • sc start sample 명령어를 실행하면 Notify Routine 함수가 실행되는데, 세 번째 인자인 CreateInfoNULL로 들어오기 때문에 바로 함수를 종료하게 된다.

  • 메모장을 실행하게 되면 다시 Notify Routine 함수가 호출되고, 여기서 CreateInfo->ImageFileName->Buffer를 통해 파일의 전체 경로를 볼 수 있다.

    • 꼭 메모장 뿐만 아니라, 모든 프로세스가 실행될 때 등록한 Notify Routine 함수가 호출된다.

  • Notify Routine 함수에 브레이크 포인트를 걸면 프로세스를 종료할 때도 브레이크가 걸리는 것을 알 수 있다.

    • 시스템 종료를 눌러도 Notify Routine이 호출된다.

브레이크 포인트 명령어

  • bl

    • 브레이크 포인트의 리스트를 볼 수 있다.

    • 명령어를 입력하면 브레이크 포인트의 번호와, 클릭할 수 있는 Disable, Clear이 나온다.

      • Disable은 잠깐 비활성화 시키는 것이고, Clear는 브레이크 포인트를 해제하는 것이다.
  • bd 번호

    • bl 명령어로 각 브레이크 포인트의 번호를 얻을 수 있는데, 이를 인자로 받아서 브레이크 포인트를 비활성화(Disable) 시킨다.
  • be 번호

    • bd로 비활성화한 브레이크 포인트를 다시 활성화(Enable) 시킨다.
  • bc 번호

    • 브레이크 포인트를 해제(Clear) 시킨다.

참고

Windows/DeviceDriver 2021. 4. 25. 18:06

05. 5편 구조체분석1 (DRIVER_OBJECT, UNICODE_STRING)

  • WDK 도움말에 구조체 이름을 검색하여 참고하면 좋다.

디바이스 드라이버 구조체

간단한 샘플 드라이버 코드

#include <ntddk.h>

NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
{
  return STATUS_UNSUCCESSFUL;
}
  • DriverEntry 함수의 인자는 다음과 같다.

    • pDrvObj : 샘플 드라이버를 설명하는 DRIVER_OBJECT 구조체의 주소

    • pRegPath : 샘플 드라이버가 등록된 시스템 레지스트리의 키 이름 정보가 보관된 메모리를 설명하는 UNICODE_STRING 구조체의 주소


DRIVER_OBJECT 구조체

  • DriverInit : 디바이스 드라이버를 올리는 IO Manager가 DriverEntry의 주소를 저장한다.

  • DriverUnload : 드라이버가 내려갈 때 실행되는 콜백 함수

    • 기본 값은 NULL이며, 프로그래머가 저장해야 한다.

실습

  • 정상적으로 드라이버를 올렸다가 내리는 작업을 WinDbg로 확인할 것이다.

    • 코드를 빌드한 뒤 .sys 드라이버 파일은 가상 머신으로 옮기고, .pdb 심볼 파일은 WinDbg에서 설정한 경로로 옮긴다.

      #include <ntddk.h>
      
      void SampleDriverUnload(PDRIVER_OBJECT pDrvObj)
      {
        pDrvObj = pDrvObj;
      }
      
      NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
      {
        pRegPath = pRegPath;
      
        pDrvObj->DriverUnload = SampleDriverUnload;
      
        return STATUS_SUCCESS;
      }
  • 가상 머신과 WinDbg 프로그램을 실행한다.

    • WinDbg에서 가상 머신을 멈춘 뒤 브레이크 포인트를 설정한다.

      bp sample!DriverEntry
      bp sample!SampleDriverUnload
    • 가상 머신에서 관리자 권한으로 CMD를 열어서 드라이버를 올린다.

      sc start sample
    • 올리는 순간 가상 머신이 멈추고 WinDbg에 소스 코드가 나오고 디버깅을 시작한다.

      • 소스 코드가 뜨지 않으면 WinDbg가 소스 코드의 경로를 찾지 못한 것이다.

        • 이럴 경우 직접 소스 코드를 불러와야 볼 수 있다는 것 같다.
    • Go를 눌러 디버깅을 마친 뒤에 드라이버를 메모리에서 내린다.

      sc stop sample
    • 내린 순간 다시 가상 머신이 멈추고 디버깅을 시작한다.

      • pDrvObj->DriverUnload에 등록된 SampleDriverUnload 함수가 호출된 것을 볼 수 있다.

참고

Windows/DeviceDriver 2021. 4. 20. 01:33

4. 프로세스 강제 종료 방지 연습


이론

  • 프로세스가 생성되면 고유의 Process ID를 갖는다.

    • PsLookupProcessByProcessId 함수를 통해 EPROCESS라는 구조체의 주소를 얻을 수 있다.

      <ntifs.h>

      NTSTATUS
        PsLookupProcessByProcessId(
          IN HANDLE ProcessId,
          OUT PEPROCESS *Process
          );
      • 첫 번째 인자로 PID를 받아서, 두 번째 인자를 역참조하여 EPROCESS의 주소(PEPROCESS)를 넘겨준다.
    • "EPROCESS 구조체의 주소 - 0x15"에 해당하는 주소의 값을 0x14로 변경하면, 다른 프로세스가 종료할 수 없도록 설정된다.


실습

빌드

  • 이전에 작성한 sample.c 파일의 내용을 다음과 같이 수정하여 빌드한다.

    #include <ntifs.h>
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegistryPath)
    {
      pDrvObj = pDrvObj;
      pRegistryPath = pRegistryPath;
    
      ULONG ProcessId = 0;
      if (ProcessId == 0)
        goto exit;
    
      PEPROCESS pEprocess = NULL;
      PsLookupProcessByProcessId((HANDLE)ProcessId, &pEprocess);
      if (pEprocess)
        *(unsigned char*)((unsigned char*)pEprocess - 0x15) = 0x14;
    
    exit:
      return STATUS_UNSUCCESSFUL;
    }
  • 빌드한 sample.sys 파일을 가상 머신의 C:\sample\ 경로로 이동시킨다.

  • 가상 머신에서 메모장과 작업 관리자를 연 뒤, 세부 정보 탭에서 메모장의 PID를 확인한다.


WinDbg

  • 나는 WinDbg를 켤 때마다 Kernel Debug (Ctrl + K)를 열어서 포트를 수정해줘야 하는데, 이유를 아직 잘 모르겠다.

  • 아무튼 가상 머신과 연결되면, 3장에서처럼 위 함수에 브레이크 포인트를 설정하고, Go를 눌러 다시 진행시킨다.

    bp sample!DriverEntry
  • 가상 머신의 CMD를 관리자 권한으로 열어서, 다음 명령어를 입력하여 드라이버를 로딩한다.

  • WinDbg에서 보면 브레이크 포인트에 걸려서 함수가 나온 것을 볼 수 있다.

    • Step into (F11) 버튼을 눌러 ULONG ProcessId = 0; 명령까지 진행한 뒤, Locals (Alt + 3)을 선택하면 로컬 변수 목록이 나온다.

  • LocalsProcessId 값에 위에서 확인한 notepad.exePID를 입력한다.

  • 그 후 Go를 눌러 가상 머신의 Break를 끝내면, 작업 관리자에서 작업 끝내기를 할 수 없다는 것을 확인할 수 있다.

Windows/DeviceDriver 2021. 4. 20. 01:32

3. 간단한 드라이버와 디버깅


디버깅을 위한 준비

  • 가상 머신에서 호스트와의 파일 공유가 원활하도록 공유 폴더를 지정해둔다.

  • 가상 머신, WinDbg, 비주얼 스튜디오 프로그램을 실행한다.

빌드

  • 새 프로젝트 생성에서 Empty WDM Driver를 선택한다.

  • 프로젝트명은 sample로 설정하였다.

  • Driver Files에서 sample.inf가 존재하는데, 아직 사용하지 않으므로 지워준다.

  • 소스 파일에 sample.c 파일을 생성한다.

    sample.c

    #include <ntddk.h>
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegistryPath)
    {
      pDrvObj = pDrvObj;
      pRegistryPath = pRegistryPath;
      return STATUS_UNSUCCESSFUL;
    }
  • x64 환경에서 빌드한다.

    • 그대로 빌드하면 에러가 발생하므로, 프로젝트 설정의 C/C++ - Code Generation - Spectre Mitigation 속성을 Disabled로 변경한다.
  • 솔루션의 경로인 sample에서 x64\Debug\로 이동하면 다음과 같은 파일들을 볼 수 있다.

    • sample.sys

      • 타겟 PC에 위치해야 하는 샘플 드라이버 파일이다.

      • 가상 머신의 공유 폴더로 옮긴 뒤, 가상 머신 내부의 C:\sample\ 경로로 옮겨준다.

    • sample.pdb

      • 호스트 PC에 위치해야 하는 샘플 드라이버 심볼 파일이다.


드라이버 실행 및 디버깅

  • 가상 머신에서 관리자 권한으로 CMD를 실행시킨다.

    • 서비스 생성

      sc create sample binpath=c:\sample\sample.sys type=kernel start=demand
  • WinDbg에서 Break를 클릭하고, 아래 명령줄에 다음을 입력하여 sample 드라이버 모듈의 DriverEntry 함수에 브레이크 포인트를 건다.

    bp sample!DriverEntry
    • 디바이스가 아직 로딩되지 않았기 때문에, 다음 메시지가 출력되는게 정상이다.

      Bp expression 'sample!DriverEntry' could not be resolved, adding deferred bp
    • g를 입력하거나 Go를 클릭하여 가상 머신을 다시 running 상태로 만들어준다.

  • 가상 머신에서 드라이버를 로딩하기 위해 관리자 권한의 CMD에서 다음을 입력한다.

    sc start sample
    • TESTSIGNING 모드에서만 정상적으로 작동된다.

    • 가상 머신이 Break 되어 조작이 불가능한 것을 볼 수 있다.

  • WinDbg를 확인해보면 브레이크 포인트로 설정한 함수의 코드를 볼 수 있고, 메뉴의 View 탭에서 콜스택이나 변수들에 대한 정보 등 많은 것을 확인할 수 있다.

    • Step into, Step over 등의 trace도 가능하다. 굉장히 강력한 디버깅 툴이다.

    • Go를 누르든 Step over로 진행하든 아무튼 디버깅을 마치고 가상 머신의 CMD로 가보면 다음과 같은 메시지가 출력되어 있다.

      [SC] StartService 실패 31:
      
      시스템에 부착된 장치가 작동하지 않습니다.
      • 이는 DriverEntry 함수가 STATUS_UNSUCCESSFUL을 반환하기 때문이다.
Windows/DeviceDriver 2021. 4. 20. 01:29

2. 윈도우 디버거 환경을 준비하자


WinDBG

  • MS Windows의 다용도 디버거이다.

  • 유저 모드 애플리케이션 뿐만 아니라 장치 드라이버나 커널 모드에서 운영체제 자체를 디버깅할 수도 있다.

  • GUI가 있으며 VS 디버거보다 강력하다.

  • 덤프 파일을 통해 디버깅할 수 있다.

고려 사항

  • 타겟 컴퓨터(가상 머신)의 부트 설정을 변경해야 한다.

    • 디버깅이 가능하도록 부트설정을 변경한다.

      • 가상 머신의 실행 창에서 msconfig 입력 후, 부팅 탭에서 고급 옵션에 들어간다.

      • 전역 디버그 설정에서 디버그 포트를 COM1, 전송 속도를 115200으로 맞추고 확인을 누른다.

      • 종료하지 않고 TESTSIGNING 모드 설정을 진행한다.

    • TESTSIGNING 모드 설정

      • 윈도우에서 드라이버가 작동하려면 MS로부터 인증을 받아야 하는데, 테스트 환경으로 부팅하면 이러한 인증 절차가 생략된다.

      • CMD를 관리자 권한으로 실행 후, 아래 명령어를 입력한다.

        bcdedit /set testsigning on
      • 완료되면 가상 머신을 종료한다.

  • 호스트 컴퓨터에서도 설정해야 하는게 두 가지 있다.

    • 디버깅할 타겟 컴퓨터와 연결할 방법을 결정한다. (가상 시리얼 포트)

      • VirtualBox 가상 머신의 설정에서 직렬 포트 탭에 들어간다.

        • 직렬 포트 사용에 체크하고, 포트 번호를 위에서 설정한 포트 번호와 맞춰준다.

        • 포트 모드를 Host Pipe로 설정하고, Connect to existing pipe/socket을 체크 해제한다.

        • 아래의 Path/Address에 다음과 같이 입력한다.

          \\.\pipe\com1

      • WinDbg(x64)에서 포트를 설정해야 한다.

        • File - Kernel Debug (Ctrl + K) 클릭 후 COM 탭으로 이동한다.

        • Pipe와 Reconnect에 체크하고 포트를 아래와 같이 작성한다.

    • 타겟 컴퓨터의 운영체제 심볼을 자동으로 받도록 설정한다.

      • C:\sym\websym 폴더를 생성한다.

      • WinDbg의 File - Symbol File Path를 클릭하고 아래 내용을 작성한다.

        C:\sym;
      • 우측의 Help를 클릭하여 Search 탭에 web symbol을 검색한다.

        • Microsoft public symbol server를 클릭하면 다음과 같이 나온다.

          The Microsoft symbol server makes Windows debugger symbols publicly available.
          
          You can refer directly to the public symbol server in your symbol path in the following manner:
          
          set _NT_SYMBOL_PATH=srv*DownstreamStore*https://msdl.microsoft.com/download/symbols
        • srv 이하 내용을 복사하여 아까의 세미콜론 뒤에 붙여넣고, DownstreamStore을 지우고 C:\sym\websym을 작성한다.

          C:\sym;srv*C:\sym\websym*https://msdl.microsoft.com/download/symbols
      • 설정을 저장하기 위해 File - SaveWorkspace를 클릭한다.

실습

  • 위의 과정을 모두 마치고나서 가상 머신을 작동시키면, WinDbg에서 커맨드 창이 열리고 다음과 같이 뜨는 것을 볼 수 있다.

    Microsoft (R) Windows Debugger Version 10.0.19041.685 AMD64
    Copyright (c) Microsoft Corporation. All rights reserved.
    
    Opened \\.\pipe\com1
    Waiting to reconnect...
    Connected to Windows 10 19041 x64 target at (Sun Apr 18 21:01:11.597 2021 (UTC + 9:00)), ptr64 TRUE
    Kernel Debugger connection established.
    
    ************* Path validation summary **************
    Response                         Time (ms)     Location
    OK                                             C:\sym
    Deferred                                       srv*C:\sym\websym*https://msdl.microsoft.com/download/symbols
    Symbol search path is: C:\sym;srv*C:\sym\websym*https://msdl.microsoft.com/download/symbols
    Executable search path is: 
    Windows 10 Kernel Version 19041 MP (1 procs) Free x64
    Built by: 19041.1.amd64fre.vb_release.191206-1406
    Machine Name:
    Kernel base = 0xfffff801`37800000 PsLoadedModuleList = 0xfffff801`3842a3b0
    System Uptime: 0 days 0:00:00.000
    KDTARGET: Refreshing KD connection
    Capacity:25500, FullChargedCapacity:50000, Voltage:10000, Rate:0
  • 메뉴 탭의 Break를 클릭하면, 가상 머신을 멈출 수 있고 커맨드 창에 다음 내용이 출력된다.

    Break instruction exception - code 80000003 (first chance)
    *******************************************************************************
    *                                                                             *
    *   You are seeing this message because you pressed either                    *
    *       CTRL+C (if you run console kernel debugger) or,                       *
    *       CTRL+BREAK (if you run GUI kernel debugger),                          *
    *   on your debugger machine's keyboard.                                      *
    *                                                                             *
    *                   THIS IS NOT A BUG OR A SYSTEM CRASH                       *
    *                                                                             *
    * If you did not intend to break into the debugger, press the "g" key, then   *
    * press the "Enter" key now.  This message might immediately reappear.  If it *
    * does, press "g" and "Enter" again.                                          *
    *                                                                             *
    *******************************************************************************
    nt!DbgBreakPointWithStatus:
    fffff801`37bfd0b0 cc              int     3
    • 다시 Go 버튼을 누를 때까지 가상 머신이 멈춘 상태로 유지된다.
Windows/DeviceDriver 2021. 4. 20. 01:28

1. 윈도우 드라이버 개발 환경 준비


WDK(Windows Driver Kit) 설치

  • https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk 의 내용을 따라가면 된다.

  • Step 1 : Visual Studio 2019 설치

    • 설치할 때 Desktop development with C++을 선택하고, 우측 Installation details의 모든 항목을 체크하여 설치하는 것을 추천한다.

    • 다운로드 속도가 너무 느리면 VPN을 사용하거나, MS 다운로드 서버의 IP를 변경하면 된다고 한다.

      • 계속 You require permission from SYSTEM to make changes to this file 오류가 발생했는데, 백신이 실시간 감시로 차단하고 있었다...
  • Step 1.5 : 윈도우 10 2004 버전을 위한 SDK 10.0.19041.685 설치

    • 나는 왜인지 모르겠는데 VS에 같이 설치되어 있었다.
  • Step 2 : WDK 다운로드

  • EWDK는 IDE 없이 CLI로 윈도우 디바이스 드라이버를 개발할 수 있도록 제공하는 것이다.


WDK 7600 설치

  • 비주얼 스튜디오 없이 standalone으로 나온, 구버전의 WDK이다.

  • 도움말이 굉장히 훌륭해서, MSDN에 검색하지 않고 이 도움말을 활용하면 좋다고 한다.

  • 설치

    • 공식 사이트(https://www.microsoft.com/en-us/download/details.aspx?id=11800)에서 iso 파일을 받는다.

    • Explorer로 iso 파일을 열어서 마운트시킨다.

    • KitSetup.exe 파일을 실행하고, Help (Documentation Collection)만 체크하고 설치를 진행한다.

    • WDK Documentation을 검색해서 실행시킬 수 있다.

  • 왼쪽 아래의 Index 탭에서 검색하여 원하는 내용을 찾을 수 있다.


VirtualBox에 윈도우10 설치

  • 나는 윈도우 10 iso 이미지를 공식 홈페이지에서 다운로드 받은 후, VirtualBox에서 설치했다.

  • 강의에서는 최신 버전의 윈도우가 무겁기 때문에 구버전의 윈도우 10을 구해서 가볍고 빠르게 사용하기를 추천한다.


프로젝트 생성

  • VS에서 Kernel Mode Driver, USB(KMDF)를 선택하여 프로젝트를 생성한다.

  • x64로 변경 후 빌드해보면, 다음과 같은 에러가 발생한다.

    error MSB8040: Spectre-mitigated libraries are required for this project. Install them from the Visual Studio installer (Individual components tab) for any toolsets and architectures being used. Learn more: https://aka.ms/Ofhn4c
  • 이는 보안 요소에 관한 에러이고, 당장은 신경쓰지 않아도 되므로 설정에서 비활성화한다.

    • 프로젝트의 속성에서 C/C++ - Code Generation의 맨 아래 Spectre Mitigation 항목을 Disabled로 변경한다.