/* * executeUntilVDMStart - go until we hit our first VDM exception */ static BOOL executeUntilVDMStart( void ) { int rc; for( ;; ) { rc = DebugExecute( STATE_WAIT_FOR_VDM_START, NULL, FALSE ); if( rc == COND_VDM_START ) { return( TRUE ); } return( FALSE ); } }
/* * executeUntilStart - run program until start address hit */ static BOOL executeUntilStart( BOOL was_running ) { HANDLE ph; opcode_type saved_opcode; opcode_type brk_opcode = BRKPOINT; LPVOID base; SIZE_T bytes; MYCONTEXT con; thread_info *ti; ph = DebugEvent.u.CreateProcessInfo.hProcess; if( !was_running ) { /* * if we are not debugging an already running app, then we * plant a breakpoint at the first instruction of our new app */ base = (LPVOID)DebugEvent.u.CreateProcessInfo.lpStartAddress; ReadProcessMemory( ph, base, (LPVOID)&saved_opcode, sizeof( saved_opcode ), &bytes ); WriteProcessMemory( ph, base, (LPVOID)&brk_opcode, sizeof( brk_opcode ), &bytes ); } else { // a trick to make app execute long enough to hit a breakpoint PostMessage( HWND_TOPMOST, WM_NULL, 0, 0L ); } for( ;; ) { /* * if we encounter anything but a break point, then we are in * trouble! */ if( DebugExecute( STATE_IGNORE_DEBUG_OUT | STATE_IGNORE_DEAD_THREAD, NULL, FALSE ) & COND_BREAK ) { ti = FindThread( DebugEvent.dwThreadId ); MyGetThreadContext( ti, &con ); if( was_running ) { AdjustIP( &con, sizeof( brk_opcode ) ); MySetThreadContext( ti, &con ); return( TRUE ); } if( StopForDLLs ) { /* * the user has asked us to stop before any DLL's run * their startup code (";dll"), so we do. */ WriteProcessMemory( ph, base, (LPVOID)&saved_opcode, sizeof( saved_opcode ), &bytes ); AdjustIP( &con, sizeof( brk_opcode ) ); MySetThreadContext( ti, &con ); return( TRUE ); } if( ( AdjustIP( &con, 0 ) == base ) ) { /* * we stopped at the applications starting address, * so we can offically declare that the app has loaded */ WriteProcessMemory( ph, base, (LPVOID)&saved_opcode, sizeof( saved_opcode ), &bytes ); return( TRUE ); } /* * skip this breakpoint and continue */ AdjustIP( &con, sizeof( brk_opcode ) ); MySetThreadContext( ti, &con ); } else { return( FALSE ); } } }
DebugIt( void *crap ) { STARTDATA start; int code; SWCNTRL SW; HSWITCH hswitch; PPIB pib; PTIB tib; HWND hwndme; QMSG qmsg; /* Message from message queue */ int i; PID Pid = 0; ULONG SID; uDB_t Buff; TID tid; HMQ the_q; DosGetInfoBlocks(&tib,&pib); start.Length = offsetof( STARTDATA, IconFile ); /* default for the rest */ start.Related = 1; start.FgBg = 1; start.TraceOpt = 1; start.PgmTitle = (PSZ) "Test Session"; start.PgmName = "HELLO.EXE"; start.PgmInputs = "hi there"; start.TermQ = 0; start.Environment = NULL; start.InheritOpt = 1; start.SessionType = SSF_TYPE_PM; code = DosStartSession( &start, &SID, &Pid ); Buff.Pid = Pid; Buff.Tid = 0; Buff.Cmd = DBG_C_Connect; Buff.Value = DBG_L_386; DosDebug( &Buff ); Buff.Pid = Pid; Buff.Tid = 1; DebugExecute( &Buff, DBG_C_Stop ); if( Buff.Cmd != DBG_N_Success ) { return; } DebugExecute( &Buff, DBG_C_Go ); if( Buff.Cmd != DBG_N_Breakpoint ) { return; } #if 0 Buff.Cmd = DBG_C_Stop; DosDebug( &Buff ); Buff.Cmd = DBG_C_ReadReg; DosDebug( &Buff ); Buff.EIP++; Buff.Cmd = DBG_C_WriteReg; DosDebug( &Buff ); #endif the_q = WinQueueFromID( Hab, Buff.Pid, Buff.Tid ); #if 0 for( ;; ) { hmq = WinQuerySendMsg( Hab, 0, Q, &qmsg ); if( hmq == 0 ) break; WinReplyMsg( Hab, hmq, Q, 1 ); } #endif WinThreadAssocQueue( Hab, the_q ); while( 1 ) { if( !WinGetMsg( Hab, &qmsg, 0L, 0, 0 ) ) break; } WinThreadAssocQueue( Hab, 0 ); for( ;; ) DosSleep( 100 ); }
bool CausePgmToLoadThisDLL( ULONG startLinear ) { char savecode[LOAD_THIS_DLL_SIZE]; USHORT codesize; USHORT len; loadstack_t far *loadstack; void far *ptr; USHORT dll_name_len; USHORT size; char this_dll[BUFF_SIZE]; bool rc; /* * save a chunk of the program's code, and put in LoadThisDLL instead */ if( DosGetModName( ThisDLLModHandle, BUFF_SIZE, this_dll ) != 0 ) { return( FALSE ); } codesize = (char *)EndLoadThisDLL - (char *)LoadThisDLL; if( codesize > LOAD_THIS_DLL_SIZE ) return( FALSE ); ReadLinear( savecode, startLinear, codesize ); if( Buff.Cmd != DBG_N_Success ) return( FALSE ); WriteLinear( (byte far *)LoadThisDLL, startLinear, codesize ); /* * set up the stack for the routine LoadThisDLL */ dll_name_len = ( strlen( this_dll ) + 1 ) & ~1; size = sizeof( loadstack_t ) + dll_name_len; loadstack = Automagic( size ); Buff.ESP -= size; strcpy( loadstack->load_name, this_dll ); loadstack->fail_name = NULL; loadstack->fail_len = 0; ptr = MakeItSegmentedNumberOne( Buff.SS, Buff.ESP + offsetof( loadstack_t, load_name ) ); loadstack->mod_name[0] = FP_OFF( ptr ); loadstack->mod_name[1] = FP_SEG( ptr ); ptr = MakeItSegmentedNumberOne( Buff.SS, Buff.ESP + offsetof( loadstack_t, hmod ) ); loadstack->phmod[0] = FP_OFF( ptr ); loadstack->phmod[1] = FP_SEG( ptr ); len = WriteBuffer( (byte far *)loadstack, Buff.SS, Buff.ESP, size ); if( len != size ) return( FALSE ); /* * set up 16:16 CS:IP, SS:SP for execution */ ptr = MakeSegmentedPointer( startLinear ); Buff.CS = FP_SEG( ptr ); Buff.EIP = FP_OFF( ptr ); ptr = MakeItSegmentedNumberOne( Buff.SS, Buff.ESP ); Buff.SS = FP_SEG( ptr ); Buff.ESP = FP_OFF( ptr ); /* * execute LoadThisDLL on behalf of the program */ WriteRegs( &Buff ); DebugExecute( &Buff, DBG_C_Go, FALSE ); if( Buff.Cmd != DBG_N_Breakpoint ) { rc = FALSE; } else { rc = TRUE; } WriteLinear( savecode, startLinear, codesize ); return( rc ); }
static void StopDebuggee( void ) { if( DebugeePid && ( IsWOW || !DebugeeEnded ) ) { /* * we must process debug events until the process is actually * terminated */ Slaying = TRUE; #if !defined( MD_x64 ) if( IsWin32s ) { DoContinueDebugEvent( DBG_TERMINATE_PROCESS ); DoWaitForDebugEvent(); DoContinueDebugEvent( DBG_CONTINUE ); } else { #else { #endif HANDLE hp; hp = OpenProcess( PROCESS_ALL_ACCESS, FALSE, DebugeePid ); if( hp != NULL ) { TerminateProcess( hp, 0 ); CloseHandle( hp ); while( !( DebugExecute( 0, NULL, FALSE ) & COND_TERMINATE ) ) { } /* * we must continue the final debug event for everything to * be truly clean and wonderful */ DoContinueDebugEvent( DBG_CONTINUE ); } } Slaying = FALSE; } DebugeePid = 0; } // end of seperate thread DWORD StartControlThread( char *name, DWORD *pid, DWORD cr_flags ) { Shared.pid = *pid; Shared.flags = cr_flags; Shared.name = name; Shared.control_thread_running = FALSE; #if !defined( MD_x64 ) if( !IsWin32s ) { #else { #endif DWORD tid; Shared.requestsem = CreateSemaphore( NULL, 0, 1, NULL ); Shared.requestdonesem = CreateSemaphore( NULL, 0, 1, NULL ); Shared.hThread = CreateThread( NULL, 0, ControlFunc, NULL, 0, &tid ); if( Shared.hThread == NULL ) { MessageBox( NULL, "Error creating thread!", TRP_The_WATCOM_Debugger, MB_APPLMODAL + MB_OK ); } Shared.control_thread_running = TRUE; } ControlReq( CTL_START ); *pid = Shared.pid; return( Shared.err ); } /* * MyWaitForDebugEvent - wait for a debug event. Only return meaningful * VDM debug events */ BOOL MyWaitForDebugEvent( void ) { if( Shared.on_control_thread ) { return( DoWaitForDebugEvent() ); } ControlReq( CTL_WAIT ); return( Shared.rc ); } void MyContinueDebugEvent( int continue_how ) { if( Shared.on_control_thread ) { DoContinueDebugEvent( continue_how ); return; } Shared.how = continue_how; ControlReq( CTL_CONTINUE ); } void StopControlThread( void ) { ControlReq( CTL_STOP ); if( Shared.control_thread_running ) { WaitForSingleObject( Shared.hThread, INFINITE ); CloseHandle( Shared.requestsem ); CloseHandle( Shared.requestdonesem ); Shared.control_thread_running = FALSE; } }