Exemplo n.º 1
0
/*
 * ReqProg_kill
 *
 * If it was a task that we attached to (WasStarted), all we do is
 * forgive the last interrupt, and then exit
 *
 * If it was a task we started, we TerminateApp it, and then wait for
 * the task ended notification.  Note:  Task ended isn't quite good enough,
 * since the module isn't unloaded.  However, you may never get the module
 * unloaded notification, if you are debugging the 2nd, 3rd etc instance
 * of an app, since the module is loaded more than once.  BUT, a NEW command
 * from the debugger ends up restarting the app "too fast" - the module isn't
 * deleted yet, and so it ends up running a second instance, even if you
 * really don't have a first instance.  This is the reason for that half
 * second pause - to allow Windows to get on with the unloading of the module,
 * if it is going to.  Ack.
 */
unsigned ReqProg_kill( void )
{
    prog_kill_ret       *ret;

    ret = GetOutPtr( 0 );
    ret->err = 0;
    Out((OUT_LOAD,"KILL: DebugeeTask=%04x, WasStarted=%d",
        DebugeeTask, WasStarted ));
    if( DebugeeTask != NULL ) {
        IntResult.EFlags &= ~TRACE_BIT;
        if( WasStarted ) {
            Out((OUT_LOAD,"Doing Release Debugee"));
            DebuggerWaitForMessage( RELEASE_DEBUGEE, DebugeeTask, RESTART_APP );
        } else {
            TerminateApp( DebugeeTask, NO_UAE_BOX );
            DebuggerWaitForMessage( KILLING_DEBUGEE, NULL, -1 );
            Out((OUT_LOAD,"Task Terminated(not current)"));
            {
                DWORD   a;
                a = GetTickCount();
                while( GetTickCount() < a + 500 ) {
                    Yield();
                }
            }
        }
#if 0
        FiniASynchHook();
#endif
    }
    ExitSoftMode();
    if( WDebug386 ) {
        if( WasInt32 ) {
            WasInt32 = FALSE;
            DoneWithInterrupt( NULL );
        }
    }
    DebugeeTask = NULL;
    ModuleTop = 0;
    CurrentModule = 1;
    FaultHandlerEntered = FALSE;
    PendingTrap = FALSE;
    SaveStdIn = NIL_HANDLE;
    SaveStdOut = NIL_HANDLE;
    Debugging32BitApp = FALSE;
    return( sizeof( *ret ) );
}
Exemplo n.º 2
0
/*
 * accessSegment:
 *
 * Access a segment to cause the windows loader to load it. We find
 * the segment by looking through the module entry (which is a lot like
 * an NE header, except that where segment numbers would be, the selector
 * value is). We then have the app we are debugging execute an instruction that
 * references the seqment in question.
 */
static void accessSegment( GLOBALHANDLE gh, WORD segment )
{
    WORD                i;
    WORD                sel;
    WORD                offset;

    ReadMem( (WORD)gh, 0x22, &offset, sizeof( offset ) );
    i = 0;
    while( i < segment ) {
        ReadMem( (WORD)gh, offset+8, &sel, sizeof( sel ) );
        offset += 10;
        i++;
    }
    SegmentToAccess = sel;
    DebuggerWaitForMessage( RUNNING_DEBUGEE, TaskAtFault, ACCESS_SEGMENT );

} /* accessSegment */
Exemplo n.º 3
0
/*
 * runProg:
 *
 * - we turn on the T-bit for single_step mode, and set the debug registers
 *   for watch points (if we can).
 * - we then switch to the debuggee, and wait for a fault to occur.
 * - after the fault, we record information about it and return
 *
 */
