Microsoft MVP성태의 닷넷 이야기
디버깅 기술: 2. 커널 구조체 살펴보기 [링크 복사], [링크+제목 복사]
조회: 26352
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 4개 있습니다.)
환경: Windows 2003 SP1 R2
     VS.NET 2005
     Debugging Tools for Windows 6.6.3.5

처음부터 설명드리는 것이 좋겠지요. ^^

우선, WinDBG.exe가 설치되어져야 합니다. 현재 WinDBG는 "Debugging Tools for Windows"를 통해서 구할 수 있는데, 설치 파일은 다음의 경로에서 다운로드 받을 수 있습니다.

Debugging Tools for Windows - Overview
; https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools

설치해도 30MB 가량의 크기이기 때문에, 잘 사용하지 않더라도 그냥 설치해 둬도 무방할 것입니다.

설치가 완료되었으면, 다음 경로의 windbg.exe를 실행시킵니다.
C:\Program Files\Debugging Tools for Windows

그럼, 다음 화면과 같이 실행되는데... ^^; 썰렁합니다.

WinDBG 실행화면

사실, 처음 대할 때는 어디서 부터 건드려야 할지 엄두가 안 납니다. Device Driver 개발하는 사람들이야 회사 분위기 속에서 자연스럽게 배웠을 수 도 있겠지만, Windows SDK 분야만 다뤄본 사람들은 그렇지가 못하죠.

일단은, 우리의 목표가 거창하게 Device Driver를 개발할 것은 아니기 때문에 SDK 개발자 나름대로의 이해의 폭을 넓히기 위한 정도로만 사용해 보도록 하겠습니다. 따라서, 원격 컴퓨터 연결은 하지 않고, 로컬에만 연결해서 사용해 볼텐데요.

"File" / "Kernel Debug" 메뉴를 선택하고 나온 대화창에서 아래와 같이 "Local" 탭을 눌러주고, 그 상태에서 "OK" 버튼을 눌러줍니다.

Local Debug 모드

그러면, 다음과 같이 Command 창이 뜨는 것을 확인할 수 있습니다. 만약 아래의 Command 창이 보이지 않는 다면, "View" / "Command" 메뉴를 실행해서 나타나게 할 수 있습니다.

Command 창

Command 창의 내용을 잘 보시면, "Symbol search path is : *** Invalid ***"라는 것이 눈에 들어오는데, 별로 바람직하지 않은 상황이란 것만은 확실한 것 같습니다. ^^; 아울러, 그 아래에 친절하게 _NT_SYMBOL_PATH 등을 설정하라고 나오는데요.

Debugging에 대해서 좀 아신다면 PDB가 Symbol 파일이라는 것 정도는 이미 알고 계시겠지요. 바로 운영체제에 대한 PDB 파일이 있어야 한다는 것인데, Microsoft는 자사의 모든 제품의 Symbol 파일을 웹으로부터 자동으로 다운로드 받을 수 있도록 하는 기능을 제공해 주고 있는데, 그와 관련하여 _NT_SYMBOL_PATH 환경 변수를 설정할 수 있도록 하고 있습니다.

따라서, 다음과 같이 "My Computer" 속성창의 "Advanced" 탭의 "Environment Variables"를 통해서 설정하도록 합니다.

_NT_SYMBOL_PATH 환경 변수 설정

구체적인 내용은 다음과 같이 해줍니다. (각자 자신의 환경에 맞게 설정해 주시면 됩니다.)

_NT_SYMBOL_PATH

SRV*\\localhost\e$\cachedSymbols*http://msdl.microsoft.com/download/symbols;C:\Windows\system32;.

자, 이제 다시 WinDbg.exe를 실행시키고, "Local" 디버그를 선택하면, 다음과 같은 내용으로 Command 창이 뜹니다.

Symbol 로딩중

위의 화면에서 잠시 멈춰있게 되는데, 바로 이 순간에 환경 변수에서 지정된 Microsoft의 Symbol 서버로부터 ntoskrnl.pdb 파일을 다운로드 받기 때문입니다. 물론, 한번 받은 이후에는 지정된 경로에 캐쉬될 것을 사용하므로 다음번에는 실행이 빠르게 이뤄집니다.

결국 최종적으로 다음과 같은 화면이 나와야 됩니다.

Symbol 이 정상적으로 지정되어 실행된 화면

