[시작하면서]


 


이 문서는 2001년에 작성된 것을 기반으로 다시 정리한 것임을 밝힙니다. 현재
더 좋은 솔루션이 있다면 공유하여주시면 감사하겠습니다.


 


다음은 설명에 필요한 환경입니다.


Windows
2000 pro, SoftICE 4.05, VC++ 6.0, Windows DDK 2000 oct


 


DDK xp 버전도 동일했으므로 요즘 나오는 것도 될것으로 생각합니다.


 


[알게된 과정]


 


처음에는 Windows Driver Model이라는 책에서 제공하는 VC app wizard를 사용하여
약간 수정하여 VC Kernel Mode NTDDK 환경을 만들었습니다.


다음과 같은 방법이었습니다.


 


WDM책의 부록 씨디 안의 wdmwiz.awx 파일을 아래 폴더에 놓고 VC를 실행시킵니다.


C:\Program
Files\Microsoft Visual Studio\Common\MSDev98\Bin\IDE


 


그러면 프로젝트 생성시 뜨는 App Wizard에 WDM 드라이버 위자드가 뜨는데 이를
선택한 후 처음 위자드 페이지에서 선택된것을 모두 빼고, Empty Driver를 선택 후,
Finish를 선택합니다.


그런 후 Project/Setting에 가신 후  C++ 섹션에서 아래 부분에 "$(DDKPATH)\inc\ddk\wdm"
을 "$(DDKPATH)\inc\ddk" 으로 수정한후


Link섹션에 wdm.lib를 hal.lib ntoskrnl.lib 로 수정한 후 컴파일 하면 sys파일이
만들어지게 됩니다.


 


이렇게 사용하다보니 하다보니 WDM 위자드 없이 적절히 C++과 Linking 옵션을
주어서 ddk 컴파일 환경을 만들 수 있다는 것을 알게 되었습니다.


 


 


[DDK in VC]


 


Win32 Empty Project로 프로젝트를 생성합니다.


Project / Setting을 선택 한 후 아래와 같이 C++과 Link 옵션을 수정해 주면
됩니다.



 


 


 Debug Setting


 


C++ Option


/nologo
/Gz /MLd /W3 /Zi /Od /Gy /I "$(DDKPATH)\inc" /I


"$(DDKPATH)\inc\ddk"
/FI"$(DDKPATH)\inc\warning.h" /D "WIN32" /D


"_DEBUG"
/D "_WINDOWS" /D "_MBCS" /D _X86_=1 /D i386=1 /D


"STD_CALL"
/D CONDITION_HANDLING=1 /D NT_UP=1 /D NT_INST=0 /D


WIN32=100 /D _NT1X_=100 /D
WINNT=1 /D _WIN32_WINNT=0x0500 /D


_WIN32_IE=0x0400 /D WIN32_LEAN_AND_MEAN=1
/D DBG=1 /D DEVL=1


/D FPO=0 /D "NDEBUG" /D _DLL=1 /D "DRIVER"
/D "_IDWBUILD" /D


"RDRDBG" /D "SRVDBG" /FR"Debug/"
/Fp"Debug/FileSM.pch" /YX


/Fo"Debug/" /Fd"Debug/"
/FD /Zel -cbstring /QIfdiv- /QI0f /GF /QIf /c


 


 


Link Option


hal.lib
ntoskrnl.lib libcmt.lib /nologo /base:"0x10000" /version:4.0


/entry:"DriverEntry@8"
/subsystem:windows /incremental:yes


/pdb:"Debug/TestDev.pdb" /debug
/debugtype:both /machine:I386


/nodefaultlib /out:"debug\TestDev.sys"



/libpath:"$(DDKPATH)\libchk\i386" -MERGE:_PAGE=PAGE


-MERGE:_TEXT=.text
-MERGE:.rdata=.text -SECTION:INIT,d -OPT:REF


-FORCE:MULTIPLE -RELEASE -FULLBUILD



-IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096


-osversion:4.00 -optidata
-driver -align:0x20 -subsystem:native,4.00


-debug:notmapped,FULL


 


 


Release Setting


 


C++ Option


/nologo
/Gz /ML /W3 /O1 /I "$(DDKPATH)\inc" /I


"$(DDKPATH)\inc\ddk"
/FI"$(DDKPATH)\inc\warning.h" /D "WIN32" /D


"NDEBUG"
/D "_WINDOWS" /D "_MBCS" /D _X86_=1 /D i386=1 /D


"STD_CALL"
/D CONDITION_HANDLING=1 /D NT_UP=1 /D NT_INST=0 /D


WIN32=100 /D _NT1X_=100 /D
WINNT=1 /D _WIN32_WINNT=0x0500 /D


_WIN32_IE=0x0400 /D WIN32_LEAN_AND_MEAN=1
/D DBG=1 /D DEVL=1


/D FPO=0 /D _DLL=1 /D "DRIVER" /D "_IDWBUILD"
/FR"Release/"


/Fp"Release/FSMon.pch" /YX /Fo"Release/"
/Fd"Release/" /FD /Zel


-cbstring /QIfdiv- /QI0f /GF /Oxs /c


 


Link Option


hal.lib
ntoskrnl.lib /nologo /base:"0x10000" /version:4.0


