debugging longman dictionary
Laurent Pinchart
laurent.pinchart at skynet.be
Tue Mar 19 16:41:19 CST 2002
On Monday 18 March 2002 22:58, Eric Pouech wrote:
> > - it also tries to read/write to the debug registers. this produces an
> > unhandled exception. should be trivial to write an exception handler to
> > support that (right ?)
>
> how does it do the writing exactly ? (I'd suspect more the program wants
> to catch itself a watchpoint)
Here's the C code I wrote from the disassembler output. It might not be
correct, and might not even compile, but the idea is there.
BOOL ReadWriteDR2 (DWORD command, DWORD * value)
{
struct {
WORD limit;
DWORD * base;
} idtr;
void *int0Handler;
DWORD int0handlerHigh;
DWORD int0handlerLow;
DWORD valDR2;
BOOL writeDR2;
if ( value == 0 )
return FALSE;
if ( command == 0x1010 )
{
writeDR2 = FALSE;
}
else if ( command == 0x1011 )
{
writeDR2 = TRUE;
valDR2 = *value;
}
else
return FALSE;
idtr = reg.IDTR;
int0Handler = idtr.base[4] & 0xffff0000;
int0Handler |= idtr.base[0];
int0handlerLow = ((DWORD*)int0Handler)[0];
int0handlerHigh = ((DWORD*)int0Handler)[1];
/* Install the division by 0 handler:
pop %eax
pop %eax
push %cs
push %ebx
iret
*/
((DWORD*)int0Handler)[0] = 0x530e5858;
((DWORD*)int0Handler)[1] = 0x000000cf;
asm ( " movl %%ebx, (%0) " : "=m"(return_label1) );
asm ( " xorl %%eax, %%eax; div %%eax, %%eax " );
return_label1:
if ( writeDR2 )
{
reg.DR2 = valDR2;
}
else
{
valDR2 = reg.dr2;
}
idtr = reg.IDTR;
int0Handler = idtr.base[4] & 0xffff0000;
int0Handler |= idtr.base[0];
/* Install the division by 0 handler:
pop %eax
pop %eax
push %cs
push %ebx
iret
*/
((DWORD*)int0Handler)[0] = 0x53515858;
((DWORD*)int0Handler)[1] = 0x000000cf;
asm ( " xorl %%ecx, %%ecx; movw %%ecx, %%cs " );
asm ( " movl %%ebx, (%0) " : "=m"(return_label2) );
asm ( " xorl %%eax, %%eax; div %%eax, %%eax " );
return_label2:
((DWORD*)int0Handler)[0] = int0handlerLow;
((DWORD*)int0Handler)[1] = int0handlerHigh;
if ( ! writeDR2 )
*value = valDR2;
return TRUE;
}
The only call to the ReadWriteDR2 function I found in the disassembler output
is a read call, and the DR2 value is compared with 0xffb31146. Hope this
helps.
> > bool detect_debugger_from_TIB
> > {
> > char *pTIB;
> > asm ( "mov %%fs:0x18, %", "=g"(pTIB) );
> > if ( pTIB[0x20] == 0 )
> > return FALSE;
> > else
> > return TRUE;
> > }
>
> fs:0x18 points in memory to the TEB structure
> and offset 0x20 (from thread.h) says:
> 20 Process id (win95: debug context)
> so I assume you run it on Win9x, and got it tested this way
> (I wouldn't be surprised that under nt it did test dword 0x64 and/or
> 0x68)
You're right, that function is for Win9x. I haven't disassembled the NT
function but I can do if needed.
Where can I find some doc about how the fs and gs registers are used ?
Laurent Pinchart
More information about the wine-devel
mailing list