자, 이제 하나 하나씩 명령어를 익혀 볼까요? ^^

우선, 현재 로드된 모듈의 목록을 보여주는 명령어로 "lm"이 있습니다.
lm 명령어를 실행하게 되면, 다음과 같은 출력이 보여집니다.

start    end        module name
80800000 80a6b000   nt         (pdb symbols)          \\sedona\d$\Symbol\OSSymbols\ntoskrnl.pdb\4106003FF97D4BCBA99245BF2172A8C12\ntoskrnl.pdb

Unloaded modules:
f8677000 f8685000   imapi.sys
f7e40000 f7e54000   redbook.sys
f873f000 f8747000   Sfloppy.SYS

보시는 것처럼, ntoskrnl.exe 모듈의 경우 정상적으로 pdb 파일이 로드되었음을 확인할 수 있습니다.

자, 이제 오늘의 본래 목표였던 커널에서 사용되고 있는 구조체의 값을 확인하는 것을 보도록 하겠습니다. 여기서 2번째 명령어로 "dt" (display type) 명령어를 익히겠습니다. 다음과 같이 명령어를 입력하면,

dt _eprocess

위의 명령은, _EPROCESS 구조체의 구조를 출력하라는 것입니다. 따라서 다음과 같은 출력 결과가 나옵니다.

nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x078 ProcessLock      : _EX_PUSH_LOCK
   +0x080 CreateTime       : _LARGE_INTEGER
   +0x088 ExitTime         : _LARGE_INTEGER
   +0x090 RundownProtect   : _EX_RUNDOWN_REF
   +0x094 UniqueProcessId  : Ptr32 Void
   +0x098 ActiveProcessLinks : _LIST_ENTRY
   +0x0a0 QuotaUsage       : [3] Uint4B
   +0x0ac QuotaPeak        : [3] Uint4B
   +0x0b8 CommitCharge     : Uint4B
   +0x0bc PeakVirtualSize  : Uint4B
   +0x0c0 VirtualSize      : Uint4B
   +0x0c4 SessionProcessLinks : _LIST_ENTRY
   +0x0cc DebugPort        : Ptr32 Void
   +0x0d0 ExceptionPort    : Ptr32 Void
   +0x0d4 ObjectTable      : Ptr32 _HANDLE_TABLE
   +0x0d8 Token            : _EX_FAST_REF
   +0x0dc WorkingSetPage   : Uint4B
   +0x0e0 AddressCreationLock : _KGUARDED_MUTEX
   +0x100 HyperSpaceLock   : Uint4B
   +0x104 ForkInProgress   : Ptr32 _ETHREAD
   +0x108 HardwareTrigger  : Uint4B
   +0x10c PhysicalVadRoot  : Ptr32 _MM_AVL_TABLE
   +0x110 CloneRoot        : Ptr32 Void
   +0x114 NumberOfPrivatePages : Uint4B
   +0x118 NumberOfLockedPages : Uint4B
   +0x11c Win32Process     : Ptr32 Void
   +0x120 Job              : Ptr32 _EJOB
   +0x124 SectionObject    : Ptr32 Void
   +0x128 SectionBaseAddress : Ptr32 Void
   +0x12c QuotaBlock       : Ptr32 _EPROCESS_QUOTA_BLOCK
   +0x130 WorkingSetWatch  : Ptr32 _PAGEFAULT_HISTORY
   +0x134 Win32WindowStation : Ptr32 Void
   +0x138 InheritedFromUniqueProcessId : Ptr32 Void
   +0x13c LdtInformation   : Ptr32 Void
   +0x140 VadFreeHint      : Ptr32 Void
   +0x144 VdmObjects       : Ptr32 Void
   +0x148 DeviceMap        : Ptr32 Void
   +0x14c Spare0           : [3] Ptr32 Void
   +0x158 PageDirectoryPte : _HARDWARE_PTE
   +0x158 Filler           : Uint8B
   +0x160 Session          : Ptr32 Void
   +0x164 ImageFileName    : [16] UChar
   +0x174 JobLinks         : _LIST_ENTRY
   +0x17c LockedPagesList  : Ptr32 Void
   +0x180 ThreadListHead   : _LIST_ENTRY
   +0x188 SecurityPort     : Ptr32 Void
   +0x18c PaeTop           : Ptr32 Void
   +0x190 ActiveThreads    : Uint4B
   +0x194 GrantedAccess    : Uint4B
   +0x198 DefaultHardErrorProcessing : Uint4B
   +0x19c LastThreadExitStatus : Int4B
   +0x1a0 Peb              : Ptr32 _PEB
   +0x1a4 PrefetchTrace    : _EX_FAST_REF
   +0x1a8 ReadOperationCount : _LARGE_INTEGER
   +0x1b0 WriteOperationCount : _LARGE_INTEGER
   +0x1b8 OtherOperationCount : _LARGE_INTEGER
   +0x1c0 ReadTransferCount : _LARGE_INTEGER
   +0x1c8 WriteTransferCount : _LARGE_INTEGER
   +0x1d0 OtherTransferCount : _LARGE_INTEGER
   +0x1d8 CommitChargeLimit : Uint4B
   +0x1dc CommitChargePeak : Uint4B
   +0x1e0 AweInfo          : Ptr32 Void
   +0x1e4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
   +0x1e8 Vm               : _MMSUPPORT
   +0x230 MmProcessLinks   : _LIST_ENTRY
   +0x238 ModifiedPageCount : Uint4B
   +0x23c JobStatus        : Uint4B
   +0x240 Flags            : Uint4B
   +0x240 CreateReported   : Pos 0, 1 Bit
   +0x240 NoDebugInherit   : Pos 1, 1 Bit
   +0x240 ProcessExiting   : Pos 2, 1 Bit
   +0x240 ProcessDelete    : Pos 3, 1 Bit
   +0x240 Wow64SplitPages  : Pos 4, 1 Bit
   +0x240 VmDeleted        : Pos 5, 1 Bit
   +0x240 OutswapEnabled   : Pos 6, 1 Bit
   +0x240 Outswapped       : Pos 7, 1 Bit
   +0x240 ForkFailed       : Pos 8, 1 Bit
   +0x240 Wow64VaSpace4Gb  : Pos 9, 1 Bit
   +0x240 AddressSpaceInitialized : Pos 10, 2 Bits
   +0x240 SetTimerResolution : Pos 12, 1 Bit
   +0x240 BreakOnTermination : Pos 13, 1 Bit
   +0x240 SessionCreationUnderway : Pos 14, 1 Bit
   +0x240 WriteWatch       : Pos 15, 1 Bit
   +0x240 ProcessInSession : Pos 16, 1 Bit
   +0x240 OverrideAddressSpace : Pos 17, 1 Bit
   +0x240 HasAddressSpace  : Pos 18, 1 Bit
   +0x240 LaunchPrefetched : Pos 19, 1 Bit
   +0x240 InjectInpageErrors : Pos 20, 1 Bit
   +0x240 VmTopDown        : Pos 21, 1 Bit
   +0x240 ImageNotifyDone  : Pos 22, 1 Bit
   +0x240 PdeUpdateNeeded  : Pos 23, 1 Bit
   +0x240 VdmAllowed       : Pos 24, 1 Bit
   +0x240 SmapAllowed      : Pos 25, 1 Bit
   +0x240 CreateFailed     : Pos 26, 1 Bit
   +0x240 DefaultIoPriority : Pos 27, 3 Bits
   +0x240 Spare1           : Pos 30, 1 Bit
   +0x240 Spare2           : Pos 31, 1 Bit
   +0x244 ExitStatus       : Int4B
   +0x248 NextPageColor    : Uint2B
   +0x24a SubSystemMinorVersion : UChar
   +0x24b SubSystemMajorVersion : UChar
   +0x24a SubSystemVersion : Uint2B
   +0x24c PriorityClass    : UChar
   +0x250 VadRoot          : _MM_AVL_TABLE
   +0x270 Cookie           : Uint4B

와... ^^ 프로세스 구조를 알아냈으니, 스레드 구조도 알아보겠습니다. 다음과 같이 실행시키면 됩니다.

dt _ethread

오늘은, 여기까지.
[연관 글]






