On the AMD 64bit machine, I enabled the Nx feature by set
“NoExecute=OptOut”, then I wrote a test application which did the simple
stack overflow, as soon as this test application is running, a DEP error
dialog will pops up and it was successfully detected. Everything works
perfect in this case. What I’m interested is how does this implemented
internally? I found actually the Nx hardware will raise an exception from
kernel (0xc0000005), this exception will be passed to the test application’s
SEH list, if not handled, default handler will launch the perfmon.exe and
show the “DEP” dialog on the desktop.
So who raised this exception in kernel and how this was done? I guess it
might be from the page fault hander somewhere but can not prove it. Also I
have tried to monitor the “RtlRaiseException()” and “KiRaiseException()” in
debugger, no one was called. How the kernel exception was generated and
transferred to the user mode? I knew it might be something under the hood,
but it helps to understand how the system works.
Page fault exceptions are handled by the page fault handler;
MmAccessFault (the memory manager code for handling page faults - called
from the machine specific page fault handler) actually specifies when it
returns if an exception should be raised as a result of the page fault.
The exception is directly handled in the page fault trap handler.
Regards,
Tony
Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc. http://www.osr.com
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of AFei
Sent: Monday, February 07, 2005 8:18 PM
To: ntdev redirect
Subject: [ntdev] How does kernel raise the exception?
Hi All,
On the AMD 64bit machine, I enabled the Nx feature by set
“NoExecute=OptOut”, then I wrote a test application which did the simple
stack overflow, as soon as this test application is running, a DEP error
dialog will pops up and it was successfully detected. Everything works
perfect in this case. What I’m interested is how does this implemented
internally? I found actually the Nx hardware will raise an exception
from
kernel (0xc0000005), this exception will be passed to the test
application’s
SEH list, if not handled, default handler will launch the perfmon.exe
and
show the “DEP” dialog on the desktop.
So who raised this exception in kernel and how this was done? I guess it
might be from the page fault hander somewhere but can not prove it. Also
I
have tried to monitor the “RtlRaiseException()” and “KiRaiseException()”
in
debugger, no one was called. How the kernel exception was generated and
transferred to the user mode? I knew it might be something under the
hood,
but it helps to understand how the system works.
I’m not sure how the kernel signals the exception to the user-app, but the
exception is caused due to a page-fault, just like if you access a page
that isn’t available. NX works through detecting that the access is “for
execution”, and generates a page-fault trap (0x0E). The page fault handler
then looks at the faulting address (in CR2 if I remember right) to identify
what caused the problem. If the page isn’t available, it pages it in (if it
should be available), and if it wasn’t supposed to be available for this
type of access, it signals an exception to the application. It doesn’t
really make any difference if the fault is caused by accessing an invalid
memory location or if it’s caused by trying to execute at an address that
has NX set, you should see the same exception either way (but the kernel
will tell that it’s a NX error, so that the exception handler can handle it
differently than say an invalid access to memory).
May I ask what you’re trying to solve by analyzing how this works?
On the AMD 64bit machine, I enabled the Nx feature by set
“NoExecute=OptOut”, then I wrote a test application which did the simple
stack overflow, as soon as this test application is running, a DEP error
dialog will pops up and it was successfully detected. Everything works
perfect in this case. What I’m interested is how does this implemented
internally? I found actually the Nx hardware will raise an exception from
kernel (0xc0000005), this exception will be passed to the test
application’s
SEH list, if not handled, default handler will launch the perfmon.exe and
show the “DEP” dialog on the desktop.
So who raised this exception in kernel and how this was done? I guess it
might be from the page fault hander somewhere but can not prove it. Also
I
have tried to monitor the “RtlRaiseException()” and “KiRaiseException()”
in
debugger, no one was called. How the kernel exception was generated and
transferred to the user mode? I knew it might be something under the
hood,
but it helps to understand how the system works.
Well, it’s from the page fault trap, at least I’m on the right track.
yes, the fault address is from CR2, the Nx bit decides the execute checking.
One strange thing I found is, sometime it will bypass the stack execution
even this Nx bit was set to 1, following is an example is you are
interested:
Sample application: MS Visual Studio.NET running on WinXP SP2 32bit, when
launching this app, it will run a piece of code from stack, on my machine
it’s: address: 0x0013f5dc pte: 0xc00009f8 *pte: 800000001cef1067
You can see the Nx bit was set but there’s no exception for this
application.With my test application, the exception will be raised. And,
another interesting thing is, if I put a WinDBG breakpoint in page fault
hander, it changes the behavior,
the kernel raised the exception for .NET as well! (breakpoint changed the
paging memory?..)
So I’m afraid there’s a “hole” or “backdoor” in kernel? it allow some
applications doing the overflow like .NET, but blocked my test application.
It confused me. Maybe I was wrong, maybe there’re something I didn’t know
yet, leave a question
mark in brain is painful, help if you want.
> So who raised this exception in kernel and how this was done? I guess it
AMD64 has the “no-execute” PTE bit. Trying to execute this page causes the CPU
hardware to make a trap. Then the kernel converts the trap to access violation
exception.
In your case, RtlDispatchException is executed in user mode, it is the function
which calls the frame block handlers and does the unwind.
The kernel (I think) just patches the EIP in the trap frame to point to
KiUserExceptionDispatcher and returns.
Just verified, the kernel will call KiDispatchException(), it will change
the EIP in
tap frame as you said, then it returned to the user mode
UserExceptionDispatcher()
(This name maybe wrong) directly.
Refer to my last post, for some reason, some applications won’t raise the
exception
when running codes in stack (exp: vs.net), kernel must know how to decide
this, I’m
still digging on this.
thanks.
“Maxim S. Shatskih” wrote in message news:xxxxx@ntdev… > > So who raised this exception in kernel and how this was done? I guess it > > AMD64 has the “no-execute” PTE bit. Trying to execute this page causes the CPU > hardware to make a trap. Then the kernel converts the trap to access violation > exception. > > In your case, RtlDispatchException is executed in user mode, it is the function > which calls the frame block handlers and does the unwind. > > The kernel (I think) just patches the EIP in the trap frame to point to > KiUserExceptionDispatcher and returns. > > Maxim Shatskih, Windows DDK MVP > StorageCraft Corporation > xxxxx@storagecraft.com > http://www.storagecraft.com > >