Ejemplo n.º 1
0
/*
 * doStartTask:
 *
 * handle NFY_STARTTASK notification
 *
 * If we are waiting for the debuggee to load, then this is the task.
 * We remember the module and task ID's, and plant a breakpoint at the
 * starting address of the application.  We can do that now, since we
 * now know the code selector for the segment with the start address.
 *
 * Otherwise, we simply record it so that we can notify the debugger
 * about a loaded module later.
 */
static BOOL doStartTask( DWORD data )
{
    char        val;
    TASKENTRY   te;

    te.dwSize = sizeof( te );
    TaskFindHandle( &te, TaskAtNotify );

    if( DebuggerState == LOADING_DEBUGEE ) {
        DebugeeModule = te.hModule;
        DebugeeTask = TaskAtNotify;
        StopNewTask.loc.segment = HIWORD( data );
        ReadMem( StopNewTask.loc.segment, StopNewTask.loc.offset,
                &StopNewTask.value, 1 );
        val = '\xcc';
        WriteMem( StopNewTask.loc.segment, StopNewTask.loc.offset,
                    &val, 1 );
        ReadMem( StopNewTask.loc.segment, StopNewTask.loc.offset,
                &val, 1 );
        Out((OUT_RUN,"           wrote breakpoint at %04x:%04lx, oldbyte=%02x(is now %02x)",
                    StopNewTask.loc.segment, StopNewTask.loc.offset,
                    StopNewTask.value, val ));
        Out((OUT_RUN,"   StartTask: cs:ip = %Fp", data ));
        ToDebugger( TASK_LOADED );
    } else {
        AddModuleLoaded( te.hModule, FALSE );
    }
    return( FALSE );

} /* doStartTask */
Ejemplo n.º 2
0
/*
 * doOutStr:
 *
 * handle a NFY_OUTSTR notification
 *
 * We return to the debugger so that it can display the string for the
 * user to see.
 */
static BOOL doOutStr( DWORD data )
{
    char        *src;

    if( DebuggerState != RUNNING_DEBUGEE ) {
        Out((OUT_ERR,"Debugger was bad! '%s'",OutBuff));
        return( 0 );
    }
    src = (LPSTR) data;
    while( *src ) {
        if( *src == '\r' || OutPos == (MAX_STR-1) ) {
            OutBuff[ OutPos++ ] = '\0';
            Out((OUT_RUN,"Going to debugger for OUT_STR '%s'",OutBuff));
            if( DebugeeTask == NULL ) return( 0 );
            ToDebugger( OUT_STR );
        }
        if( *src != '\n' && *src != '\t' ) {
            OutBuff[ OutPos++ ] = *src;
        }
        src++;
    }
    return( 0 );
} /* doOutStr */
Ejemplo n.º 3
0
/*
 * FaultHandler:
 *
 * Handle all faults.
 *
 * When we get a fault, the first thing we do is check if we are using
 * WDEBUG.386.  If we are, we call GetDebugInterruptData in WINT32.DLL
 * to see if the fault was a 32-bit one.  If it was, the structure
 * IntResult will be filled in.
 *
 * We make sure that we are not already handling a fault.  If we
 * are, we punt and give it to the next guy.
 *
 * We disable the hot key for doing CTRL_ALT_F (in WDEBUG.386), to make
 * sure that we are not interrupted while in the debugger!
 *
 * If we get an INT3, and it was NOT a 32-bit fault, we back up IP.
 * (If it was a 32-bit fault, it is communicated as a breakpoint, and
 * we don't need to back up IP). We then check if we were waiting for
 * the breakpoint, and if we were, we write back the original byte.
 *
 * If it was not a 32-bit fault, we call saveState, which copies the
 * correct data into the IntResult structure (this is the structure
 * that we use to access/update the registers, see accregs.c).
 *
 * We then directed yield to the debugger, and go into a message loop
 * for the debuggee.
 *
 * Once the debuggee exits its message loop, we check to see if we
 * need to do a special request (access a segment or do an I/O redirection).
 *
 * If there was no special request, we then reset the app's registers
 * (with restoreState for a 16-bit fault, and DoneWithInterreupt in WINT32.DLL
 * for a 32-bit fault), re-enable the hot key for async stopping,
 * and return to IntHandler to allow it to restart the debuggee.
 */