/entry:"DriverEntry@8"
/subsystem:windows /pdb:none /machine:I386


/nodefaultlib /out:"release\FSMon.sys"
/libpath:"$(DDKPATH)\libfre\i386"


-MERGE:_PAGE=PAGE -MERGE:_TEXT=.text
-MERGE:.rdata=.text


-SECTION:INIT,d -OPT:REF -FORCE:MULTIPLE -RELEASE -FULLBUILD



-IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096


-osversion:4.00 -optidata
-driver -align:0x20 -subsystem:native,4.00


-debug:notmapped,minimal


 


 


[VC with SoftICE]


 


VC에서 컴파일한 디바이스 드라이버를 로드 한 후 이를 디버깅 하기 위해서는
일반적으로 WinDBG를 사용하여 두개의 pc를 시리얼로 연결 후, 디버깅 pc의 boot.ini에
debug 옵션을 주어 디버그 할 수 있습니다. 어떤 이는 VMWare에 디버깅 guest os를
두어 가상 시리얼 연결로 디버깅 하기도 합니다. 저자 역시 시리얼로 연결하는
것을 유로 세미나를 들으면서 해보았지만 열악한 환경에서는 무척 매력적이지 안았습니다. 그러는
중에 SoftICE는 싱글머신 소스레벨 디버깅이 된다는 반가운 소식을 들었고, 성공적으로
프로젝트를 완수 할 수 있었습니다.


 


소프트 아이스에서 디버깅 하기 위해서 브레이크 포인트를 걸어야 하는데 소스에
직접 걸거나, 소프트 아이스에서 걸수가 있습니다. 만일 소스에서 걸길 원한다면


 


__asm
int 0x03;


 


을 넣으면 됩니다. 또는


 


DbgBreakPoint();


를 해도 됩니다. 이렇게 브레이크 포인트를 담은 드라이버를 실행 하면 해당 코드에서
소프트 아이스 디버깅 콘솔이 뜨게 됩니다.


 


(참고로 www.sysinternals.com
가시면 커널 모드 디버그 문자열도 보여주는 DebugView 유틸이 있습니다. 이를
이용하면 소스 레벨 디버깅은 불가능하지만 간단하게 디버그 문자열 출력을 볼 수
있습니다. )


 


이제 소프트 아이스를 사용하여 디버깅을 해 보겠습니다.


 


아래와 같이 소프트 아이스를 실행합니다.



 


소프트 아이스가 실행되었다면 Symbol Loader를 실행 한 후 Open으로 디버깅할
디바이스 드라이버 ( sys )를 엽니다.



 


위 그림처럼 툴바의 버튼이 눌렸는지 확인해 보아야 합니다.특히 Package With
Source 버튼은 눌려 있어야 소스 레벨 디버깅이 가능하게 됩니다. 되었다면
왼쪽의 세번째 버튼을 Translate 버튼으로 변환 후 왼쪽 두번째 버튼으로 변환후
생성된 디버깅용 심볼 파일 NMS를 로드하도록 합니다.


 



위와 같은 상황이 되었다면 디버깅 할 수 있는 준비가 끝난 것입니다.


 


만일 시스템에 의해서 이 후 드라이버가 로드되어 실행되고, 소스상의 브레이크
포인트가 실행될때 자동으로 소프트 아이스 디버그 콘솔창이 뜨게 될 것입니다.


 


저 같은 경우 Ctrl+D를 눌러 디버그 콘솔창을 부른 후, file * 명령을 주어 현재
소프트 아이스 디버깅에 올라온 파일이 있는지 확인 한 다음 u '파일명'을 한 후
u DriverEntry 를 해서 DriverEntry 소스 코드가 보이게 되면 그때 브레이크 포인트를
주어 작업을 하였습니다.


 


아래는 간단한 소프트 아이스 명령 입니다.


 


F10
: 한줄 실행한다.


F11
: 함수안으로 Step into 한다.


F3
or SRC : 소스 코드를 보여준다.


G
: 다음 브레이크 포인트까지 코드를 실행한다.


    (소스코드창에서
마우스 클릭으로 브이크 포인트를 걸 수 있다. )    


Watch
data : data라는 변수를 watch한다.    


WL
: 현재 로컬 지역 변수를 모두 보여준다.    


Ctrl+D
: 언제든지 소프트아이스 팝업 콘솔창을 열고 닫을 수 있다.


X
: 소프트 아이스 콘솔 창을 나온다.


 


 


정리


Visual C++의 에디팅과 컴파일 링킹 세팅을 하여 Kernel Mode 드라이버를
작성하는 방법을 알아 보았고, 소프트 아이스를 사용하여 싱글머신 소스레벨 디버깅
하는 방법을 알아 보았습니다.


http://www.debuglab.com 에 가시면 시리얼
케이블 연결이나 VMWare를 사용한 원격 디버깅에 대한 정보를 얻으실 수 있습니다.


 


 

'KB > tutorial' 카테고리의 다른 글

Implementation FAT File System  (0) 2004.11.04
How to i386 32bit OS Kernel Compile in VC6  (0) 2004.11.04
COM 형식 라이브러리 사용하기  (0) 2004.11.04
[winsock] 윈속 소켓 정리  (0) 2004.03.19
snmp 프로그래밍  (0) 2004.03.19

+ Recent posts