http://bugs.winehq.org/show_bug.cgi?id=10467
--- Comment #10 from Anastasius Focht focht@gmx.net 2007-11-18 16:23:55 --- Hello,
--- quote --- I'm not sure why you quoting something that's available by scrolling up. But just in case you need it, you can find it blow. --- quote ---
I quote the way I like it. Sometimes its better to respond/comment to _specific_ parts of posts than to quote everything or nothing.
--- quote --- You didn't read it right. And you did not search the commit log for _WHY_ Wine does not use guard page. You really should and also look at all the mentioned bugs. --- quote ---
Well I searched and found this last commit:
http://www.winehq.org/pipermail/wine-cvs/2005-December/019888.html
"ntdll: Don't use a real guard page at the bottom of the stack. A no-access page is enough, we can't properly raise an overflow exception anyway."
But I didn't found a discussion related to that message that explains "is enough" and "can't properly raise stack overflow exception".
--- quote MSDN --- If a thread in an application causes an EXCEPTION_STACK_OVERFLOW exception, the thread has left its stack in a damaged state.
When this maximum stack size is exceeded, the system does the following three things: * Removes the PAGE_GUARD protection on the guard page, as previously described. * Tries to allocate a new guard page below the last one. However, this fails because the maximum stack size has been exceeded. * Raises an exception so that the thread can handle it in the exception block. ... Note that, at that point, the stack no longer has a guard page. The next time that the program grows the stack all the way to the end, where there should be a guard page, the program writes beyond the end of the stack and causes an access violation. --- quote MSDN ---
So why not having both? Two-layered page guard for thread stacks:
NtProtectVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size, PAGE_NOACCESS, NULL ); NtProtectVirtualMemory( NtCurrentProcess(), &teb->Tib.StackLimit, &size, PAGE_GUARD, NULL );
-- stack bottom -- PAGE_NO_ACCESS -> raise access violation / die PAGE_GUARD -> "last chance", raise EXCEPTION_STACK_OVERFLOW (and reset the guard if necessary) .. PAGE_READ_WRITE/EXECUTE whatever -> normal stack pages .. current callstack -- stack top --
When the PAGE_GUARD page is touched, remove the PAGE_GUARD flag *and* raise EXCEPTION_STACK_OVERFLOW. This gives the executing thread the chance to actually do something within "last chance" 4K page limit, cleanup, error reporting whatever. If the app structured exception handler - which catches EXCEPTION_STACK_OVERFLOW - tries to touch/walk the stack further, then the PAGE_NO_ACCESS comes into play (causing nested exception). This could be the access violation exception described in MSDN (quote). With this mechanism wine doesn't need to implement dynamically grown PAGE_GUARD stack and pleases applications that expect a PAGE_GUARD flagged page (like .NET) and some sort of EXCEPTION_STACK_OVERFLOW. Better than dying in very last NO_ACCESS page without telling the real cause: stack overflow.
-- quote --- I'm telling you that stuff like starforce and securerom _WILL_ crash if you don't grow stack on guard page access. It HAVE TO be gown, or it HAVE TO BE no access page as it is now. Your hack is just that - a hack. It can not be used as is without implementing stack growth. -- quote ---
Show me the code/disassembly snippet of Securom illustrating NO_ACCESS vs. PAGE_GUARD problem at stack bottom. I reversed various copy prot stuff and the stack wipe is NOT an issue there (even retested the bottom PAGE_GUARD patch for v6 and v7 just in case).
Besides this a common technique to prevent debuggers getting a good callstack if the target protector code smells something fishy. All "on purpose" stack wipes I have encountered in various PE protections didn't started from/reached stack bottom at all. Usually a fixed amount of stack pages are cleared from current_esp-n*page_size to stack top. Current to-the-top callstack is what matters.
And StarForce ... aren't you the one who tells people "StarForce won't ever work"? So who cares then?
Regards