본문 바로가기
Programming/7. Device Driver

드라이버 개발 핵심 - 9화 첫 번째 커널 드라이버

by S.W 2026. 5. 27.
Windows 커널 & 드라이버 시리즈 — 9화

첫 번째 커널 드라이버 — Hello Kernel World

📅 2026 ⏱ 읽기 약 15분 🏷 드라이버 개발 / 입문 코드
드디어 코드를 쓸 때가 됐어요! 이번 화에서는 가장 간단한 커널 드라이버를 직접 작성하고, 빌드하고, VM에서 실제로 로드해볼 거예요. "Hello World"는 단순해 보이지만, 이 안에 드라이버의 핵심 구조가 모두 담겨있어요.

드라이버의 기본 골격

일반 C 프로그램은 main()에서 시작하죠. 커널 드라이버는 DriverEntry()에서 시작합니다. OS가 드라이버를 로드할 때 이 함수를 가장 먼저 호출해요.

#include <ntddk.h> // 드라이버 언로드 함수 (선택이지만 거의 필수) VOID DriverUnload(_In_ PDRIVER_OBJECT DriverObject) { UNREFERENCED_PARAMETER(DriverObject); DbgPrint("[HelloKernel] Driver unloaded.\n"); } // 드라이버 진입점 — 여기서 모든 것이 시작됩니다 NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { UNREFERENCED_PARAMETER(RegistryPath); DbgPrint("[HelloKernel] Hello from the kernel!\n"); // 언로드 루틴 등록 (안 하면 드라이버를 멈출 수 없어요) DriverObject->DriverUnload = DriverUnload; return STATUS_SUCCESS; }

딱 이것만으로도 동작하는 드라이버예요. 하나씩 뜯어볼게요.

#include <ntddk.h>

드라이버 개발의 핵심 헤더예요. NTSTATUS, DbgPrint, PDRIVER_OBJECT 같은 타입과 함수들이 여기 정의되어 있어요. 유저 모드 앱에서 windows.h를 쓰는 것처럼, 드라이버에서는 ntddk.h가 기본이에요.

NTSTATUS — 드라이버의 반환값

드라이버 함수들은 대부분 NTSTATUS 값을 반환해요. 성공이면 STATUS_SUCCESS(0), 실패면 오류 코드를 반환합니다. NT_SUCCESS(status) 매크로로 성공 여부를 확인하는 게 관례예요.

DriverObject — 드라이버 자신을 나타내는 구조체

DRIVER_OBJECT는 OS가 만들어서 DriverEntry에 넘겨주는 구조체예요. 여기에 드라이버의 IRP 처리 함수(DispatchRoutine), 언로드 함수 등을 등록합니다. 이 구조체가 곧 드라이버의 "신분증"이에요.

DriverUnload — 꼭 등록하세요

언로드 루틴을 등록하지 않으면, sc stop으로 드라이버를 멈추려 해도 OS가 거부해요. 운영 중에 드라이버를 교체하거나 수정하려면 언로드가 가능해야 하니, 항상 등록하는 게 좋아요.

Visual Studio에서 프로젝트 만들기

  1. Visual Studio → 새 프로젝트 → "Kernel Mode Driver (KMDF)" 선택
  2. 프로젝트 이름: HelloKernel
  3. 생성된 .c 파일의 내용을 위의 코드로 교체
  4. 솔루션 플랫폼을 x64로 변경
  5. 구성을 Release로 변경 후 빌드 (Ctrl+B)

빌드가 성공하면 x64\Release\HelloKernel.sys 파일이 생성됩니다.

⚠️ KMDF vs WDM 템플릿 Visual Studio에 KMDF와 WDM 두 가지 커널 드라이버 템플릿이 있어요. 이번 실습은 최소한의 코드를 보기 위해 WDM 방식으로 작성했어요. KMDF는 더 현대적인 프레임워크인데, 19화에서 자세히 다룹니다.

VM에서 드라이버 로드하기

HelloKernel.sys를 VM에 복사한 뒤, 관리자 CMD에서:

# 드라이버 등록 sc create HelloKernel type= kernel binPath= "C:\Test\HelloKernel.sys" # 드라이버 로드 sc start HelloKernel # WinDbg 또는 DebugView에서 확인: # [HelloKernel] Hello from the kernel! # 드라이버 언로드 sc stop HelloKernel sc delete HelloKernel
💡 DebugView로 DbgPrint 메시지 보기 WinDbg가 연결되어 있지 않아도, Sysinternals의 DebugView를 VM에서 실행하면 DbgPrint 메시지를 볼 수 있어요. Options → "Capture Kernel"을 활성화하면 됩니다.

DbgPrint 메시지가 안 보인다면?

기본 설정에서는 DbgPrint 메시지가 필터링될 수 있어요. 레지스트리에서 디버그 출력 레벨을 조정해야 합니다:

; VM의 레지스트리 편집기에서: ; HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter ; 키가 없으면 새로 만들고 ; "DEFAULT" DWORD 값을 0xFFFFFFFF로 설정
✅ 9화 요약
  • 드라이버의 진입점은 DriverEntry()이며, OS가 드라이버 로드 시 호출합니다.
  • 핵심 헤더는 ntddk.h, 반환값은 NTSTATUS를 사용합니다.
  • DriverUnload를 반드시 등록해야 드라이버를 동적으로 언로드할 수 있어요.
  • DbgPrint()로 커널 메시지를 출력하고 WinDbg/DebugView로 확인합니다.
다음 화
10화 — DriverEntry와 드라이버 오브젝트: DRIVER_OBJECT 구조체 완전 해부 →

#HelloKernel #DriverEntry #첫번째드라이버 #ntddk #DbgPrint