void WriteLinear( void *data, ULONG lin, USHORT size ) { Buff.Cmd = DBG_C_WriteMemBuf; Buff.Addr = lin; Buff.Buffer = (ULONG)data; Buff.Len = size; CallDosDebug(&Buff); }
void WriteLinear( void __far *data, ULONG lin, USHORT size ) { Buff.Cmd = DBG_C_WriteMemBuf; Buff.Addr = lin; Buff.Buffer = MakeLocalPtrFlat( data ); Buff.Len = size; CallDosDebug( &Buff ); }
/* * MakeSegmentedPointer - create a 16:16 ptr from a 0:32 ptr */ void __far *MakeSegmentedPointer( ULONG val ) { dos_debug buff; buff.Pid = Buff.Pid; buff.Cmd = DBG_C_LinToSel; buff.Addr = val; CallDosDebug( &buff ); return( MK_FP( (USHORT) buff.Value, (USHORT) buff.Index ) ); } /* MakeSegmentedPointer */
/* * MakeItFlatNumberOne - make a (sel,offset) into a flat pointer */ ULONG MakeItFlatNumberOne( USHORT seg, ULONG offset ) { dos_debug buff; if( IsFlatSeg( seg ) ) return( offset ); buff.Pid = Buff.Pid; buff.Cmd = DBG_C_SelToLin; buff.Value = seg; buff.Index = offset; CallDosDebug( &buff ); return( buff.Addr ); } /* MakeItFlatNumberOne */
static USHORT ReadBuffer( void *dst, USHORT segv, ULONG offv, USHORT size ) { USHORT length; bool iugs; USHORT resdata; ULONG flat; BYTE *data = dst; if( segv < 4 ) { return( 0 ); } length = size; if( Pid != 0 ) { iugs = IsUnknownGDTSeg( segv ); if( !iugs ) { flat = MakeItFlatNumberOne( segv, offv ); ReadLinear( data, flat, size ); if( Buff.Cmd == DBG_N_Success ) { return( size ); } } while( length != 0 ) { if( iugs || offv > KERNEL_MEM_OFFSET ) { if( !TaskReadWord( segv, offv, &resdata ) ) { break; } } else { Buff.Cmd = DBG_C_ReadMem_D; Buff.Addr = MakeItFlatNumberOne( segv, offv ); CallDosDebug(&Buff); if( Buff.Cmd != DBG_N_Success ) { break; } resdata = Buff.Value; } *data = resdata & 0xff; data++; offv++; length--; if( length != 0 ) { *data = resdata >> 8; data++; offv++; length--; } }
USHORT WriteBuffer( void *src, USHORT segv, ULONG offv, USHORT size ) { USHORT length; bool iugs; USHORT resdata; ULONG flat; BYTE *data = src; if( segv < 4 ) { return( 0 ); } length = size; if( Pid != 0 ) { iugs = IsUnknownGDTSeg( segv ); if( !iugs ) { flat = MakeItFlatNumberOne( segv, offv ); WriteLinear( data, flat, size ); if( Buff.Cmd == DBG_N_Success ) { return( size ); } } while( length != 0 ) { Buff.Cmd = DBG_C_WriteMem_D; if( length == 1 ) { /* Don't want to write anything in the kernel area - that means no breakpoints! */ if( iugs /*|| offv > KERNEL_MEM_OFFSET*/ ) { if( !TaskReadWord( segv, offv, &resdata ) ) { break; } resdata &= 0xff00; resdata |= *data; if( !TaskWriteWord( segv, offv, resdata ) ) { break; } } else { Buff.Cmd = DBG_C_ReadMem_D; Buff.Addr = MakeItFlatNumberOne( segv, offv ); CallDosDebug( &Buff ); Buff.Cmd = DBG_C_WriteMem_D; Buff.Addr = MakeItFlatNumberOne( segv, offv ); Buff.Value &= 0xff00; Buff.Value |= *data; CallDosDebug( &Buff ); if( Buff.Cmd != DBG_N_Success ) { break; } } data++; length--; offv++; } else { resdata = *data; data++; resdata |= *data << 8; data++; if( iugs ) { if( !TaskWriteWord( segv, offv, resdata ) ) { break; } } else { Buff.Value = resdata; Buff.Addr = MakeItFlatNumberOne( segv, offv ); CallDosDebug( &Buff ); if( Buff.Cmd != DBG_N_Success ) { break; } } length -= 2; offv += 2; } } } return( size - length ); /* return amount written */ }
void ReadRegs( uDB_t *buff ) { buff->Cmd = DBG_C_ReadReg; CallDosDebug( buff ); }
void WriteRegs( uDB_t *buff ) { buff->Cmd = DBG_C_WriteReg; CallDosDebug( buff ); }
bool DebugExecute( uDB_t *buff, ULONG cmd, bool stop_on_module_load ) { EXCEPTIONREPORTRECORD ex; ULONG value; ULONG stopvalue; ULONG notify = 0; BOOL got_second_notification; ULONG fcp; CONTEXTRECORD fcr; buff->Cmd = cmd; value = buff->Value; if( cmd == DBG_C_Go ) { value = 0; } stopvalue = XCPT_CONTINUE_EXECUTION; got_second_notification = FALSE; if( cmd == DBG_C_Stop ) { stopvalue = XCPT_CONTINUE_STOP; } for( ;; ) { buff->Value = value; buff->Cmd = cmd; CallDosDebug( buff ); value = stopvalue; cmd = DBG_C_Continue; /* * handle the preemptive notifications */ switch( buff->Cmd ) { case DBG_N_ModuleLoad: RecordModHandle( buff->Value ); if( stop_on_module_load ) return( TRUE ); break; case DBG_N_ModuleFree: break; case DBG_N_NewProc: break; case DBG_N_ProcTerm: value = XCPT_CONTINUE_STOP; /* halt us */ notify = DBG_N_ProcTerm; break; case DBG_N_ThreadCreate: break; case DBG_N_ThreadTerm: break; case DBG_N_AliasFree: break; case DBG_N_Exception: ExceptLinear = buff->Addr; if( buff->Value == DBG_X_STACK_INVALID ) { value = XCPT_CONTINUE_SEARCH; break; } fcp = buff->Len; if( buff->Value == DBG_X_PRE_FIRST_CHANCE ) { ExceptNum = buff->Buffer; if( ExceptNum == XCPT_BREAKPOINT ) { notify = DBG_N_Breakpoint; value = XCPT_CONTINUE_STOP; break; } else if( ExceptNum == XCPT_SINGLE_STEP ) { notify = DBG_N_SStep; value = XCPT_CONTINUE_STOP; break; } } // // NOTE: Going to second chance causes OS/2 to report the // exception in the debugee. However, if you report // the fault at the first chance notification, the // debugee's own fault handlers will not get invoked! // if( buff->Value == DBG_X_FIRST_CHANCE && !ExpectingAFault ) { if( stopOnSecond && !got_second_notification ) { value = XCPT_CONTINUE_SEARCH; break; } } notify = DBG_N_Exception; value = XCPT_CONTINUE_STOP; /* * Buffer contains the ptr to the exception block */ buff->Cmd = DBG_C_ReadMemBuf; buff->Addr = buff->Buffer; buff->Buffer = (ULONG)&ex; buff->Len = sizeof( ex ); CallDosDebug( buff ); ExceptNum = ex.ExceptionNum; if( ExceptNum == XCPT_PROCESS_TERMINATE || ExceptNum == XCPT_ASYNC_PROCESS_TERMINATE || ExceptNum == XCPT_GUARD_PAGE_VIOLATION || ( ExceptNum & XCPT_CUSTOMER_CODE ) ) { value = XCPT_CONTINUE_SEARCH; break; } /* * get the context record */ buff->Cmd = DBG_C_ReadMemBuf; buff->Addr = fcp; buff->Buffer = (ULONG)&fcr; buff->Len = sizeof( fcr ); CallDosDebug( buff ); buff->EAX = fcr.ctx_RegEax; buff->EBX = fcr.ctx_RegEbx; buff->ECX = fcr.ctx_RegEcx; buff->EDX = fcr.ctx_RegEdx; buff->ESI = fcr.ctx_RegEsi; buff->EDI = fcr.ctx_RegEdi; buff->ESP = fcr.ctx_RegEsp; buff->EBP = fcr.ctx_RegEbp; buff->DS = fcr.ctx_SegDs; buff->CS = fcr.ctx_SegCs; buff->ES = fcr.ctx_SegEs; buff->FS = fcr.ctx_SegFs; buff->GS = fcr.ctx_SegGs; buff->SS = fcr.ctx_SegSs; buff->EIP = fcr.ctx_RegEip; buff->EFlags = fcr.ctx_EFlags; WriteRegs(buff); if( ExpectingAFault || got_second_notification ) { break; } if( stopOnSecond ) { value = XCPT_CONTINUE_EXECUTION; got_second_notification = TRUE; } break; default: if( notify != 0 ) { buff->Cmd = notify; // Check if we hit our splice DLL breakpoint if( (notify == DBG_N_Breakpoint) && splice_bp_set && (splice_bp_lin_addr == ExceptLinear) ) { uDB_t save; // Remove breakpoint WriteLinear( &saved_splice_bp, splice_bp_lin_addr, sizeof( byte ) ); splice_bp_set = FALSE; splice_bp_lin_addr = 0; // Attempt to load helper DLL save.Pid = Pid; save.Tid = 1; ReadRegs( &save ); ExpectingAFault = TRUE; // NB - the following will recursively call DebugExecute! if( !CausePgmToLoadHelperDLL( ExceptLinear ) ) { CanExecTask = FALSE; } else { CanExecTask = TRUE; } WriteRegs( &save ); break; } } return( FALSE ); } } // return( FALSE ); }
USHORT WriteBuffer( byte __far *data, USHORT segv, ULONG offv, USHORT size ) { USHORT length; bool iugs; USHORT resdata; ULONG flat; if( segv < 4 ) { return( 0 ); } length = size; if( Pid != 0 ) { iugs = IsUnknownGDTSeg( segv ); if( !iugs ) { flat = MakeItFlatNumberOne( segv, offv ); WriteLinear( data, flat, size ); if( Buff.Cmd == DBG_N_Success ) { return( size ); } } while( length != 0 ) { Buff.Cmd = DBG_C_WriteMem_D; if( length == 1 ) { if( iugs ) { if( !TaskReadWord( segv, offv, &resdata ) ) { break; } resdata &= 0xff00; resdata |= *data; if( !TaskWriteWord( segv, offv, resdata ) ) { break; } } else { Buff.Cmd = DBG_C_ReadMem_D; Buff.Addr = MakeItFlatNumberOne( segv, offv ); CallDosDebug( &Buff ); Buff.Cmd = DBG_C_WriteMem_D; Buff.Addr = MakeItFlatNumberOne( segv, offv ); Buff.Value &= 0xff00; Buff.Value |= *data; CallDosDebug( &Buff ); if( Buff.Cmd != DBG_N_Success ) { break; } } data++; length--; offv++; } else { resdata = *data; data++; resdata |= *data << 8; data++; if( iugs ) { if( !TaskWriteWord( segv, offv, resdata ) ) { break; } } else { Buff.Value = resdata; Buff.Addr = MakeItFlatNumberOne( segv, offv ); CallDosDebug( &Buff ); if( Buff.Cmd != DBG_N_Success ) { break; } } length -= 2; offv += 2; } } } return( size - length ); /* return amount written */ }
void ReadRegs( dos_debug *buff ) { buff->Cmd = DBG_C_ReadReg; CallDosDebug( buff ); }
void WriteRegs( dos_debug *buff ) { buff->Cmd = DBG_C_WriteReg; CallDosDebug( buff ); }