void AttView::KeyDown(const char *bytes, int32 numBytes) { // Single byte values can be tested against ascii character codes... if (numBytes == 1) { if (bytes[0] == 32) { if (SingleStepMode()) SingleStepMode(false); else SingleStepMode(true); } else if (bytes[0] == 122) { mStep++; } } inherited::KeyDown(bytes, numBytes); }
/* * 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 ) {
/* * 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 ) ); }