void __loadds __cdecl FaultHandler( volatile fault_frame ff )
{
    restart_opts        rc=CHAIN;
    private_msg         pmsg = FAULT_HIT;
    WORD                sig[2];

    WasInt32 = false;
    if( WDebug386 ) {
        WasInt32 = (bool)GetDebugInterruptData( &IntResult );
        if( WasInt32 ) {
            ff.intf.intnumber = IntResult.InterruptNumber;
            Out((OUT_RUN,"***** 32-bit fault %d, cs:eip=%04x:%08lx *****",
                IntResult.InterruptNumber, IntResult.CS, IntResult.EIP ));
        }
    }
    newStack( 0, 0L );

    /*
     * only one fault at a time
     */
    Out((OUT_RUN,"***** Fault %d, cs:ip=%04x:%04x, ent=%d, state=%d, WasInt32=%d *****",
        ff.intf.intnumber, ff.intf.CS, ff.intf.IP, FaultHandlerEntered,
        (WORD)DebuggerState, WasInt32 ));
    if( FaultHandlerEntered || DebuggerState == ACTIVE ) {
        if( ff.intf.intnumber == WGOD_ASYNCH_STOP_INT ) {
            setRetHow( RESTART_APP );
        } else {
            setRetHow( CHAIN );
        }
        return;
    }
    UseHotKey( 0 );

    ff.ESP = (WORD) ff.ESP;
    ff.intf.oldEBP = (WORD) ff.intf.oldEBP;

    if( ff.intf.intnumber == INT_3 ) {
        if( !WasInt32 ) {
            ff.intf.IP--;
        }
        Out((OUT_ERR,"BP at '(%d) %4.4x:%4.4x %4.4x:%8.8lx'",WasInt32,ff.intf.CS,ff.intf.IP,
        IntResult.CS,IntResult.EIP));
        if( ( WasInt32 && IntResult.CS == DLLLoadCS && IntResult.EIP == DLLLoadIP ) ||
            ( !WasInt32 && ff.intf.CS == DLLLoadCS && ff.intf.IP == DLLLoadIP ) ) {
            Out((OUT_RUN,"Caught DLL Loaded '%4.4x:%4.4x'",DLLLoadCS,DLLLoadIP));
            WriteMem( DLLLoadCS, DLLLoadIP, &DLLLoadSaveByte, 1 );
            ReadMem( IntResult.CS, SIG_OFF, sig, sizeof( DWORD ) );
            if( memcmp( sig, win386sig, 4 ) == 0 ) {
                Out((OUT_RUN,"Zapped sig"));
                WriteMem( IntResult.CS, SIG_OFF, win386sig2, sizeof( DWORD ) );
                pmsg = DLL_LOAD32;
                DLLLoadExpectingInt1 = TRUE;
            } else {
                pmsg = DLL_LOAD;
            }
            DLLLoadCS = 0;
            DLLLoadIP = 0;
        } else if( DebuggerState == WAITING_FOR_BREAKPOINT ) {
            if( (WasInt32 && IntResult.CS == StopNewTask.loc.segment &&
                        IntResult.EIP == StopNewTask.loc.offset ) ||
                (!WasInt32 && ff.intf.CS == StopNewTask.loc.segment &&
                        ff.intf.IP == StopNewTask.loc.offset) ) {
                WriteMem( StopNewTask.loc.segment, StopNewTask.loc.offset,
                            &StopNewTask.value, 1 );
                pmsg = START_BP_HIT;
            }
        }
    } else if( ff.intf.intnumber == 1 && WasInt32 && DLLLoadExpectingInt1 ) {
            // 32-bit dll load from above
        DLLLoadExpectingInt1 = FALSE;
        pmsg = DLL_LOAD;
    } else if( ff.intf.intnumber == WGOD_ASYNCH_STOP_INT ) {
        pmsg = ASYNCH_STOP;
        Out((OUT_RUN,"***** Sending ASYNCH_STOP to debugger"));
    }


    if( !WasInt32 ) {
        saveState( &ff );
    }
    FaultHandlerEntered = true;
    TaskAtFault = GetCurrentTask();

    if( FPUType == X86_NO ) {
        memset( &FPResult, 0, sizeof( FPResult ) );
    } else if( FPUType < X86_387 ) {
        Read8087( &FPResult );
    } else {
        Read387( &FPResult );
    }

    /*
     * switch to debugger
     */
    while( 1 ) {
        if( !ToDebugger( pmsg ) ) break;
        rc = DebugeeWaitForMessage();
        if( rc == RUN_REDIRECT ) {
            ExecuteRedirect();
        } else if( rc == ACCESS_SEGMENT ) {
            AVolatileInt = *(LPINT) MK_FP( SegmentToAccess+1, 0 );
        } else {
            break;
        }
    }
    Out((OUT_RUN,"***** ---> restarting app, rc=%d",rc));

    if( FPUType >= X86_387 ) {
        Write387( &FPResult );
    } else if( FPUType != X86_NO ) {
        Write8087( &FPResult );
    }

    if( !WasInt32 ) {
        restoreState( &ff );
        newStack( IntResult.SS, IntResult.ESP );
    } else {
        WasInt32 = false;
        DoneWithInterrupt( &IntResult );
    }
    TaskAtFault = NULL;

    FaultHandlerEntered = false;
    setRetHow( rc );
    UseHotKey( 1 );

} /* FaultHandler */