<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx</link><description>Hi NTDebuggers, I have another puzzler for you. We started crash2.exe under windbg and it crashed. Go figure! Sometimes we have a very limited amount of data available to figure out what went wrong. That being said, this week’s puzzler only gives you</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8394913</link><pubDate>Tue, 15 Apr 2008 00:49:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8394913</guid><dc:creator>C++ Guy</dc:creator><description>&lt;P&gt;Great puzzle!&lt;/P&gt;
&lt;P&gt;I'll take a guess: somebody called atexit() and passed in a function pointer that's implemented in a DLL. &amp;nbsp;But that DLL has been unloaded when _onexit() gets called.&lt;/P&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8396015</link><pubDate>Tue, 15 Apr 2008 05:05:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8396015</guid><dc:creator>molotov</dc:creator><description>&lt;p&gt;Looks like crash2.exe is a 32-bit app running on x64 Vista+. &amp;nbsp;EBP and EIP appear trashed; I'd suspect some kind of buffer overrun.&lt;/p&gt;
&lt;p&gt;&amp;quot;e if our stack is larger enough This is more data for us&amp;quot;&lt;/p&gt;
&lt;p&gt;I guess one thing I'd do is check the output of db esp...&lt;/p&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8396291</link><pubDate>Tue, 15 Apr 2008 06:33:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8396291</guid><dc:creator>Doug</dc:creator><description>&lt;P&gt;Nice stack overflow. &amp;nbsp;The ascii char are a dead give away.&lt;/P&gt;
&lt;P&gt;"if our stack is larger enough This is more data for us"&lt;/P&gt;
&lt;P&gt;I somewhat don't understand the "problem". &amp;nbsp;Is it that it crashes or is it that it crashes under Windbg?&lt;/P&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8396430</link><pubDate>Tue, 15 Apr 2008 07:28:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8396430</guid><dc:creator>MSDNTST</dc:creator><description>&lt;P&gt;This looks like the stack corruption to me. &lt;/P&gt;
&lt;P&gt;The ebp has quite different value as esp register(their difference should be less than 1M):&lt;/P&gt;
&lt;P&gt;esp=0017ff00 ebp=6f207473 &lt;/P&gt;
&lt;P&gt;The further "db" command confirms that 6f207473 points to invalid address.(Free VA region)&lt;/P&gt;
&lt;P&gt;Since the ebp register is saved on the stack and later popped up from their I assume the garbage value "6f207473" is caused by corruption of "ret value" or "saved ebp value" on the stack. &lt;/P&gt;
&lt;P&gt;Esp value looks ok, since the "dps esp" output makes sense. &lt;/P&gt;
&lt;P&gt;The Access Violation is caused by "eip=65732074" which also points to the invalid VA region. This is expected because "ebp" value is corrupted, which provides incorrect offset return value for "eip". &lt;/P&gt;
&lt;P&gt;Finally, to verify it, we can turn-on the /GS compiler option in the VS2003/2005/2008.&lt;/P&gt;
&lt;P&gt;Jeffrey Tan&lt;/P&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8397032</link><pubDate>Tue, 15 Apr 2008 11:43:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8397032</guid><dc:creator>Tal Rosen</dc:creator><description>&lt;P&gt;dds output looks very 'ASCII'&lt;/P&gt;
&lt;P&gt;let start with&lt;/P&gt;
&lt;P&gt;0:020&amp;gt; da esp&lt;/P&gt;
&lt;P&gt;xxxxxxxxxx &amp;nbsp;"fi eruo ats i kal sregro@."&lt;/P&gt;
&lt;P&gt;Well, it a buffer overflow corrupting our stack.&lt;/P&gt;
&lt;P&gt;since ecx=0042ecc8 (near out module code)&lt;/P&gt;
&lt;P&gt;maybe this will give us a hint of the last call? &amp;nbsp;&lt;/P&gt;
&lt;P&gt;how about: ln 0042ecc8&lt;/P&gt;
&lt;P&gt;?????????&lt;/P&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8397627</link><pubDate>Tue, 15 Apr 2008 17:18:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8397627</guid><dc:creator>Matthieu</dc:creator><description>&lt;p&gt;eip=65732074 esp=0017ff00 ebp=6f207473&lt;/p&gt;
&lt;p&gt;0017fefc 66692065 0x65732074&lt;/p&gt;
&lt;p&gt;It means EIP value is from [ESP]&lt;/p&gt;
&lt;p&gt;EBP is also erased. Then the overflow is probably caused by something like&lt;/p&gt;
&lt;p&gt;pop ebp&lt;/p&gt;
&lt;p&gt;retn XXXX&lt;/p&gt;
&lt;p&gt;Then, retn opcode gives a bad return address to EIP. I guess the problem is to locate which function causes the buffer overflow right&lt;/p&gt;
&lt;p&gt;ChildEBP RetAddr &lt;/p&gt;
&lt;p&gt;WARNING: Frame IP not in any known module. Following frames may be wrong.&lt;/p&gt;
&lt;p&gt;0017fefc 66692065 0x65732074&lt;/p&gt;
&lt;p&gt;0017ff3c 0041b9a3 0x66692065&lt;/p&gt;
&lt;p&gt;Is it possible to know the value at offset 0017ff044?&lt;/p&gt;
&lt;p&gt;(Hypothesis-1)&lt;/p&gt;
&lt;p&gt;There is a common dword between to string it looks like buffer from 0017FEFC is copied to 0017FF40.&lt;/p&gt;
&lt;p&gt;It can be verified if dword at 0x17FF44 is equal to 0x65732074.&lt;/p&gt;
&lt;p&gt;Debug dump also give the following information.&lt;/p&gt;
&lt;p&gt;0017ff3c &amp;nbsp;fffffffe&lt;/p&gt;
&lt;p&gt;0017ff40 &amp;nbsp;0041b9a3 crash2!_onexit+0x35&lt;/p&gt;
&lt;p&gt;0017ff44 &amp;nbsp;0041b9c2 crash2!atexit+0x9&lt;/p&gt;
&lt;p&gt;Then, pointer to atexit()+0x9 offset may have been modified. It means when the program tried to return to atexit()+0x9 it returns to 0x65732074.&lt;/p&gt;
&lt;p&gt;atexit offset = 0041b9c2-0x9&lt;/p&gt;
&lt;p&gt;A call usualy is coded on 5 bytes, like 0xE8 then let's disassemble the code at 0x0041B9C2 - 0x5 (0x41B9BD)&lt;/p&gt;
&lt;p&gt;In the dump we can see:&lt;/p&gt;
&lt;p&gt;0041B9BD : e8 42 5c ff ff&lt;/p&gt;
&lt;p&gt;Destination is : 0x41B9C2 + 0xFFFF5C42 = 0x0411604&lt;/p&gt;
&lt;p&gt;If my logical is right the vulnerable function to the overflow is located at 0x0411604, but we don't see information or this address in the dump.&lt;/p&gt;
&lt;p&gt;This answer depends if hypothesis-1 is right or not.&lt;/p&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8397724</link><pubDate>Tue, 15 Apr 2008 18:12:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8397724</guid><dc:creator>Skywing</dc:creator><description>&lt;p&gt;I would concur that it's a stack overrun, probably in either a global/static class destructor, or an explicitly registered atexit handler.&lt;/p&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8398535</link><pubDate>Wed, 16 Apr 2008 05:31:48 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8398535</guid><dc:creator>Mark Steward</dc:creator><description>&lt;p&gt;dds crash2!__onexitbegin&lt;/p&gt;
&lt;p&gt;dds crash2!__onexitend&lt;/p&gt;
&lt;p&gt;Ta&lt;/p&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8398629</link><pubDate>Wed, 16 Apr 2008 07:54:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8398629</guid><dc:creator>RichardRudek</dc:creator><description>&lt;p&gt;My guess is that you've got a global function like described on the VC Blog, and that global is cause a stack overrun.&lt;/p&gt;
&lt;p&gt;Basically, during _cinit() it goes through these, one by one:&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt; &amp;nbsp;atexit(_RTC_Terminate);&lt;/p&gt;
&lt;p&gt; &amp;nbsp;_initterm( __xc_a, __xc_z );&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt;It happens after the atexit() call. That's why we see it in the dds esp output.&lt;/p&gt;
&lt;p&gt;Just a guess... :)&lt;/p&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8398630</link><pubDate>Wed, 16 Apr 2008 07:54:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8398630</guid><dc:creator>RichardRudek</dc:creator><description>&lt;P&gt;Oh, the blog entry is &lt;A href="http://blogs.msdn.com/vcblog/archive/2006/10/20/crt-initialization.aspx" target=_new rel=nofollow&gt;http://blogs.msdn.com/vcblog/archive/2006/10/20/crt-initialization.aspx&lt;/A&gt;&lt;/P&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8402226</link><pubDate>Thu, 17 Apr 2008 13:37:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8402226</guid><dc:creator>JM</dc:creator><description>&lt;p&gt;@RichardRudek: I think you're on to something. In fact, what's happening is that the SEH epilog of msvcrt!_onexit (statically linked in this case) is failing due to stack corruption. I'm not experienced enough to know why or how this happens. :-)&lt;/p&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8403316</link><pubDate>Thu, 17 Apr 2008 18:05:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8403316</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;Unfortunately, it looks like the nice idea of providing more data is too hard...&lt;/p&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8405551</link><pubDate>Fri, 18 Apr 2008 04:01:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8405551</guid><dc:creator>Jeffrey Tan</dc:creator><description>&lt;p&gt;Hi JM,&lt;/p&gt;
&lt;p&gt;Is there any clue that this is caused by the SEH overwrite instead of stack overflow for global variable? I am glad to hear the reason :-).&lt;/p&gt;
&lt;p&gt;Anyway, we can turn-on /SafeSEH to give it a shoot.&lt;/p&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8408078</link><pubDate>Fri, 18 Apr 2008 18:35:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8408078</guid><dc:creator>Mark Steward</dc:creator><description>&lt;P&gt;I forgot they're encoded. &amp;nbsp;The quickest way to find the corruption would be to use ba on an address within the SEH frame from _onexit+0xc.&lt;/P&gt;
&lt;P&gt;Jeffrey: the code at 0041b9a3 matches the return from __SEH_epilog4 in _onexit (in the latest non-debug msvcrt). &amp;nbsp;So it's while clearing up the SEH that exposes the problem, but that doesn't mean it *is* the problem.&lt;/P&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8408345</link><pubDate>Fri, 18 Apr 2008 19:50:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8408345</guid><dc:creator>Mark Steward</dc:creator><description>&lt;P&gt;Ahh. &amp;nbsp;Optimisation bites again. &amp;nbsp;None of the CRTs I can find optimises crash2!_onexit...&lt;/P&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8408943</link><pubDate>Fri, 18 Apr 2008 23:05:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8408943</guid><dc:creator>JM</dc:creator><description>&lt;P&gt;@Jeffrey: Well, I obviously was wrong, but that's because I don't have enough experience decoding debugger output. For example, I did not understand how this:&lt;/P&gt;
&lt;P&gt;0017ffa0 75a919f1 crash2!__tmainCRTStartup+0x15e [f:\sp\vctools\crt_bld\self_x86\crt\src\crt0.c @ 327]&lt;/P&gt;
&lt;P&gt;0017ffac 7782d109 kernel32!BaseThreadInitThunk+0xe&lt;/P&gt;
&lt;P&gt;0017ffec 00000000 ntdll!_RtlUserThreadStart+0x23&lt;/P&gt;
&lt;P&gt;Turns into this on the next step:&lt;/P&gt;
&lt;P&gt;0017ffa0 75a919f1 crash2!_onexit+0x35 [f:\sp\vctools\crt_bld\self_x86\crt\src\onexit.c @ 98]&lt;/P&gt;
&lt;P&gt;0017ffac 7782d109 kernel32!BaseThreadInitThunk+0xe&lt;/P&gt;
&lt;P&gt;0017ffec 00000000 ntdll!_RtlUserThreadStart+0x23&lt;/P&gt;
&lt;P&gt;I thought the symbol indicated the symbol associated with the return address ("75a919f1") which I could have known was not the case from the initial start ("00000000" is certainly not ntdll!_RtlUserThreadStart+0x23). So ignore me, I'm an idiot.&lt;/P&gt;
&lt;P&gt;(The SEH overwrite was based on disassembling my copy of _onexit(), which is executing the SEH epilog around +0x35).&lt;/P&gt;</description></item><item><title>re: Debug puzzler 0x00000002 “Attack of the crazy stack”</title><link>http://blogs.msdn.com/ntdebugging/archive/2008/04/14/debug-puzzler-0x00000002-attack-of-the-crazy-stack.aspx#8409416</link><pubDate>Sat, 19 Apr 2008 03:19:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8409416</guid><dc:creator>Mark Steward</dc:creator><description>&lt;P&gt;Ignore everything I said this morning - this puzzle is a brilliant example of why you can't make assumptions when debugging!&lt;/P&gt;
&lt;P&gt;JM: the current line (the symbol) is the return address from the line above. &amp;nbsp;Windbg sees 0041b9a3 on the stack, and assumes that's the return address. &amp;nbsp;It therefore doesn't find wmain's frame at 0017ff50, which is obvious when you check it manually.&lt;/P&gt;
&lt;P&gt;The reason it's on the stack is that _cinit previously called atexit(_RTC_Terminate), which uses SEH to do a check on the stack on termination. &amp;nbsp;But these aren't valid frames - they just haven't been overwritten yet, because wmain has allocated 40 bytes of unused local stack space.&lt;/P&gt;
&lt;P&gt;Unfortunately, onexit's name confused everyone except RichardRudek: onexit is not called while exiting! &amp;nbsp;As soon as you know that, the problem is just "stack overflow".&lt;/P&gt;
&lt;P&gt;If debugging outside a blog, I'd always check the most reliable-looking frame by doing ub 00412ac4 l1, which would show it had called wmain, not _cinit.&lt;/P&gt;
&lt;P&gt;P.S. If you actually build this program, you need /GS- to avoid getting a STATUS_STACK_BUFFER_OVERRUN exception!&lt;/P&gt;</description></item></channel></rss>