omega_red
April 29th, 2007, 06:46
I shall be known as "Dances-with-Exceptions" after I finish the code I'm writing.. 
Anyway. I don't know if this has been written about (if it was, I'd appreciate pointers
, at least I didn't find anything about the subject. The whole topic started after I discovered that my code (32bit) was running fine on 32bit OS, but crashed on 64bit OS. Took me about half a day to figure this out.
There is a subtle yet very important difference in 'RaiseException'-type APIs between 32-bit OS and 64bit OS running 32-bit code in WOW. Namely, RaiseException and RtlRaiseException on 64bit capture much less data from CONTEXT of calling thread than their 32bit counterparts. It's especially important if you want to play with debug registers (what I was doing) - you can't modify DRs in exception handler called by RaiseException on 64bit OS, since debug registers are not captured in the context. The only way is causing 'native' exception by means of int3, ud2, access violation etc. On 32-bit OS, 'native' exceptions work exactly as Raise Exception - both capture full context of faulting thread.
POC code attached (fasm format).

Anyway. I don't know if this has been written about (if it was, I'd appreciate pointers

There is a subtle yet very important difference in 'RaiseException'-type APIs between 32-bit OS and 64bit OS running 32-bit code in WOW. Namely, RaiseException and RtlRaiseException on 64bit capture much less data from CONTEXT of calling thread than their 32bit counterparts. It's especially important if you want to play with debug registers (what I was doing) - you can't modify DRs in exception handler called by RaiseException on 64bit OS, since debug registers are not captured in the context. The only way is causing 'native' exception by means of int3, ud2, access violation etc. On 32-bit OS, 'native' exceptions work exactly as Raise Exception - both capture full context of faulting thread.
POC code attached (fasm format).