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

비밀번호

댓글 작성자
 




... 121  122  123  124  125  126  127  128  129  130  [131]  132  133  134  135  ...
NoWriterDateCnt.TitleFile(s)
1781정성태10/21/201420607디버깅 기술: 64. new/delete의 짝이 맞는 경우에도 메모리 누수가 발생한다면?
1780정성태10/15/201424257오류 유형: 249. The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID
1779정성태10/15/201419773오류 유형: 248. Active Directory에서 OU가 지워지지 않는 경우
1778정성태10/10/201418240오류 유형: 247. The Netlogon service could not create server share C:\Windows\SYSVOL\sysvol\[도메인명]\SCRIPTS.
1777정성태10/10/201421343오류 유형: 246. The processing of Group Policy failed. Windows attempted to read the file \\[도메인]\sysvol\[도메인]\Policies\{...GUID...}\gpt.ini
1776정성태10/10/201418353오류 유형: 245. 이벤트 로그 - Name resolution for the name _ldap._tcp.dc._msdcs.[도메인명]. timed out after none of the configured DNS servers responded.
1775정성태10/9/201419471오류 유형: 244. Visual Studio 디버깅 (2) - Unable to break execution. This process is not currently executing the type of code that you selected to debug.
1774정성태10/9/201426662개발 환경 구성: 246. IIS 작업자 프로세스의 20분 자동 재생(Recycle)을 끄는 방법
1773정성태10/8/201429836.NET Framework: 471. 웹 브라우저로 다운로드가 되는 파일을 왜 C# 코드로 하면 안되는 걸까요? [1]
1772정성태10/3/201418620.NET Framework: 470. C# 3.0의 기본 인자(default parameter)가 .NET 1.1/2.0에서도 실행될까? [3]
1771정성태10/2/201428125개발 환경 구성: 245. 실행된 프로세스(EXE)의 명령행 인자를 확인하고 싶다면 - Sysmon [4]
1770정성태10/2/201421720개발 환경 구성: 244. 매크로 정의를 이용해 파일 하나로 C++과 C#에서 공유하는 방법 [1]파일 다운로드1
1769정성태10/1/201424144개발 환경 구성: 243. Scala 개발 환경 구성(JVM, 닷넷) [1]
1768정성태10/1/201419561개발 환경 구성: 242. 배치 파일에서 Thread.Sleep 효과를 주는 방법 [5]
1767정성태10/1/201424697VS.NET IDE: 94. Visual Studio 2012/2013에서의 매크로 구현 - Visual Commander [2]
1766정성태10/1/201422530개발 환경 구성: 241. 책 "프로그래밍 클로저: Lisp"을 읽고 나서. [1]
1765정성태9/30/201426073.NET Framework: 469. Unity3d에서 transform을 변수에 할당해 사용하는 특별한 이유가 있을까요?
1764정성태9/30/201422316오류 유형: 243. 파일 삭제가 안 되는 경우 - The action can't be comleted because the file is open in System
1763정성태9/30/201423884.NET Framework: 468. PDB 파일을 연동해 소스 코드 라인 정보를 알아내는 방법파일 다운로드1
1762정성태9/30/201424578.NET Framework: 467. 닷넷에서 EIP/RIP 레지스터 값을 구하는 방법 [1]파일 다운로드1
1761정성태9/29/201421652.NET Framework: 466. 윈도우 운영체제의 보안 그룹 이름 및 설명 문자열을 바꾸는 방법파일 다운로드1
1760정성태9/28/201419915.NET Framework: 465. ICorProfilerInfo::GetILToNativeMapping 메서드가 0x80131358을 반환하는 경우
1759정성태9/27/201431037개발 환경 구성: 240. Visual C++ / x64 환경에서 inline-assembly를 매크로 어셈블리로 대체하는 방법파일 다운로드1
1758정성태9/23/201437920개발 환경 구성: 239. 원격 데스크톱 접속(RDP)을 기존의 콘솔 모드처럼 사용하는 방법 [1]
1757정성태9/23/201418495오류 유형: 242. Lync로 모임 참여 시 소리만 들리지 않는 경우 - 두 번째 이야기
1756정성태9/23/201427486기타: 48. NVidia 제품의 과다한 디스크 사용 [2]
... 121  122  123  124  125  126  127  128  129  130  [131]  132  133  134  135  ...