I downloaded (shudder) Microsoft's windbg program
(http://www.microsoft.com/ddk/debugging/installx86beta.asp) and ran it
for the app under Win2000/VMWare.
It also shows an exception at the same access! However, windbg displays
the exception and then allows the user to continue the program, letting
whatever exception handler the program installed handle the exception.
And the program does install an exception handler.
After I stepped it past that exception, it started accessing memory
starting from 0x401000 in steps of multiples of 0x1000, each access
throwing an exception, until it hit the last exception at 0x757000, and
then then program ran normally. Probably no coincidence, since the next
writable segment starts at 0x759000.
So apparently the program is designed to throw the exceptions.
Just before the call to VirtualProtect:
0806d398:Call kernel32.SetUnhandledExceptionFilter(0075f447) ret=0075f0cb
0806d398:Ret kernel32.SetUnhandledExceptionFilter() retval=00000000
ret=0075f0cb
This function is this:
0075F447 sub_75F447 proc near
0075F447 call sub_75F047
0075F44C xor eax, eax
0075F44E retn 4
0075F44E sub_75F447 endp
eax is set to 0 on exit, which is EXCEPTION_CONTINUE_SEARCH, which means
to proceed with the UnhandledExceptionFilter Windows function, which
should either display an Application Error message, or return to the
application if SetErrorMode says so.
So what's with this trace?
0806d398:trace:seh:EXC_CallHandler calling handler at 0x761b10
code=c0000005 flags=0
It looks like we're calling 0x761B10, not 0x75F447. Why?
It also looks like EXC_CallHandler is called from EXC_RtlRaiseException,
which is called from do_segv, which is called from a signal handler for
SIGSEGV.
Why does do_segv call EXC_RtlRaiseException, and not
UnhandledExceptionFilter? Where did EXC_CallHandler get that 0x761B10
address from?
--Rob