Dmitriy, I played with Kernel debugger a little bit especially looked
PageFault interrupt handler. I'm using Vista x64. I remember I did it
long time ago with Win XP and seems Microsoft has changed the code
since then.
There is function called KiCheckForSListAddress for checking if the
pagefault occurred inside InterlockedPopEntrySList.
KiCheckForSListAddress is checking if the fault address is between
KiInterlockedPopEntrySListResumeEntryPoint and
KiInterlockedPopEntrySListEndEntryPoint. It that's true return address
of KeUserPopEntrySListResume. I couldn't find the code that limited
time of retries. (I'll look it further if I have some more time later)
The way they handling this pagefault is very low level (Kernel's
pagefault IDT function) I thought it's not quite same as SEH since
it's not a user mode try/catch thing but probably Dmitriy and me are
talking same thing differently.)
More important thing is, as Neill mentioned, user more exception
handler has an issue like if freed memory reused as stack guard page
which is pretty paranoid though.
0: kd> u
nt!KiPageFault+0x231:
fffff800`02478171 8945a0 mov dword ptr [rbp-60h],eax
fffff800`02478174 7509 jne nt!KiPageFault+0x23f
(fffff800`0247817f)
fffff800`02478176 b901000000 mov ecx,1
fffff800`0247817b 440f22c1 mov cr8,rcx
fffff800`0247817f 488d4d80 lea rcx,[rbp-80h]
fffff800`02478183 e878600000 call nt!KiCheckForSListAddress
(fffff800`0247e200) <==
fffff800`02478188 8b4da0 mov ecx,dword ptr [rbp-60h]
fffff800`0247818b 0bc9 or ecx,ecx
fffff800`0242a888 mov rax,qword ptr [nt!
KeUserPopEntrySListResumeWow64 (fffff800`02646460)]
fffff800`0242a88f jmp nt!KiCheckForSListAddress+0x3c
(fffff800`0247e23c)
0: kd> uf nt!KiCheckForSListAddress
fffff800`0247e200 movzx eax,word ptr [rcx+170h]
fffff800`0247e207 mov rdx,qword ptr [rcx+168h]
fffff800`0247e20e cmp ax,33h
fffff800`0247e212 je nt!KiCheckForSListAddress+0x44
(fffff800`0247e244)
nt!KiCheckForSListAddress+0x14:
fffff800`0247e214 cmp ax,23h
fffff800`0247e218 je nt!KiCheckForSListAddress+0x65
(fffff800`0247e265)
nt!KiCheckForSListAddress+0x1a:
fffff800`0247e21a cmp rdx,qword ptr [nt!
KiInterlockedPopEntrySListResumeEntryPoint (fffff800`02646458)]
fffff800`0247e221 ja nt!KiCheckForSListAddress+0x26
(fffff800`0247e226)
nt!KiCheckForSListAddress+0x23:
fffff800`0247e223 ret 0
nt!KiCheckForSListAddress+0x26:
fffff800`0247e226 cmp rdx,qword ptr [nt!
KiInterlockedPopEntrySListEndEntryPoint (fffff800`02646860)]
fffff800`0247e22d ja nt!KiCheckForSListAddress+0x23
(fffff800`0247e223)
nt!KiCheckForSListAddress+0x2f:
fffff800`0247e22f cmp ax,10h
fffff800`0247e233 jne nt!KiCheckForSListAddress+0x23
(fffff800`0247e223)
nt!KiCheckForSListAddress+0x35:
fffff800`0247e235 mov rax,qword ptr [nt!
KiInterlockedPopEntrySListResumeEntryPoint (fffff800`02646458)]
nt!KiCheckForSListAddress+0x3c:
fffff800`0247e23c mov qword ptr [rcx+168h],rax
fffff800`0247e243 ret