[최초 등록일: ]
[최종 수정일: 4/5/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2007-11-06 07시40분
kevin25
2008-03-04 01시25분
kevin25
2008-03-27 09시03분
kevin25
2011-03-08 10시24분
Effective WinDbg breakpoints using hit counts
; (broken) http://blogs.msdn.com/b/yizhang/archive/2011/03/07/effective-windbg-breakpoints-using-hit-counts.aspx
정성태
2020-01-14 10시07분
정성태

... [16]  17  18  19  20  21  22  23  24  25  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
13220정성태1/19/20234281오류 유형: 837. NETSDK1045 The current .NET SDK does not support targeting .NET ...
13219정성태1/18/20233856Windows: 220. 네트워크의 인터넷 접속 가능 여부에 대한 판단 기준
13218정성태1/17/20233780VS.NET IDE: 178. Visual Studio 17.5 (Preview 2) - 포트 터널링을 이용한 웹 응용 프로그램의 외부 접근 허용
13217정성태1/13/20234381디버깅 기술: 185. windbg - 64비트 운영체제에서 작업 관리자로 뜬 32비트 프로세스의 덤프를 sos로 디버깅하는 방법
13216정성태1/12/20234648디버깅 기술: 184. windbg - 32비트 프로세스의 메모리 덤프인 경우 !peb 명령어로 나타나지 않는 환경 변수
13215정성태1/11/20236147Linux: 56. 리눅스 - /proc/pid/stat 정보를 이용해 프로세스의 CPU 사용량 구하는 방법 [1]
13214정성태1/10/20235724.NET Framework: 2087. .NET 6부터 SourceGenerator와 통합된 System.Text.Json [1]파일 다운로드1
13213정성태1/9/20235259오류 유형: 836. docker 이미지 빌드 시 "RUN apt install ..." 명령어가 실패하는 이유
13212정성태1/8/20235024기타: 85. 단정도/배정도 부동 소수점의 정밀도(Precision)에 따른 형변환 손실
13211정성태1/6/20235106웹: 42. (https가 아닌) http 다운로드를 막는 웹 브라우저
13210정성태1/5/20234131Windows: 219. 윈도우 x64의 경우 0x00000000`7ffe0000 아래의 주소는 왜 사용하지 않을까요?
13209정성태1/4/20234023Windows: 218. 왜 윈도우에서 가상 메모리 공간은 64KB 정렬이 된 걸까요?
13208정성태1/3/20233957.NET Framework: 2086. C# - Windows 운영체제의 2MB Large 페이지 크기 할당 방법파일 다운로드1
13207정성태12/26/20224268.NET Framework: 2085. C# - gpedit.msc의 "User Rights Assignment" 특권을 코드로 설정/해제하는 방법파일 다운로드1
13206정성태12/24/20224471.NET Framework: 2084. C# - GetTokenInformation으로 사용자 SID(Security identifiers) 구하는 방법 [3]파일 다운로드1
13205정성태12/24/20224869.NET Framework: 2083. C# - C++과의 연동을 위한 구조체의 fixed 배열 필드 사용 (2)파일 다운로드1
13204정성태12/22/20224149.NET Framework: 2082. C# - (LSA_UNICODE_STRING 예제로) CustomMarshaler 사용법파일 다운로드1
13203정성태12/22/20224277.NET Framework: 2081. C# Interop 예제 - (LSA_UNICODE_STRING 예제로) 구조체를 C++에 전달하는 방법파일 다운로드1
13202정성태12/21/20224652기타: 84. 직렬화로 설명하는 Little/Big Endian파일 다운로드1
13201정성태12/20/20225275오류 유형: 835. PyCharm 사용 시 C 드라이브 용량 부족
13200정성태12/19/20224156오류 유형: 834. 이벤트 로그 - SSL Certificate Settings created by an admin process for endpoint
13199정성태12/19/20224434개발 환경 구성: 656. Internal Network 유형의 스위치로 공유한 Hyper-V의 VM과 호스트가 통신이 안 되는 경우
13198정성태12/18/20224312.NET Framework: 2080. C# - Microsoft.XmlSerializer.Generator 처리 없이 XmlSerializer 생성자를 예외 없이 사용하고 싶다면?파일 다운로드1
13197정성태12/17/20224267.NET Framework: 2079. .NET Core/5+ 환경에서 XmlSerializer 사용 시 System.IO.FileNotFoundException 예외 발생하는 경우파일 다운로드1
13196정성태12/16/20224393.NET Framework: 2078. .NET Core/5+를 위한 SGen(Microsoft.XmlSerializer.Generator) 사용법
13195정성태12/15/20224987개발 환경 구성: 655. docker - bridge 네트워크 모드에서 컨테이너 간 통신 시 --link 옵션 권장 이유
... [16]  17  18  19  20  21  22  23  24  25  26  27  28  29  30  ...