Crash Dump Analysis Patterns (Part 12)
Crash Dump Analysis Patterns (Part 12)
번역: Heejune Kim (https://insidekernel.net , drost@naver.com)
번역일: 2007-11-13
크래쉬 덤프에서 자주 발생하는 다른 패턴은 컴포넌트 심볼 없음(No Component Symbols) 패턴입니다. 이 경우에 컴포넌트가 어떤 일을 하는가는 그것의 이름이나, 호출된 전체 스레드 스택, import table들을 살펴보면서 추측할 수 있습니다. 예를 하나 들어봅시다. 커널 덤프에서 어떤 스레드 스택에 component.sys 드라이버가 보이지만, 그 컴포넌트가 잠재적으로 무엇을 할 수 있을지에 대해서는 모릅니다. 우리는 심볼을 가지고 있지 않기 때문에, 그것의 import된 함수들 또한 볼 수 없습니다:
kd> x component!*
kd>
그것의 image header를 덤프하기 위해서 !dh 명령어를 사용해봅시다:
kd> lmv m component
start end module name
fffffadf`e0eb5000 fffffadf`e0ebc000 component (no symbols)
Loaded symbol image file: component.sys
Image path: \??\C:\Component\x64\component.sys
Image name: component.sys
Timestamp: Sat Jul 01 19:06:16 2006 (44A6B998)
CheckSum: 000074EF
ImageSize: 00007000
Translations: 0000.04b0 0000.04e0 0409.04b0 0409.04e0
kd> !dh fffffadf`e0eb5000
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
8664 machine (X64)
6 number of sections
44A6B998 time date stamp Sat Jul 01 19:06:16 2006
0 file pointer to symbol table
0 number of symbols
F0 size of optional header
22 characteristics
Executable
App can handle >2gb addresses
OPTIONAL HEADER VALUES
20B magic #
8.00 linker version
C00 size of code
A00 size of initialized data
0 size of uninitialized data
5100 address of entry point
1000 base of code
----- new -----
0000000000010000 image base
1000 section alignment
200 file alignment
1 subsystem (Native)
5.02 operating system version
5.02 image version
5.02 subsystem version
7000 size of image
400 size of headers
74EF checksum
0000000000040000 size of stack reserve
0000000000001000 size of stack commit
0000000000100000 size of heap reserve
0000000000001000 size of heap commit
0 [ 0] address [size] of Export Directory
51B0 [ 28] address [size] of Import Directory
6000 [ 3B8] address [size] of Resource Directory
4000 [ 6C] address [size] of Exception Directory
0 [ 0] address [size] of Security Directory
0 [ 0] address [size] of Base Relocation Directory
2090 [ 1C] address [size] of Debug Directory
0 [ 0] address [size] of Description Directory
0 [ 0] address [size] of Special Directory
0 [ 0] address [size] of Thread Storage Directory
0 [ 0] address [size] of Load Configuration Directory
0 [ 0] address [size] of Bound Import Directory
2000 [ 88] address [size] of Import Address Table Directory
0 [ 0] address [size] of Delay Import Directory
0 [ 0] address [size] of COR20 Header Directory
0 [ 0] address [size] of Reserved Directory
…
…
…
이제 Import Address Table Directory의 내용을 dps 명령어를 사용해서 볼 수 있습니다:
kd> dps fffffadf`e0eb5000+2000 fffffadf`e0eb5000+2000+88
fffffadf`e0eb7000 fffff800`01044370 nt!IoCompleteRequest
fffffadf`e0eb7008 fffff800`01019700 nt!IoDeleteDevice
fffffadf`e0eb7010 fffff800`012551a0 nt!IoDeleteSymbolicLink
fffffadf`e0eb7018 fffff800`01056a90 nt!MiResolveTransitionFault+0x7c2
fffffadf`e0eb7020 fffff800`0103a380 nt!ObDereferenceObject
fffffadf`e0eb7028 fffff800`0103ace0 nt!KeWaitForSingleObject
fffffadf`e0eb7030 fffff800`0103c570 nt!KeSetTimer
fffffadf`e0eb7038 fffff800`0102d070 nt!IoBuildPartialMdl+0x3
fffffadf`e0eb7040 fffff800`012d4480 nt!PsTerminateSystemThread
fffffadf`e0eb7048 fffff800`01041690 nt!KeBugCheckEx
fffffadf`e0eb7050 fffff800`010381b0 nt!KeInitializeTimer
fffffadf`e0eb7058 fffff800`0103ceb0 nt!ZwClose
fffffadf`e0eb7060 fffff800`012b39f0 nt!ObReferenceObjectByHandle
fffffadf`e0eb7068 fffff800`012b7380 nt!PsCreateSystemThread
fffffadf`e0eb7070 fffff800`01251f90 nt!FsRtlpIsDfsEnabled+0x114
fffffadf`e0eb7078 fffff800`01275160 nt!IoCreateDevice
fffffadf`e0eb7080 00000000`00000000
fffffadf`e0eb7088 00000000`00000000
이 드라이버는 특정한 상황 아래에서 KeBugCheckEx를 사용해서 시스템을 bugcheck할 수 있고, PsCreateSystemThread를 이용해서 시스템 스레드를 만들며, KeInitializeTimer와 KeSetTimer를 이용해서 타이머를 사용한다는 것을 보여줍니다.
만약 여러분이 import table에서 name+offset (OMAP 코드 최적화 때문에 발생했다고 생각됨)을 본다면, 여러분은 ln 명령어(list nearest symbols, 가장 가까운 심볼을 나열하라)를 사용해서 함수를 얻어낼 수 있습니다:
kd> ln fffff800`01056a90
(fffff800`01056760) nt!MiResolveTransitionFault+0x7c2 | (fffff800`01056a92) nt!RtlInitUnicodeString
kd> ln fffff800`01251f90
(fffff800`01251e90) nt!FsRtlpIsDfsEnabled+0×114 | (fffff800`01251f92) nt!IoCreateSymbolicLink
이 테크닉은 드라이버가 특정 함수를 호출할 때마다 bugcheck가 발생하거나, 또는 bugcheck 0x20처럼 특정 함수를 짝으로 반드시 호출할 때 발생하는 bugcheck 상황에서 유용하게 사용할 수 있습니다:
kd> !analyze -show 0x20
KERNEL_APC_PENDING_DURING_EXIT (20)
The key data item is the thread's APC disable count. If this is non-zero, then this is the source of the problem. The APC disable count is decremented each time a driver calls KeEnterCriticalRegion, KeInitializeMutex, or FsRtlEnterFileSystem. The APC disable count is incremented each time a driver calls KeLeaveCriticalRegion, KeReleaseMutex, or FsRtlExitFileSystem. Since these calls should always be in pairs, this value should be zero when a thread exits. A negative value indicates that a driver has disabled APC calls without re-enabling them. A positive value indicates that the reverse is true. If you ever see this error, be very suspicious of all drivers installed on the machine — especially unusual or non-standard drivers. Third party file system redirectors are especially suspicious since they do not generally receive the heavy duty testing that NTFS, FAT, RDR, etc receive. This current IRQL should also be 0. If it is not, that a driver’s cancelation routine can cause this bugcheck by returning at an elevated IRQL. Always attempt to note what you were doing/closing at the time of the crash, and note all of the installed drivers at the time of the crash. This symptom is usually a severe bug in a third party driver.
그러면 여러분은 최소한 의심가는 드라이버가 이런 함수들을 잠재적으로 사용했는지 아닌지를 위 방법을 이용하여 살펴보고 만약 그것들 중의 하나를 import 했다면 그 대응되는 짝이 되는 함수를 import 했는지 아닌지를 살펴볼 수 있을 것입니다.
- Dmitry Vostokov -
Comments
- Anonymous
September 17, 2008
PingBack from http://www.easycoded.com/crash-dump-analysis-patterns-part-12/