http://www.microsoft.com/mspress/books/12069.aspx
Inside Windows 2000 부터 계속 애독하고 있지만 정말 좋은책입니다.
5 Edition 빨리 나왔으면 좋겠내요 ㅜ.ㅜ
- 디버깅의 마술사 !! 제라툴의 블로그
http://www.microsoft.com/mspress/books/12069.aspx
Inside Windows 2000 부터 계속 애독하고 있지만 정말 좋은책입니다.
5 Edition 빨리 나왔으면 좋겠내요 ㅜ.ㅜ
아래 내용의 덤프는 솔직히 현재 GG 상태 이지만 … 그래도 분석 했던 과정을 몇자 적습니다.(잘못된 분석일 수 있음)
. 0 Id: 6a4.1cc Suspend: 1 Teb: 7ffdf000 Unfrozen
# ChildEBP RetAddr Args to Child
00 0012da50 7c93e9c0 7c8025cb 00000350 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
01 0012da54 7c8025cb 00000350 00000000 00000000 ntdll!ZwWaitForSingleObject+0xc (FPO: [3,0,0])
02 0012dab8 7c802532 00000350 ffffffff 00000000 kernel32!WaitForSingleObjectEx+0xa8 (FPO: [Non-Fpo])
03 0012dacc 769b4d8d 00000350 ffffffff 0012dbc8 kernel32!WaitForSingleObject+0×12 (FPO: [Non-Fpo])
04 0012db04 769915c0 00000001 0012dbc8 0012dbb4 ole32!CRWLock::AcquireReaderLock+0×120 (FPO: [Non-Fpo])
05 0012db40 76991524 00000001 0012dbc8 0012db7c ole32!CClassCache::GetClassObjectActivator+0×47 (FPO: [Non-Fpo])
06 0012db70 7698f9e9 0012dbc8 0012db54 02f5e8e0 ole32!CClassCache::SearchForLoadedClass+0×4a (FPO: [Non-Fpo])
07 0012dc54 7698faba 00557564 00000000 00000017 ole32!ICoCreateInstanceEx+0×15a (FPO: [Non-Fpo])
08 0012dc7c 7698fa89 00557564 00000000 00000017 ole32!CComActivator::DoCreateInstance+0×28 (FPO: [Non-Fpo])
09 0012dca0 7698faf7 00557564 00000000 00000017 ole32!CoCreateInstanceEx+0×1e (FPO: [Non-Fpo])
0a 0012dcd0 004f9ab4 00557564 00000000 00000017 ole32!CoCreateInstance+0×37 (FPO: [Non-Fpo])
…
Application Hang 상황에서 위와 같은 스택을 만난다면 굉장히 당황할 수 있습니다. 특히나 OLE 32와 같은 경우 거의 대부분의 내용이 Undocument 되어 있기때문에 사실상 Reversing 이외에는 방법이 없지요. WaitForSingleObject와 함께 발생하는 Application Hang이라면 WaitForSingleObject가 실행될 조건을 판단해 보는것이 분석에 꽤나 도움이 됩니다. ( 저 역시도 GG 입니다. )
ole32!CRWLock::AcquireReaderLock:
7698fc39 8bff mov edi,edi
7698fc3b 55 push ebp
7698fc3c 8bec mov ebp,esp
7698fc3e 83ec1c sub esp,1Ch
7698fc41 a16461a976 mov eax,dword ptr [ole32!gdwDefaultTimeout (76a96164)]
7698fc46 57 push edi
7698fc47 8bf9 mov edi,ecx
7698fc49 f6471801 test byte ptr [edi+18h],1
7698fc4d 897df0 mov dword ptr [ebp-10h],edi
7698fc50 8945e4 mov dword ptr [ebp-1Ch],eax
7698fc53 0f8458020700 je ole32!CRWLock::AcquireReaderLock+0×1c (769ffeb1)ole32!CRWLock::AcquireReaderLock+0x20:
7698fc59 ff1580129776 call dword ptr [ole32!_imp__GetCurrentThreadId (76971280)]
7698fc5f 394710 cmp dword ptr [edi+10h],eax
7698fc62 0f8452020700 je ole32!CRWLock::AcquireReaderLock+0×2b (769ffeba)
…일단 edi+10h와 GetCurrentThreadId를 비교하는 것으로 보아 edi+10h ( edi에는 ole32!CClassCache::_mxs 의 값이 있지요 ) 는 어떤 Thread의 ID가 있는 것으로 추정됩니다. 하지만 실제로 그 Thread는 존재하지 않습니다. ( 가장 아쉬운 부분 )
0:000> dd 76a96068+0x10
76a96078 00000794 00000178 00010001 00000001
76a96088 00000003 7697d2cc 00000000 00000000
76a96098 00000000 00000000 00000043 00000001
76a960a8 00000002 00000000 76a12cfb 7698cf29
76a960b8 7698cf29 76a12fcc 76a1304a 76a1313f
76a960c8 76a131e6 76a1326b 76a132f1 00000000
76a960d8 00000000 00000000 00000000 00000001
76a960e8 00000000 00000000 7697d7c0 00000021
0:000> ~*
. 0 Id: 6a4.1cc Suspend: 1 Teb: 7ffdf000 Unfrozen
Priority: 0 Priority class: 32
1 Id: 6a4.a7c Suspend: 1 Teb: 7ffdb000 Unfrozen
Priority: 0 Priority class: 32
2 Id: 6a4.d1c Suspend: 1 Teb: 7ffda000 Unfrozen
Priority: 0 Priority class: 32
3 Id: 6a4.d94 Suspend: 1 Teb: 7ffd9000 Unfrozen
Priority: 0 Priority class: 32
4 Id: 6a4.fd0 Suspend: 1 Teb: 7ffd8000 Unfrozen
Priority: 0 Priority class: 32
5 Id: 6a4.3d8 Suspend: 1 Teb: 7ffd7000 Unfrozen
Priority: 0 Priority class: 32
6 Id: 6a4.a58 Suspend: 1 Teb: 7ffd6000 Unfrozen
Priority: 0 Priority class: 32
7 Id: 6a4.6b8 Suspend: 1 Teb: 7ffd4000 Unfrozen
Priority: 0 Priority class: 32
8 Id: 6a4.f78 Suspend: 1 Teb: 7ffd3000 Unfrozen
Priority: 0 Priority class: 32
9 Id: 6a4.fc0 Suspend: 1 Teb: 7ff9f000 Unfrozen
Priority: 0 Priority class: 32
# 10 Id: 6a4.85c Suspend: 1 Teb: 7ffde000 Unfrozen
Priority: 0 Priority class: 32
이 Thread가 존재했다면 좀더 정확한 원인을 찾았을꺼라 생각이되는데 …
ole32!CRWLock::AcquireReaderLock+0x3a:
7698fc68 8b07 mov eax,dword ptr [edi]
7698fc6a 53 push ebx
7698fc6b 56 push esi
7698fc6c 8d4de8 lea ecx,[ebp-18h]
7698fc6f 51 push ecx
7698fc70 8bcf mov ecx,edi
7698fc72 ff5008 call dword ptr [eax+8] // GetTLSLockData
7698fc75 85c0 test eax,eax
7698fc77 8945fc mov dword ptr [ebp-4],eax
7698fc7a 0f8cae510200 jl ole32!CRWLock::AcquireReaderLock+0×256 (769b4e2e)ole32!CRWLock::AcquireReaderLock+0x52:
7698fc80 8b4de8 mov ecx,dword ptr [ebp-18h]
7698fc83 33c0 xor eax,eax
7698fc85 668b01 mov ax,word ptr [ecx]
7698fc88 6685c0 test ax,ax
7698fc8b 0f8538020700 jne ole32!CRWLock::AcquireReaderLock+0×5f (769ffec9)ole32!CRWLock::AcquireReaderLock+0x68:
7698fc91 8365fc00 and dword ptr [ebp-4],0
7698fc95 8365f400 and dword ptr [ebp-0Ch],0
7698fc99 8b770c mov esi,dword ptr [edi+0Ch]
ole32!CRWLock::AcquireReaderLock+0×73: <==
7698fc9c b8ff030000 mov eax,3FFh
7698fca1 3bf0 cmp esi,eax
7698fca3 8975ec mov dword ptr [ebp-14h],esi
7698fca6 0f83ba4f0200 jae ole32!CRWLock::AcquireReaderLock+0×83 (769b4c66)
0:000> dd 76a96068+0×0C
76a96074 00803000 00000794 00000178 00010001
76a96084 00000001 00000003 7697d2cc 00000000
76a96094 00000000 00000000 00000000 00000043
76a960a4 00000001 00000002 00000000 76a12cfb
76a960b4 7698cf29 7698cf29 76a12fcc 76a1304a
76a960c4 76a1313f 76a131e6 76a1326b 76a132f1
76a960d4 00000000 00000000 00000000 00000000
76a960e4 00000001 00000000 00000000 7697d7c0
WaitSingle Object를 타기위해서는 위에 있는 769b4c66 으로 Jump를 해야합니다. 그런 조건이라면 esi 의 값이 0×3FFh 의 값보다 컷어야 한다는 것이지요 .. 0×3FF와 비교 해야하는 값에 의미를 파악하지 할 수 있다면 더없이 좋을것으로 일단 생각 됩니다.
ole32!CRWLock::AcquireReaderLock+0x1f9:
7698fcac 56 push esi
7698fcad 46 inc esi
7698fcae 56 push esi
7698fcaf 8d470c lea eax,[edi+0Ch]
7698fcb2 50 push eax
7698fcb3 ff1540129776 call dword ptr [ole32!_imp__InterlockedCompareExchange (76971240)]
7698fcb9 8bf0 mov esi,eax
7698fcbb 3b75ec cmp esi,dword ptr [ebp-14h]ole32!CRWLock::AcquireReaderLock+0x20b:
7698fcbe 0f85f04f0200 jne ole32!CRWLock::AcquireReaderLock+0x20d (769b4cb4)ole32!CRWLock::AcquireReaderLock+0x27f:
7698fcc4 837dfc00 cmp dword ptr [ebp-4],0
7698fcc8 0f8c60510200 jl ole32!CRWLock::AcquireReaderLock+0×256 (769b4e2e)
ole32!CRWLock::AcquireReaderLock+0×285:
7698fcce 8b45e8 mov eax,dword ptr [ebp-18h]
7698fcd1 66c7000100 mov word ptr [eax],1
ole32!CRWLock::AcquireReaderLock+0×277:
7698fcd6 5e pop esi
7698fcd7 5b pop ebx
ole32!CRWLock::AcquireReaderLock+0×279:
7698fcd8 8b45fc mov eax,dword ptr [ebp-4]
7698fcdb 5f pop edi
7698fcdc c9 leave
7698fcdd c3 ret
ole32!CRWLock::AcquireReaderLock+0×83:
769b4c66 b900040000 mov ecx,400h
769b4c6b 85f1 test ecx,esi
769b4c6d 0f8591010000 jne ole32!CRWLock::AcquireReaderLock+0×8c (769b4e04)
ole32!CRWLock::AcquireReaderLock+0xad:
769b4c73 8bd6 mov edx,esi
769b4c75 23d0 and edx,eax
769b4c77 3bd0 cmp edx,eax
769b4c79 0f84ddb20400 je ole32!CRWLock::AcquireReaderLock+0×1e5 (769fff5c)
ole32!CRWLock::AcquireReaderLock+0xb9:
769b4c7f b800e07f00 mov eax,7FE000h
769b4c84 8bd6 mov edx,esi
769b4c86 23d0 and edx,eax
769b4c88 3bd0 cmp edx,eax
769b4c8a 0f84ccb20400 je ole32!CRWLock::AcquireReaderLock+0×1e5 (769fff5c)
ole32!CRWLock::AcquireReaderLock+0xca:
769b4c90 8bc6 mov eax,esi
769b4c92 25000c0000 and eax,0C00h
769b4c97 3bc1 cmp eax,ecx
769b4c99 0f84bdb20400 je ole32!CRWLock::AcquireReaderLock+0×1e5 (769fff5c)
ole32!CRWLock::AcquireReaderLock+0xd9: <==
769b4c9f ff45f4 inc dword ptr [ebp-0Ch]
769b4ca2 8b45f4 mov eax,dword ptr [ebp-0Ch]
769b4ca5 3b05bc64a976 cmp eax,dword ptr [ole32!gdwDefaultSpinCounu t (76a964bc)]
769b4cab 0f87a3000000 ja ole32!CRWLock::AcquireReaderLock+0xeb (769b4d54)
ole32!CRWLock::AcquireReaderLock+0×1f4:
769b4cb1 8b770c mov esi,dword ptr [edi+0Ch]
ole32!CRWLock::AcquireReaderLock+0×20d:
769b4cb4 817dfc1f010180 cmp dword ptr [ebp-4],8001011Fh
769b4cbb 0f84afb20400 je ole32!CRWLock::AcquireReaderLock+0×216 (769fff70)
ole32!CRWLock::AcquireReaderLock+0×24c:
769b4cc1 837dfc00 cmp dword ptr [ebp-4],0
769b4cc5 0f8dd1affdff jge ole32!CRWLock::AcquireReaderLock+0×73 (7698fc9c)
ole32!CRWLock::AcquireReaderLock+0×256:
769b4ccb e95e010000 jmp ole32!CRWLock::AcquireReaderLock+0×256 (769b4e2e)
ole32!CRWLock::AcquireReaderLock+0xeb:
769b4d54 56 push esi
769b4d55 81c600200000 add esi,2000h
769b4d5b 56 push esi
769b4d5c 8d470c lea eax,[edi+0Ch]
769b4d5f 50 push eax
769b4d60 ff1540129776 call dword ptr [ole32!_imp__InterlockedCompareExchange (76971240)]
769b4d66 8bf0 mov esi,eax
769b4d68 3b75ec cmp esi,dword ptr [ebp-14h]
769b4d6b 0f8543ffffff jne ole32!CRWLock::AcquireReaderLock+0×20d (769b4cb4)
ole32!CRWLock::AcquireReaderLock+0×108:
769b4d71 8bcf mov ecx,edi
769b4d73 e8bdffffff call ole32!CRWLock::GetReaderEvent (769b4d35)
769b4d78 85c0 test eax,eax
769b4d7a 8945f8 mov dword ptr [ebp-8],eax
769b4d7d 0f844fb10400 je ole32!CRWLock::AcquireReaderLock+0×124 (769ffed2)
ole32!CRWLock::AcquireReaderLock+0×116:
769b4d83 ff75e4 push dword ptr [ebp-1Ch]
769b4d86 50 push eax
769b4d87 ff15b8129776 call dword ptr [ole32!_imp__WaitForSingleObject (769712b8)]
769b4d8d 8bd8 mov ebx,eax
ole32!CRWLock::AcquireReaderLock+0xd9지점을 거져서 Default Time Out Count를 가지고 WaitForSingleObject를 호출하게 되죠 .. 그렇다면 왜 hang이 걸려 있나 ?? 일단 확인 가능한 정보로는 Default Time Out Count 의 값이 INFINITE라는 점, 그리고 알 수 없는 Thread의 ID 있다는 점을 미루어 보면 그 알 수 없는 Thread ID를 가지는 Thread에서 SetEvent를 해줄 것 같다는 불길한 생각이 듭니다. 그럼 그 Thread는 과연 어디로 살아진것일까 ???
정말 궁금합니다.. 재현이 안되니 아쉬움도 많이 남는 ㅜ.ㅜ 흑흑….
이 덤프 분석 가능하다 ==> 리플 고고싱
이 덤프 예전에 봤었다 ==> 리플 고고싱
이 덤프 원인은 모르지만 해결가능하다 ==> 리플 고고싱
EFlag Register 상에 TF Flag 도 Disable 되어 있고 DR6에 BS Flag도 역시 Disable 되어 있는데 이상하게 Single Step Exception이 발생하는 현상이 있어 관련 부분을 뒤지다 잼있는것을 찾았습니다.
Intel Manual 상에도 없는 Undocument Instruction이 있더군요.
download : opcodes.zip
상당히 재미있는 Instruction도 있군요 ㅋ
IRQL_NOT_LESS_OR_EQUAL (a)
Arg1: fffffff0, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: 8040df56, address which referenced memory
be0d9bfc 8040ec83 87fb8908 00000000 00000000 nt!CcAcquireByteRangeForWrite+0×390
be0d9cd4 8040e626 87f3a0f4 00000000 00000001 nt!CcFlushCache+0×2c7
be0d9d0c 80412efa 890518e8 80476800 836ddb60 nt!CcWriteBehind+0×124
be0d9d78 80416fad 890518e8 00000000 00000000 nt!CcWorkerThread+0×158
be0d9da8 804551f6 890518e8 00000000 00000000 nt!ExpWorkerThread+0xaf
be0d9ddc 8046a512 80416efe 80000000 00000000 nt!PspSystemThreadStartup+0×54
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0×16
BSOD가 발생했을때 위와 같은 스택을 만나게 된다면 MS Hotfix를 요청하시길 바랍니다..( Windows XP의 경우 Offset이 조금 다름 ) CcAcquireByteRangeForWrite Function 내에서 SharedCacheMap ( First Parameter) 를 Access 하다 발생하는 문제더군요. Windows 2000에서만 발생하는게 아니라 알고 보니 XP에도 여전히 발생하고있습니다. 혹시나 이것으로 인해 삽질하고 계시다면 아래 사이트를 확인해 보시길 ..
http://support.microsoft.com/kb/892045
덤프를 지금 가지고 있어 … 이 정도만 .. ㅜ.ㅜ

http://www.pyrasis.com/blog/entry/PublicationWindowsProjectEssentialUtility
http://kangcom.com/common/bookinfo/bookinfo.asp?sku=200805280006
재홍군의 책이 드디어 출간됐습니다.
내용 정말 좋습니다. 실무에 적용하고 있는 내용이기도 하고요.
최근 답글