본문 바로가기
정상을향해/OS·Kernel Driver·Rootkit

2장. 커널 조작 - 윈도우 디바이스 드라이버 개발

by 사이테일 2014. 1. 10.

윈도우 XP와 윈도우 2000 플랫폼에서 동작하는 간단한 디바이스 드라이버를 작성해보자.


다음은 단순히 "Hello World!"를 출력하는 디바이스 드라이버다.


mydriver.c

#include "ntddk.h"
NTSTATUS DriverEntry ( IN PDRIVER_OBJECT theDriverObject,
IN PUNICODE_STRING theRegistryPath )
{
	DbgPrint("Hello World!");
	return STATUS_SUCCESS;
}

이 코드를 커널에 로드해 동작시키면 디버그 문자열이 출력될 것이다.




Device Driver Development Kit (DDK)


윈도우 디바이스 드라이버를 개발하려면 Driver Development Kit(DDK)이 필요하다.



빌드환경


DDK는 두 가지 다른 개발 환경을 제공한다.


checked와 free 빌드 환경인데, 디바이스 드라이버를 개발하는 과정에서는 checked 빌드 환경을 사용하고,


개발이 완료된 드라이버를 배포할 때는 free 빌드 환경을 사용한다.


checked 빌드는 디버그 정보를 포함해서 컴파일하기 때문에 free 빌드로 컴파일한 버전보다 사이즈가 훨씬 크다.


따라서 대부분의 개발 작업에서는 항상 checked 빌드 환경을 사용해야 하고,


최종적인 버전을 테스트할 때만 free 빌드 환경을 사용해야 한다.



파일


SOURCES 파일


SOURCES 파일은 파일 이름이 항상 대문자로 SOURCES이어야 하고 파일 확장자가 없다.


다음은 SOURCES 파일이 포함해야 하는 내용을 보여주고 있다.


TARGETNAME=MYDRIVER
TARGETPATH=OBJ
TARGETTYPE=DRIVER
SOURCES=mydriver.c

TARGETNAME 변수에는 드라이버의 이름을 할당한다.


TARGETNAME에 설정된 이름은 드라이버 바이너리에 포함되기 때문에 TARGETNAME에는 이미 작동하는 드라이버들의 이름과 유사하게 설정하는게 좋다.


TARGETPATH 변수는 일반적으로 OBJ로 설정된다.


이 것은 파일이 컴파일되어 어디에 저장되는지를 나타낸다.


일반적으로 드라이버 파일은 현재 디렉토리의 objchk_xxx/i386 하위 디렉토리에 위치한다.


TARGETTYPE 변수는 컴파일하는 파일의 종류를 나타낸다. 드라이버인 경우에는 DRIVER라고 설정한다.


SOURCES 항목에는 소스 파일인 .c 파일을 명시한다. 여러 줄을 이용해서 소스 파일을 명시하고자 한다면 백슬래시를 이용하면 된다. (마지막 줄에는 백슬래시가 없다.)


선택적으로 INCLUDES 변수를 추가로 이용할 수도 있다.


이를 이용해 인클루드 파일이 위치하는 디렉토리를 명시할 수 있다.


링크해야 할 라이브러리가 있는 경우에는 TARGETLIBS 변수를 이용해야 한다.


예를 들어 NDIS 라이브러리를 사용하는 경우 다음과 같은 형태로 선언해야 한다.


TARGETLIBS=$(BASEDIR)\lib\w2k\i386\ndis.lib

또는
TARGETLIBS=$(DDK_LIB_PATH)\ndis.lib


NDIS 드라이버를 만들 때 필요한 ndis.lib가 자신의 시스템 어느 위치에 존재하는지를 찾아서 그 경로를 TARGETLIBS 변수에 설정하면 된다.


$(BASEDIR)은 DDK가 설치된 경로를 의미하고 $(DDK_LIB_PAATH)는 디폴트 라이브러리가 설치된 경로를 의미한다.


그 외의 나머지 경로는 DDK가 설치된 시스템과 DDK의 버전에 따라 달라질 수 있다.



MAKEFILE 파일


MAKEFILE은 확장자가 없으며 내용은 다음과 같은 내용을 포함해야 한다.


!INCLUDE $(NTMAKEENV)\makefile.def