Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 3개 있습니다.)
디버깅 기술: 148. cdb.exe를 이용해 (ntdll.dll 등에 정의된) 커널 구조체 출력하는 방법
; https://www.sysnet.pe.kr/2/0/12092

.NET Framework: 874. C# - 커널 구조체의 Offset 값을 하드 코딩하지 않고 사용하는 방법
; https://www.sysnet.pe.kr/2/0/12098

디버깅 기술: 156. C# - PDB 파일로부터 심벌(Symbol) 및 타입(Type) 정보 열거
; https://www.sysnet.pe.kr/2/0/12114




cdb.exe를 이용해 (ntdll.dll 등에 정의된) 커널 구조체 출력하는 방법

커널 구조체들이 운영체제 버전 및 패치에 민감하다 보니 코드에 해당 offset 값들을 하드 코딩하는 게 영 탐탁지 않습니다. 게다가 offset 값들을 알아보는 것도 꽤나 귀찮은 작업인데요, 매번 windbg를 실행해 "dt" 명령어를 다음과 같이 실행해 offset이 맞는지 확인하는 식입니다.

0:001> dt _PEB
ntdll!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 BitField         : UChar
   +0x003 ImageUsesLargePages : Pos 0, 1 Bit
   +0x003 IsProtectedProcess : Pos 1, 1 Bit
...[생략]...
   +0x7b8 LeapSecondData   : Ptr64 _LEAP_SECOND_DATA
   +0x7c0 LeapSecondFlags  : Uint4B
   +0x7c0 SixtySecondEnabled : Pos 0, 1 Bit
   +0x7c0 Reserved         : Pos 1, 31 Bits
   +0x7c4 NtGlobalFlag2    : Uint4B

멋이 좀 덜하긴 하지만, 저 출력 작업만 명령행으로 구할 수 있다면 대강의 문자열 파싱으로 offset 값 구하는 것이 그리 어렵지 않을 것 같습니다. 이를 위해 cdb.exe를 이용할 수 있습니다.

CDB Command-Line Options
; https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/cdb-command-line-options

cdb, ntsd, windbg 등은 모두 같은 디버그 엔진(dbgeng.dll)을 사용하는 래퍼에 불과하다고 합니다. 또한 내부 사용 명령도 일관성을 유지하고 있는 데다 cdb.exe의 경우 명령행에서 전달하는 것도 가능하므로 다음과 같이 커널 구조체의 출력 결과를 쉽게 얻을 수 있습니다.

// "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe"

c:\temp> cdb -pn notepad.exe -c "dt _PEB; qd"

Microsoft (R) Windows Debugger Version 10.0.17763.168 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

*** wait with pending attach
Unable to add extension DLL: ntsdexts
Unable to add extension DLL: uext
Unable to add extension DLL: exts
The call to LoadLibrary(ext) failed, Win32 error 0n2
    "지정된 파일을 찾을 수 없습니다."