static unsigned runProg( bool single_step )
{
    private_msg         pmsg;
    BOOL                watch386;
    BOOL                dowatch;
    BOOL                ton;
    restart_opts        restart_option;
    prog_go_ret         *ret;

    ret = GetOutPtr( 0 );

    if( DebugeeTask == NULL ) {
        ret->conditions = COND_TERMINATE;
        return( sizeof( *ret ) );
    }

    IntResult.EFlags &= ~TRACE_BIT;
    dowatch = FALSE;
    watch386 = FALSE;
    UnLockInput();

    if( single_step ) {
        SingleStepMode();
    } else if( WPCount != 0 ) {
        dowatch = TRUE;
        watch386 = SetDebugRegs();
    }

    ret->conditions = 0;
    restart_option = RESTART_APP;
    while( DebugeeTask != NULL ) {
        if( dowatch && !watch386 ) {
            SingleStepMode();
        }
        ton = TraceOn;
        pmsg = DebuggerWaitForMessage( RUNNING_DEBUGEE, TaskAtFault, restart_option );
        TraceOn = FALSE;

        if( pmsg == FAULT_HIT ) {
            switch( IntResult.InterruptNumber ) {
            case INT_1:
                ret->conditions = COND_TRACE;
                if( watch386 ) {
                    if( GetDR6() & 0xf ) {
                        ret->conditions = COND_WATCH;
                        if( DebugDebugeeOnly ) {
                            if( !CheckWatchPoints() ) {
                                restart_option = CHAIN;
                                continue;
                            }
                        }
                    }
                    break;
                }
                if( !ton && DebugDebugeeOnly ) {
                    restart_option = CHAIN;
                    continue;
                }
                if( dowatch ) {
                    if( CheckWatchPoints() ) {
                        ret->conditions = COND_WATCH;
                    } else {
                        restart_option = RESTART_APP;
                        continue;
                    }
                }
                break;
            case INT_3:
                if( DebugDebugeeOnly ) {
                    if( !IsOurBreakpoint( IntResult.CS, IntResult.EIP ) ) {
                        IntResult.EIP++;
                        restart_option = CHAIN;
                        continue;
                    }
                }
                ret->conditions = COND_BREAK;
                break;
            default:
                if( DebugDebugeeOnly ) {
                    if( TaskAtFault != DebugeeTask ) {
                        restart_option = CHAIN;
                        continue;
                    }
                }
                ret->conditions = COND_EXCEPTION;
                break;
            }
            break;
        } else if( pmsg == TASK_ENDED ) {
            ret->conditions = COND_TERMINATE;
            DebugeeTask = NULL;
            IntResult.CS = TerminateCSIP >> 16;
            IntResult.EIP = (DWORD) (WORD) TerminateCSIP;
            break;
        } else if( pmsg == GET_CHAR ) {
Exemplo n.º 4
0
/*
 * AccLoadProg
 *
 * To load a app, we do the following:
 *
 *  Case 1: debugging an existing task
 *      - Find its current CS:IP.
 *      - Plant a breakpoint at the current CS:IP
 *
 *  Case 2: starting a task from scratch
 *      - Look up the start address from the .EXE
 *      - WinExec the app
 *      - Wait for the STARTASK notification for the app
 *      - Plant a breakpoint at its start address
 *
 *  - Wait for the app to hit the breakpoint
 *  - Check if the app is a 32-bit app (look for "DEADBEEF" in code seg).
 *     If it is a 32-bit app:
 *      - Flip the "DEADBEEF" to "BEEFDEAD".  If the extender see's the
 *        "BEEFDEAD", it executes a breakpoint right before it jumps to
 *        the 32-bit code
 *      - Let the app run until a breakpoint is hit
 *      - Trace one instruction. This leaves you at the first instruction
 *        of the 32-bit code
 */
unsigned ReqProg_load( void )
{
    char                exe_name[_MAX_PATH];
    char                drive[_MAX_DRIVE],directory[_MAX_DIR];
    char                buff[256];
    lm_parms            loadp;
    word_struct         cmdshow;
    char                *parm;
    char                *src;
    char                *dst;
    char                ch;
    unsigned            a,b;
    private_msg         pmsg;
    char                sig[sizeof(DWORD)];
    HTASK               tid;
    DWORD               csip;
    prog_load_req       *acc;
    prog_load_ret       *ret;
    char                *end;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret->flags = LD_FLAG_IS_PROT | LD_FLAG_HAVE_RUNTIME_DLLS;
    parm = GetInPtr( sizeof( *acc ) );

    /*
     * reset flags
     */
    OutPos = 0;
    WasStarted = FALSE;
    LoadingDebugee = TRUE;
    Debugging32BitApp = FALSE;
    AddAllCurrentModules();

    /*
     * check for task id
     */
    tid = 0;
    src = parm;
    if( *src == '#' ) {
        src++;
        tid = (HTASK)strtol( src, NULL, 16 );
    } else {
        while( *src != 0 ) {
            if( !isdigit( *src ) ) {
                break;
            }
            src++;
        }
        if( *src == 0 && src != parm ) {
            tid = (HTASK)atoi( parm );
        }
    }
    if( tid != 0 ) {
        csip = GetRealCSIP( tid, &DebugeeModule );
        if( csip == 0 ) {
            tid = 0;
        } else {
            DebugeeTask = tid;
            StopNewTask.loc.segment = FP_SEG( (LPVOID) csip );
            StopNewTask.loc.offset = FP_OFF( (LPVOID) csip );
            ReadMem( StopNewTask.loc.segment, StopNewTask.loc.offset,
                    &StopNewTask.value, 1 );
            ch = 0xcc;
            WriteMem( StopNewTask.loc.segment, StopNewTask.loc.offset, &ch, 1 );
        }
    } else {
        tid = 0;
    }

    /*
     * get the file to execute
     */
    if( tid == 0 ) {
        if( TINY_ERROR( FindFilePath( parm, exe_name, ExtensionList ) ) ) {
            exe_name[0] = 0;
        } else {
            _splitpath( exe_name, drive, directory, NULL, NULL );
            a = tolower( drive[0] ) - 'a' + 1;
            _dos_setdrive( a, &b );
            directory[ strlen( directory ) - 1 ] = 0;
            chdir( directory );
        }

        /*
         * get the parm list
         */

        src = parm;
        while( *src != 0 )
            ++src;
        ++src;
        end = GetInPtr( GetTotalSize() - 1 );
        dst = &buff[1];
        for( ;; ) {
            if( src > end )
                break;
            ch = *src;
            if( ch == 0 )
                ch = ' ';
            *dst = ch;
            ++dst;
            ++src;
        }
        if( dst > &buff[1] )
            --dst;
        *dst = '\0';
        buff[0] = dst-buff-1;

        /*
         * get starting point in task
         */
        if( !GetStartAddress( exe_name, &StopNewTask.loc ) ) {
            Out((OUT_ERR,"Could not get starting address"));
            ret->err = WINERR_NOSTART;
            LoadingDebugee = FALSE;
            return( sizeof( *ret ) );
        }
        StopNewTask.segment_number = StopNewTask.loc.segment;
        Out((OUT_LOAD,"Loading %s, cs:ip = %04x:%04lx", exe_name, StopNewTask.loc.segment,
                            StopNewTask.loc.offset ));

        /*
         * load the task
         */
        loadp.cmdshow = &cmdshow;
        loadp.wEnvSeg = 0;
        loadp.lpCmdLine = (LPSTR) buff;
        loadp.cmdshow->mustbe2 = 2;
        loadp.cmdshow->cmdshow = SW_NORMAL;
        loadp.reserved = 0L;
        DebuggerState = LOADING_DEBUGEE;
        DebugeeInstance = LoadModule( exe_name, (LPVOID) &loadp );
        if( (UINT)DebugeeInstance < 32 ) {
            Out((OUT_ERR,"Debugee did not load %d", DebugeeInstance));
            ret->err = WINERR_NOLOAD;
            LoadingDebugee = FALSE;
            return( sizeof( *ret ) );
        }
        DebuggerWaitForMessage( WAITING_FOR_TASK_LOAD, NULL, RESTART_APP );
    }
    AddDebugeeModule();
    pmsg = DebuggerWaitForMessage( WAITING_FOR_BREAKPOINT, DebugeeTask, RESTART_APP );
    if( pmsg == START_BP_HIT ) {

        ret->err = 0;
        ret->task_id = (unsigned_32)DebugeeTask;

        /*
         * look for 32-bit windows application
         */
        ReadMem( IntResult.CS, SIG_OFF, sig, sizeof( DWORD ) );
        if( !StopOnExtender && (!memcmp( sig, win386sig, 4 ) ||
                !memcmp( sig, win386sig2, 4 )) ) {
            Out((OUT_LOAD,"Is Win32App" ));
            Debugging32BitApp = TRUE;
            /*
             * make sure that WDEBUG.386 is installed
             */
            if( !WDebug386 ) {
                ret->err = WINERR_NODEBUG32; /* Can't debug 32 bit app */
                LoadingDebugee = FALSE;
                return( sizeof( *ret ) );
            }
            ret->flags |= LD_FLAG_IS_32;
            if( tid == 0 ) {
                WriteMem( IntResult.CS, SIG_OFF, win386sig2, sizeof( DWORD ) );
                pmsg = DebuggerWaitForMessage( GOING_TO_32BIT_START,
                                DebugeeTask, RESTART_APP );
                if( pmsg == FAULT_HIT && IntResult.InterruptNumber == INT_3 ) {
                    IntResult.EIP++;
                    SingleStepMode();
                    pmsg = DebuggerWaitForMessage( GOING_TO_32BIT_START,
                                DebugeeTask, RESTART_APP );
                    if( pmsg != FAULT_HIT || IntResult.InterruptNumber != INT_1 ) {
                        Out((OUT_ERR,"Expected INT_1 not found"));
                        ret->err = WINERR_NOINT1;
                    }
                } else {
                    Out((OUT_ERR,"Expected INT_3 not found"));
                    ret->err = WINERR_NOINT3;
                }
            }
        }
        if( tid != 0 ) {
            ret->flags |= LD_FLAG_IS_STARTED;
            WasStarted = TRUE;
        }
    } else {
        Out((OUT_ERR,"Starting breakpoint not found, pmsg=%d", pmsg ));
        ret->err = WINERR_STARTNOTFOUND;
    }
#if 0
    if( DebugeeTask != NULL ) {
        InitASynchHook();
    }
#endif
    LoadingDebugee = FALSE;
    CurrentModule = 1;
    ret->mod_handle = 0;
    return( sizeof( *ret ) );
}