原帖地址:http://eparg.spaces.live.com/blog/cns!59BFC22C0E7E1A76!1208.entry
LONG WINAPI UnhandledExceptionFilter1(
struct _EXCEPTION_POINTERS* ExceptionInfo
)
{
MessageBox(0,"fdsa",0,0);
return 0;
}
int main(int, char*)
{
SetUnhandledExceptionFilter(UnhandledExceptionFilter1);
char *p=0;
*p=0;
return 0;
}
When running above code without debugger attached, the MessgeBox shows fine. However, when I attach windbg, the UnhandledExceptionFilter1 is not called any more. The behavior is by design and described in MSDN:
However, my customer uses self defined UnhandleExceptionHandler1 to do some jobs, and the function contains some bug. We need to debug the UnhandleExceptionHandler1 in windbg but as above test, the function is never called if windbg attached.
I tried to change peb+2 to 0 to cheat the IsDebuggerPresent API. However it does not help.
Is there any way to allow us to debug the UnhandleExceptionHandler1 function?
======
Thanks Kwan Hyun Kim for providing the following superexcellent solution:
1. put a bp on kernel32!UnhandledExceptionFilter
0:000> bl
0 e 00411410 0001 (0001) 0:**** uef!wmain
1 e 004113be 0001 (0001) 0:**** uef!UnhandledExceptionFilter1+0x1e
2 e 77e9951c 0001 (0001) 0:**** kernel32!UnhandledExceptionFilter
2. debugger sees the first exception and run “g”
0:000> g
(a24.a08): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=7ffde000 ecx=0012fe58 edx=7c82ed54 esi=0012fe90 edi=0012ff68
eip=0041144c esp=0012fe90 ebp=0012ff68 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
uef!wmain+0x3c:
0041144c c60000 mov byte ptr [eax],0 ds:0023:00000000=??
3. breakpoint 2 hit on kernel32!UnhandledExceptionFilter
0:000> g
Breakpoint 2 hit
eax=0012fa9c ebx=00000000 ecx=10310980 edx=00000000 esi=00000000 edi=00000000
eip=77e9951c esp=0012fa2c ebp=0012fa4c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
kernel32!UnhandledExceptionFilter:
77e9951c 6830020000 push 230h
4. run “g” to till you see a call to NtQueryInformationProcess (UnhandledExceptionFilter calls this function to see the process has a valid value in DebugPort field of EPROCESS)
0:000> g 77e995cf
eax=ffffffff ebx=00000004 ecx=77e98e31 edx=7c82ed54 esi=0012fa9c edi=00000000
eip=77e995cf esp=0012f7c8 ebp=0012fa28 iopl=0 nv up ei ng nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000286
kernel32!UnhandledExceptionFilter+0x84:
77e995cf ff15b810e477 call dword ptr [kernel32!_imp__NtQueryInformationProcess (77e410b8)] ds:0023:77e410b8={ntdll!ZwQueryInformationProcess (7c821998)}
5. run “p” command to step over a call to NtQueryInformationProcess
0:000> p
eax=00000000 ebx=00000004 ecx=0012f7c0 edx=7c82ed54 esi=0012fa9c edi=00000000
eip=77e995d5 esp=0012f7dc ebp=0012fa28 iopl=0 nv up ei ng nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000286
kernel32!UnhandledExceptionFilter+0x8a:
77e995d5 85c0 test eax,eax
6. eax has the return value, and change it into 0x80000000 <<< this is the trick
0:000> r eax=80000000
7. run “g” and your unhandledexceptionhandler will be called.
0:000> g
Breakpoint 1 hit
eax=cccccccc ebx=00000004 ecx=00000000 edx=7c82ed54 esi=0012fa9c edi=0012f7d0
eip=004113be esp=0012f704 ebp=0012f7d0 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
uef!UnhandledExceptionFilter1+0x1e:
004113be 8bf4 mov esi,esp