These days, I am working on a crash dump from an escalation.
0:012> kb
ChildEBP RetAddr Args to Child
04ceb7a0 7c827d0b 77e61d1e 00000530 00000000 ntdll!KiFastSystemCallRet
04ceb7a4 77e61d1e 00000530 00000000 04ceb7e8 ntdll!NtWaitForSingleObject+0xc
04ceb814 77e61c8d 00000530 00004e20 00000000 kernel32!WaitForSingleObjectEx+0xac
04ceb828 7a0c0a43 00000530 00004e20 284e61d1 kernel32!WaitForSingleObject+0x12
04ceb858 7a0c0e89 00000530 00004e20 284e649d mscorwks!ClrWaitForSingleObject+0x24
04cebd14 7a0c2bfd 000005f8 00000530 000005f0 mscorwks!RunWatson+0x1df
04cec458 7a0c3171 04cec7a8 00000001 001edd38 mscorwks!DoFaultReportWorker+0xb62
04cec494 7a106b2d 04cec7a8 00000001 04cec7a8 mscorwks!DoFaultReport+0xc3
04cec4bc 7a10a89a 001edd38 04cec7a8 00000001 mscorwks!WatsonLastChance+0x43
04cec514 7a10a9ae 04cec780 7c35f0c3 04cec7a8 mscorwks!SaveIPFilter+0x1b5
04cec51c 7c35f0c3 04cec7a8 77ecb7c0 77e761b7 mscorwks!InternalUnhandledExceptionFilter+0x22
04cec528 77e761b7 04cec7a8 00000000 00000000 msvcr71!__CxxUnhandledExceptionFilter+0x46
04cec780 77e792a3 04cec7a8 77e61ac1 04cec7b0 kernel32!UnhandledExceptionFilter+0x12a
04cec788 77e61ac1 04cec7b0 00000000 04cec7b0 kernel32!BaseThreadStart+0x4a
04cec7b0 7c828752 04cec894 04ceffdc 04cec8b0 kernel32!_except_handler3+0x61
04cec7d4 7c828723 04cec894 04ceffdc 04cec8b0 ntdll!ExecuteHandler2+0x26
04cec87c 7c82855e 04ce6000 04cec8b0 04cec894 ntdll!ExecuteHandler+0x24
04cec87c 7c82bcd4 04ce6000 04cec8b0 04cec894 ntdll!KiUserExceptionDispatcher+0xe
04cecd98 78134d83 00620000 00000000 00000f5c ntdll!RtlAllocateHeap+0xa2a
04cecdb8 78160e30 00000f5c 00000001 035334f4 msvcr80!malloc+0x7a
The stack trace indicates that an unhandled exception has caused Dr. Watson to generate the user dump. Since kernel32!UnhandledExceptionFilter appears in the stack trace, we can use the method introduced in http://support.microsoft.com/kb/313109 to find out the exception record and switch to the context when the exception was thrown.
0:012> dt EXCEPTION_POINTERS 04cec7a8
msvcr71!EXCEPTION_POINTERS
+0x000 ExceptionRecord : 0x04cec894 _EXCEPTION_RECORD
+0x004 ContextRecord : 0x04cec8b0 _CONTEXT
0:012> .exr 0x04cec894
ExceptionAddress: 7c82bcd4 (ntdll!RtlAllocateHeap+0x00000a2a)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: fffffff8
Attempt to read from address fffffff8
0:012> .cxr 0x04cec8b0
eax=fffffff8 ebx=00000090 ecx=00000000 edx=04190e70 esi=00620178 edi=035455e0
eip=7c82bcd4 esp=04cecb7c ebp=04cecd98 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
ntdll!RtlAllocateHeap+0xa2a:
7c82bcd4 663b18 cmp bx,word ptr [eax] ds:0023:fffffff8=????
0:012> kb
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr Args to Child
04cecd98 78134d83 00620000 00000000 00000f5c ntdll!RtlAllocateHeap+0xa2a
04cecdb8 78160e30 00000f5c 00000001 035334f4 msvcr80!malloc+0x7a
Unable to load image C:\Program Files\Ipswitch\Common\ftplogwriter.dll, Win32 error 0n2
*** WARNING: Unable to verify timestamp for ftplogwriter.dll
04cecdd0 030b6d6f 00000f5c 29549f5d 035334f0 msvcr80!operator new+0x1d
04cece2c 79e77fd5 79e80171 04cecec8 00000000 ftplogwriter!IFTPLogWriter_Impl::LogArray+0x9f [d:\fts\ftplogwriter\src\ftplogwriter_impl.cpp @ 184]
04cece68 79e8025f 79e80277 284e1699 00000000 mscorwks!HelperMethodFrame_1OBJ::HelperMethodFrame_1OBJ+0x14
04cecfec 79f08df5 04ced190 0465dc30 00000000 mscorwks!ObjectNative::GetHashCode+0x13a
04ced0f8 79e84b26 04ced190 04ced76c 04ced140 mscorwks!COMPlusUnwindCallback+0x7c3
04ced10c 79e84962 04ced190 79f07d64 04ced76c mscorwks!Thread::MakeStackwalkerCallback+0x15
79e73940 79e730fb 79e79318 79e74034 79f0ce08 mscorwks!Thread::StackWalkFramesEx+0x396
79e73958 79e730fb 79f0ce29 79e754a8 79e730fc mscorwks!Exception::`vftable'+0x2b
7a08959d 75c08510 58026a04 e9c88bc3 fff310de mscorwks!Exception::`vftable'+0x2b
WARNING: Frame IP not in any known module. Following frames may be wrong.
7a0895a1 58026a04 e9c88bc3 fff310de 0424448b 0x75c08510
7a0895a5 e9c88bc3 fff310de 0424448b c13bc933 0x58026a04
7a0895a9 fff310de 0424448b c13bc933 08890274 0xe9c88bc3
7a0895ad 0424448b c13bc933 08890274 0824448b 0xfff310de
7a0895b1 c13bc933 08890274 0824448b 0274c13b 0x424448b
7a0895b5 08890274 0824448b 0274c13b 448b0889 0xc13bc933
7a0895b9 0824448b 0274c13b 448b0889 c13b0c24 0x8890274
7a0895bd 0274c13b 448b0889 c13b0c24 08890274 0x824448b
7a0895c1 448b0889 c13b0c24 08890274 8b000cc2 0x274c13b
So it is an access violation due to heap corruption. Obviously, the crash happened when the code tried to dereference the address pointed to by EAX. The address pointed to by EAX is quite interesting -- fffffff8.
0:012> .formats fffffff8
Evaluate expression:
Hex: fffffff8
Decimal: -8
Octal: 37777777770
Binary: 11111111 11111111 11111111 11111000
Chars: ....
Time: ***** Invalid
Float: low -1.#QNAN high 0
Double: 2.122e-314
The address is -8! The next question is how EAX gets that invalid address.
0:012>uf ntdll!RtlAllocateHeap
...
ntdll!RtlAllocateHeap+0xa05:
7c82bcb3 0fb7c3 movzx eax,bx
7c82bcb6 50 push eax
7c82bcb7 ff75e4 push dword ptr [ebp-1Ch]
7c82bcba e8fefeffff call ntdll!RtlpFindEntry (7c82bbbd)
ntdll!RtlAllocateHeap+0xa15:
7c82bcbf 8bc8 mov ecx,eax
ntdll!RtlAllocateHeap+0xa17:
7c82bcc1 898d70ffffff mov dword ptr [ebp-90h],ecx
7c82bcc7 3bf1 cmp esi,ecx
7c82bcc9 7412 je ntdll!RtlAllocateHeap+0xa33 (7c82bcdd)
ntdll!RtlAllocateHeap+0xa21:
7c82bccb 8d41f8 lea eax,[ecx-8]
7c82bcce 8985d4feffff mov dword ptr [ebp-12Ch],eax
7c82bcd4 663b18 cmp bx,word ptr [eax]
7c82bcd7 0f87de4f0000 ja ntdll!RtlAllocateHeap+0xa2f (7c830cbb)
...
From the unassembled function, it seems that EAX stores the return value from ntdll!RtlpFindEntry. Then it moves the value to ECX. Later, EAX = ECX - 8. Since EAX is -8, so ECX is 0, and thereby EAX is 0 and ntdll!RtlpFindEntry might return NULL for some reason. However, the code seems to assume ntdll!RtlpFindEntry will return some valid address.
Software Anti-Narrative
10 hours ago
0 comments:
Post a Comment