

Dmitry Vostokov, 15th June 2009
http://www.dumpanalysis.org
Once we got a process memory dump with a stack overflow pattern[5]. There were hundreds of repeated frames involving exception dispatch:
(d70.111c): Stack overflow - code c00000fd (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=00113354 ebx=00113068 ecx=0011307c edx=7c9485ec esi=001133c8 edi=00000000 eip=7c95153e esp=00112ff4 ebp=00113050 iopl=0 nv up ei pl nz ac po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210212 ntdll!RtlDispatchException+0x8: 7c95153e 56 push esi 0:000> k 1000 ChildEBP RetAddr 00113050 7c94855e ntdll!RtlDispatchException+0x8 00113050 7c978002 ntdll!KiUserExceptionDispatcher+0xe 001133b0 7c94855e ntdll!RtlDispatchException+0xf7 001133b0 7c978002 ntdll!KiUserExceptionDispatcher+0xe 00113710 7c94855e ntdll!RtlDispatchException+0xf7 00113710 7c978002 ntdll!KiUserExceptionDispatcher+0xe 00113a70 7c94855e ntdll!RtlDispatchException+0xf7 00113a70 7c978002 ntdll!KiUserExceptionDispatcher+0xe 00113dd0 7c94855e ntdll!RtlDispatchException+0xf7 00113dd0 7c978002 ntdll!KiUserExceptionDispatcher+0xe 00114130 7c94855e ntdll!RtlDispatchException+0xf7 00114130 7c978002 ntdll!KiUserExceptionDispatcher+0xe 00114490 7c94855e ntdll!RtlDispatchException+0xf7 [...] 0020f830 7c978002 ntdll!KiUserExceptionDispatcher+0xe 0020fb90 7c94863c ntdll!RtlDispatchException+0xf7 0020fe70 7c80bee7 ntdll!RtlRaiseException+0x3d 0020fed0 00058dc9 kernel32!RaiseException+0x53 WARNING: Stack unwind information not available. Following frames may be wrong. 0020ff34 000a7d5a Application+0x48dc9 0020ff54 000a7bf2 Application+0x97d5a 0020ff78 000a7de2 Application+0x97bf2 0020ffc0 7c82f23b Application+0x97de2 0020fff0 00000000 kernel32!BaseProcessStart+0x23
If we look at raw stack we could see repeated hidden exception pattern[6]:
0:000> dds esp
00112ff4 00000000
00112ff8 00000000
00112ffc 00000000
00113000 00000000
00113004 00000000
00113008 00000000
0011300c 00000000
00113010 00000000
00113014 00000000
00113018 00000000
0011301c 00000000
00113020 00000000
00113024 00000000
00113028 00000000
0011302c 00000000
00113030 00000000
00113034 00000000
00113038 00000000
0011303c 00000000
00113040 00000000
00113044 00000000
00113048 00000000
0011304c 00000000
00113050 001133b0
00113054 7c94855e ntdll!KiUserExceptionDispatcher+0xe
00113058 00113068
0011305c 0011307c ; .cxr
00113060 00113068 ; .exr
00113064 0011307c
00113068 c0000025
0011306c 00000001
00113070 001133c8
0:000> .exr 00113068
ExceptionAddress: 7c978002 (ntdll!RtlDispatchException+0x000000f7)
ExceptionCode: c0000025
ExceptionFlags: 00000001
NumberParameters: 0
0:000> !error c0000025
Error code: (NTSTATUS) 0xc0000025 (3221225509) - {EXCEPTION}
Cannot Continue Windows cannot continue from this exception.
Looking closer at RaiseException call we noticed that its second parameter is 1:
0:000> kv 100 ChildEBP RetAddr Args to Child [...] 0020fed0 00058dc9 0eedfade 00000001 00000007 kernel32!RaiseException+0x53 [...]
This function has the following prototype[7]:
void RaiseException( DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const DWORD* lpArguments );
What caught our attention was the fact that dwExceptionFlags paramater can have the value EXCEPTION_NONCONTINUABLE and if we continue to execute the code afterwards another exception is raised:
EXCEPTION_NONCONTINUABLE_EXCEPTION
Therefore, to test our hypothesis that the code of Application module attempted to continue code excution after raising non-continuable exception we created a small C++ application:
#include "stdafx.h"
#include <excpt.h>
#include <windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
__try
{
RaiseException (0xdeaddead, EXCEPTION_NONCONTINUABLE, NULL, NULL);
}
__except (EXCEPTION_CONTINUE_EXECUTION)
{
}
return 0;
}
The application raises a non-continuable exception but SEH exception filter attempts to continue execution. If the second parameter is 0 then the program quietly exits as expected. However if this parameter is set to 1 (EXCEPTION_NONCONTINUABLE) then the program crashes:
We then attached WinDbg non-invasively to SEHTest.exe:
0:000> k ChildEBP RetAddr 00081128 00000000 ntdll!RtlRaiseException+0xa 0:000> r eax=00081140 ebx=0017ff34 ecx=00000000 edx=ffffffd8 esi=000811bc edi=00000000 eip=77052fb2 esp=00080e58 ebp=00081128 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202 ntdll!RtlRaiseException+0xa: 77052fb2 54 push esp
Unfortunately WinDbg was unable to reconstruct stack trace so we did that manually[8]:
0:000> dds ebp 00081128 000811a4 0008112c 77096fb7 ntdll!RtlDispatchException+0x18a 00081130 00081140 00081134 00000000 00081138 000811bc 0008113c 00081560 00081140 c0000025 00081144 00000001 00081148 000811bc 0008114c 00000000 00081150 00000000 00081154 00000000 00081158 00000000 0008115c 00000000 00081160 00000000 00081164 00000000 00081168 00000000 0008116c 00000000 00081170 00000000 00081174 00000000 00081178 00000000 0008117c 00000000 00081180 00000000 00081184 00000000 00081188 00000000 0008118c 00000000 00081190 00000000 00081194 00000000 00081198 00180000 0008119c 00081000 000811a0 00000000 000811a4 00081548 0:000> k L=00081128 00081128 77052fb2 1000 ChildEBP RetAddr 00081128 77096fb7 ntdll!RtlRaiseException+0xa 000811a4 77052eff ntdll!RtlDispatchException+0x18a 000811a4 77096fb7 ntdll!KiUserExceptionDispatcher+0xf 00081548 77052eff ntdll!RtlDispatchException+0x18a 00081548 77096fb7 ntdll!KiUserExceptionDispatcher+0xf 000818ec 77052eff ntdll!RtlDispatchException+0x18a 000818ec 77096fb7 ntdll!KiUserExceptionDispatcher+0xf 00081c90 77052eff ntdll!RtlDispatchException+0x18a 00081c90 77096fb7 ntdll!KiUserExceptionDispatcher+0xf 00082034 77052eff ntdll!RtlDispatchException+0x18a 00082034 77096fb7 ntdll!KiUserExceptionDispatcher+0xf 000823d8 77052eff ntdll!RtlDispatchException+0x18a 000823d8 77096fb7 ntdll!KiUserExceptionDispatcher+0xf 0008277c 77052eff ntdll!RtlDispatchException+0x18a 0008277c 77096fb7 ntdll!KiUserExceptionDispatcher+0xf 00082b20 77052eff ntdll!RtlDispatchException+0x18a 00082b20 77096fb7 ntdll!KiUserExceptionDispatcher+0xf 00082ec4 77052eff ntdll!RtlDispatchException+0x18a 00082ec4 77096fb7 ntdll!KiUserExceptionDispatcher+0xf 00083268 77052eff ntdll!RtlDispatchException+0x18a [...] 0017f7dc 77096fb7 ntdll!KiUserExceptionDispatcher+0xf 0017fb80 77052eff ntdll!RtlDispatchException+0x18a 0017fb80 75b7f328 ntdll!KiUserExceptionDispatcher+0xf 0017ff04 0040104b kernel32!RaiseException+0x58 0017ff44 004011d8 SEHTest!wmain+0x4b 0017ff88 75bde4a5 SEHTest!__tmainCRTStartup+0x10f 0017ff94 770acfed kernel32!BaseThreadInitThunk+0xe 0017ffd4 770ad1ff ntdll!__RtlUserThreadStart+0x23 0017ffec 00000000 ntdll!_RtlUserThreadStart+0x1b 0:000> kv L=00081128 00081128 77052fb2 1000 ChildEBP RetAddr Args to Child [...] 0017ff04 0040104b deaddead 00000001 00000000 kernel32!RaiseException+0x58 (FPO: [4,20,0]) [...]
We can also see the same hidden exception on raw stack: c0000025. Therefore we conclude that we sucessfully modeled the problem.
The SEHTest application and its symbols can be downloaded from:
http://www.dumpanalysis.org/Debugged/Jun09/download/SEHTest.zip
[5] http://www.dumpanalysis.org/blog/index.php/2008/06/10/crash-dump-analysi...
[6] http://www.dumpanalysis.org/blog/index.php/2007/02/02/crash-dump-analysi...
[7] http://msdn.microsoft.com/en-us/library/aa909203.aspx
[8] http://www.dumpanalysis.org/blog/index.php/2007/07/25/reconstructing-sta...