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