ntdll: Fix SIGTRAP handling
Petr Tesarik
hat at tesarici.cz
Mon Mar 27 09:15:47 CST 2006
Dne 03/27/06 v 16:49:13 (+0200), Alexandre Julliard napsal(a):
> Petr Tesarik <hat at tesarici.cz> writes:
>
> > In my opinion, the solution is reasonable because if any application
> > is really interested in the DR6 register (i.e. it is a debugger), it
> > will clear the status register (DR6) anyway, since the processor never
> > clears the bits and unless you clear them manually, the register gets
> > pretty useless.
>
> There are applications other than debuggers that care about debug
> registers, notably copy protection code. We can't afford to do things
> differently even if they sound reasonable.
I'm afraid I can't understand you. At first, you're advocating the
wrong test for the TF bit by the fact that it's 99.9 % correct and
then you're criticizing clearing DR6 which is also 99.9 % correct.
Not enough on that, I've provided a patch already which is 100 %
correct on most platforms and only 99.9 % correct on the remaining
ones.
If you talk about copy protection schemes, I've seen code like this
(while debugging self, of course):
pushf
pop %eax
orl $0x100,%eax
push %eax
popf
; some code
pushf
pop %eax
andl ~$0x100,%eax
push %eax
popf
Now, native Windows will generate EXCEPTION_SINGLE_STEP after the last
popf. In Wine you'll get a SIGTRAP (possibly with get_trap_code() ==
TRAP_x86_TRCTRAP, if TRAP_sig is defined for the platform). This will
check the TF bit in context->EFlags. Since this is not set, it will
fetch the debug registers and check the lowest 4 bits. These will be
zero, so Wine generates an EXCEPTION_BREAKPOINT.
I've already explained in another email that it's not possible to get
the correct behavior in any other way than the way I've proposed.
Petr Tesarik
More information about the wine-devel
mailing list