Please check your debugger configuration and/or network access.
Symbol search path is: srv*
Executable search path is:
ModLoad: 00007ff7`d8b60000 00007ff7`d8ba3000   C:\WINDOWS\system32\notepad.exe
ModLoad: 00007ff8`b76f0000 00007ff8`b78dd000   C:\WINDOWS\SYSTEM32\ntdll.dll
...[생략]...
ModLoad: 00007ff8`ade60000 00007ff8`ade9e000   C:\Windows\System32\IME\IMEKR\imkrapi.dll
ModLoad: 00007ff8`add90000 00007ff8`addcf000   C:\Windows\System32\IME\shared\imjkapi.dll
(c3c.17a4): Break instruction exception - code 80000003 (first chance)
ntdll!DbgBreakPoint:
00007ff8`b7793080 cc              int     3
0:001> cdb: Reading initial command 'dt _PEB; qd'
ntdll!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
...[생략]...
   +0x7c0 SixtySecondEnabled : Pos 0, 1 Bit
   +0x7c0 Reserved         : Pos 1, 31 Bits
   +0x7c4 NtGlobalFlag2    : Uint4B
quit:

그럼 이렇게 필터링하는 것도 가능하고,

c:\temp> cdb -pn notepad.exe -c "dt _PEB; qd" | findstr Ldr
   +0x018 Ldr              : Ptr64 _PEB_LDR_DATA

간단하게 저 출력만 분석하면 구조체 필드의 offset 값을 하드 코딩하지 않고 사용할 수 있을 것입니다.




그렇다면 cdb.exe를 실행하기 위한 최소한의 파일은 뭐가 있을까요? 우선, cdb.exe 자체는 여타 다른 의존성이 없습니다. 단지 커널 구조체를 가져오기 위해서는 대상이 되는 DLL(예를 들어 ntdll.dll)의 심벌 파일이 필요한데 cdb.exe만 복사해 실행하는 경우에는 다음과 같은 식으로 심벌 로드에 오류가 발생합니다.

0:007> .sympath SRV*c:\temp*http://msdl.microsoft.com/download/symbols
DBGHELP: Symbol Search Path: srv*c:\temp*http://msdl.microsoft.com/download/symbols
Symbol search path is: SRV*c:\temp*http://msdl.microsoft.com/download/symbols
Expanded Symbol search path is: srv*c:\temp*http://msdl.microsoft.com/download/symbols

************* Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       SRV*c:\temp*http://msdl.microsoft.com/download/symbols

0:007> .reload /s /f ntdll.dll
DBGHELP: C:\WINDOWS\SYSTEM32\ntdll.pdb - file not found
DBGHELP: ntdll.pdb - file not found
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\SYSTEM32\ntdll.dll -
DBGHELP: ntdll - export symbols

************* Symbol Loading Error Summary **************
Module name            Error
ntdll                  The system cannot find the file specified
                                The SYMSRV client failed to find a file in the UNC store, or there
                                is an invalid UNC store (an invalid path or the pingme.txt file is
                                not present in the root directory), or the file is present in the
                                symbol server exclusion list.

그래서 지난 글에 설명한,

pdb 파일을 다운로드하기 위한 symchk.exe 실행에 필요한 최소 파일
; https://www.sysnet.pe.kr/2/0/12091

내용에 따라 (symchk.exe는 필요 없으니) 다음의 4개 파일만 함께 복사해 주시면 됩니다.

  • cdb.exe
  • dbghelp.dll
  • SymbolCheck.dll
  • symsrv.dll




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 1/15/2025]

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

비밀번호

댓글 작성자
 




1  [2]  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13893정성태2/27/20252234Linux: 115. eBPF (bpf2go) - ARRAY / HASH map 기본 사용법
13892정성태2/24/20252986닷넷: 2325. C# - PowerShell과 연동하는 방법파일 다운로드1
13891정성태2/23/20252503닷넷: 2324. C# - 프로세스의 성능 카운터용 인스턴스 이름을 구하는 방법파일 다운로드1
13890정성태2/21/20252331닷넷: 2323. C# - 프로세스 메모리 중 Private Working Set 크기를 구하는 방법(Win32 API)파일 다운로드1
13889정성태2/20/20253062닷넷: 2322. C# - 프로세스 메모리 중 Private Working Set 크기를 구하는 방법(성능 카운터, WMI) [1]파일 다운로드1
13888정성태2/17/20252498닷넷: 2321. Blazor에서 발생할 수 있는 async void 메서드의 부작용
13887정성태2/17/20253077닷넷: 2320. Blazor의 razor 페이지에서 code-behind 파일로 코드를 분리 및 DI 사용법
13886정성태2/15/20252574VS.NET IDE: 196. Visual Studio - Code-behind처럼 cs 파일을 그룹핑하는 방법
13885정성태2/14/20253238닷넷: 2319. ASP.NET Core Web API / Razor 페이지에서 발생할 수 있는 async void 메서드의 부작용
13884정성태2/13/20253527닷넷: 2318. C# - (async Task가 아닌) async void 사용 시의 부작용파일 다운로드1
13883정성태2/12/20253271닷넷: 2317. C# - Memory Mapped I/O를 이용한 PCI Configuration Space 정보 열람파일 다운로드1
13882정성태2/10/20252582스크립트: 70. 파이썬 - oracledb 패키지 연동 시 Thin / Thick 모드
13881정성태2/7/20252839닷넷: 2316. C# - Port I/O를 이용한 PCI Configuration Space 정보 열람파일 다운로드1
13880정성태2/5/20253175오류 유형: 947. sshd - Failed to start OpenSSH server daemon.
13879정성태2/5/20253416오류 유형: 946. Ubuntu - N: Updating from such a repository can't be done securely, and is therefore disabled by default.
13878정성태2/3/20253198오류 유형: 945. Windows - 최대 절전 모드 시 DRIVER_POWER_STATE_FAILURE 발생 (pacer.sys)
13877정성태1/25/20253250닷넷: 2315. C# - PCI 장치 열거 (레지스트리, SetupAPI)파일 다운로드1
13876정성태1/25/20253711닷넷: 2314. C# - ProcessStartInfo 타입의 Arguments와 ArgumentList파일 다운로드1
13875정성태1/24/20253140스크립트: 69. 파이썬 - multiprocessing 패키지의 spawn 모드로 동작하는 uvicorn의 workers
13874정성태1/24/20253561스크립트: 68. 파이썬 - multiprocessing Pool의 기본 프로세스 시작 모드(spawn, fork)
13873정성태1/23/20252984디버깅 기술: 217. WinDbg - PCI 장치 열거파일 다운로드1
13872정성태1/23/20252888오류 유형: 944. WinDbg - 원격 커널 디버깅이 연결은 되지만 Break (Ctrl + Break) 키를 눌러도 멈추지 않는 현상
13871정성태1/22/20253296Windows: 278. Windows - 윈도우를 다른 모니터 화면으로 이동시키는 단축키 (Window + Shift + 화살표)
13870정성태1/18/20253736개발 환경 구성: 741. WinDbg - 네트워크 커널 디버깅이 가능한 NIC 카드 지원 확대
13869정성태1/18/20253460개발 환경 구성: 740. WinDbg - _NT_SYMBOL_PATH 환경 변수에 설정한 경로로 심벌 파일을 다운로드하지 않는 경우
13868정성태1/17/20253114Windows: 277. Hyper-V - Windows 11 VM의 Enhanced Session 모드로 로그인을 할 수 없는 문제
1  [2]  3  4  5  6  7  8  9  10  11  12  13  14  15  ...