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)
13729정성태9/9/20248899C/C++: 173. Windows / C++ - AllocConsole로 할당한 콘솔과 CRT 함수 연동 [1]파일 다운로드1
13728정성태9/7/20248518C/C++: 172. Windows - C 런타임에서 STARTUPINFO의 cbReserved2, lpReserved2 멤버를 사용하는 이유파일 다운로드1
13727정성태9/6/20249190개발 환경 구성: 722. ARM 플랫폼 빌드를 위한 미니 PC(?) - Khadas VIM4 [1]
13726정성태9/5/20248230C/C++: 171. C/C++ - 윈도우 운영체제에서의 file descriptor와 HANDLE파일 다운로드1
13725정성태9/4/20246826디버깅 기술: 201. WinDbg - sos threads 명령어 실행 시 "Failed to request ThreadStore"
13724정성태9/3/20249674닷넷: 2296. Win32/C# - 자식 프로세스로 HANDLE 상속파일 다운로드1
13723정성태9/2/20249067C/C++: 170. Windows - STARTUPINFO의 cbReserved2, lpReserved2 멤버 사용자 정의파일 다운로드2
13722정성태9/2/20246904C/C++: 169. C/C++ - CRT(C Runtime) 함수에 의존성이 없는 프로젝트 생성
13721정성태8/30/20246694C/C++: 168. Visual C++ CRT(C Runtime DLL: msvcr...dll)에 대한 의존성 제거 - 두 번째 이야기
13720정성태8/29/20247059VS.NET IDE: 193. C# - Visual Studio의 자식 프로세스 디버깅
13719정성태8/28/20247087Linux: 79. C++ - pthread_mutexattr_destroy가 없다면 메모리 누수가 발생할까요?
13718정성태8/27/20248953오류 유형: 921. Visual C++ - error C1083: Cannot open include file: 'float.h': No such file or directory [2]
13717정성태8/26/20248533VS.NET IDE: 192. Visual Studio 2022 - Windows XP / 2003용 C/C++ 프로젝트 빌드
13716정성태8/21/20247681C/C++: 167. Visual C++ - 윈도우 환경에서 _execv 동작 [1]
13715정성태8/19/20248859Linux: 78. 리눅스 C/C++ - 특정 버전의 glibc 빌드 (docker-glibc-builder)
13714정성태8/19/20247453닷넷: 2295. C# 12 - 기본 생성자(Primary constructors) (책 오타 수정) [3]
13713정성태8/16/20248993개발 환경 구성: 721. WSL 2에서의 Hyper-V Socket 연동
13712정성태8/14/20248289개발 환경 구성: 720. Synology NAS - docker 원격 제어를 위한 TCP 바인딩 추가
13711정성태8/13/20248777Linux: 77. C# / Linux - zombie process (defunct process) [1]파일 다운로드1
13710정성태8/8/20249363닷넷: 2294. C# 13 - (6) iterator 또는 비동기 메서드에서 ref와 unsafe 사용을 부분적으로 허용파일 다운로드1
13709정성태8/7/20248693닷넷: 2293. C# - safe/unsafe 문맥에 대한 C# 13의 (하위 호환을 깨는) 변화파일 다운로드1
13708정성태8/7/20248934개발 환경 구성: 719. ffmpeg / YoutubeExplode - mp4 동영상 파일로부터 Audio 파일 추출
13707정성태8/6/20248908닷넷: 2292. C# - 자식 프로세스의 출력이 4,096보다 많은 경우 Process.WaitForExit 호출 시 hang 현상파일 다운로드1
13706정성태8/5/20248666개발 환경 구성: 718. Hyper-V - 리눅스 VM에 새로운 디스크 추가
13705정성태8/4/20248897닷넷: 2291. C# 13 - (5) params 인자 타입으로 컬렉션 허용 [2]파일 다운로드1
13704정성태8/2/20249613닷넷: 2290. C# - 간이 dotnet-dump 프로그램 만들기파일 다운로드1
1  2  3  4  5  6  7  8  9  [10]  11  12  13  14  15  ...