static void DoAddLib( pid_t pid, struct link_map *lmap ) { lib_load_info *lli; // inefficient code, but not called very often ModuleTop++; lli = malloc( ModuleTop * sizeof( lib_load_info ) ); memset( lli, 0, ModuleTop * sizeof( lib_load_info ) ); memcpy( lli, ModuleInfo, (ModuleTop - 1) * sizeof( lib_load_info ) ); free( ModuleInfo ); ModuleInfo = lli; lli = ModuleInfo + ModuleTop - 1; lli->offset = lmap->l_addr; lli->dbg_dyn_sect = (addr_off)lmap->l_ld; dbg_strcpy( pid, lli->filename, lmap->l_name ); lli->offset = lmap->l_addr; dbg_printf( "Added library, ofs/dyn = %p/%p'%s'\n", lmap->l_addr, (addr_off)lmap->l_ld, lli->filename ); // no name, not interested if( lli->filename[0] != '\0' ) { CodeLoad( lli->filename, lmap->l_addr, SAMP_CODE_LOAD ); } }
static USHORT LibLoadPTrace( TRACEBUF FAR_PTR *buff ) { int cmd; int value; USHORT rv; USHORT offv; USHORT segv; char name[BUFF_SIZE]; cmd = buff->cmd; value = buff->value; segv = buff->segv; offv = buff->offv; for( ;; ) { rv = DosPTrace( buff ); if( MainMod == 0 ) MainMod = buff->mte; if( buff->cmd != PT_RET_LIB_LOADED ) return( rv ); buff->cmd = PT_CMD_GET_LIB_NAME; buff->segv = FP_SEG( name ); buff->offv = FP_OFF( name ); DosPTrace( buff ); CodeLoad( buff, buff->value, name, ( MainMod == buff->value ) ? SAMP_MAIN_LOAD : SAMP_CODE_LOAD ); buff->value = value; buff->cmd = cmd; buff->offv = offv; buff->segv = segv; } }
void StartProg( char *cmd, char *prog, char *full_args, char *dos_args ) { char exe_name[PATH_MAX]; pid_t save_pgrp; pid_t pid; int status; MaxThread = 0; GrowArrays( 1 ); HaveRdebug = false; DbgDyn = NULL; OrigPGrp = getpgrp(); Attached = true; pid = Pid = SamplePid; /* allow attaching to existing process by pid */ if( pid == 0 || ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) { int num_args; size_t len; const char **argv; Attached = false; /* massage 'full_args' into argv format */ len = strlen( full_args ); num_args = SplitParms( full_args, NULL, len ); argv = alloca( ( num_args + 2 ) * sizeof( *argv ) ); argv[SplitParms( full_args, argv + 1, len ) + 1] = NULL; argv[0] = prog; Output( MsgArray[MSG_SAMPLE_1 - ERR_FIRST_MESSAGE] ); Output( prog ); Output( "\n" ); save_pgrp = getpgrp(); setpgid( 0, OrigPGrp ); pid = fork(); if( pid == -1 ) InternalError( MsgArray[MSG_SAMPLE_3 - ERR_FIRST_MESSAGE] ); if( pid == 0 ) { int rc; if( ptrace( PTRACE_TRACEME, 0, NULL, NULL ) < 0 ) { InternalError( MsgArray[MSG_SAMPLE_4 - ERR_FIRST_MESSAGE] ); } dbg_printf( "executing '%s'\n", prog ); for( rc = 0; argv[rc] != NULL; ++rc ) dbg_printf( "argv[%d] = '%s'\n", rc, argv[rc] ); rc = execve( prog, (char const * const *)argv, (char const * const *)environ ); dbg_printf( "execve() failed, returned %d\n", rc ); InternalError( MsgArray[MSG_SAMPLE_3 - ERR_FIRST_MESSAGE] ); // failsafe } setpgid( 0, save_pgrp ); strcpy( exe_name, prog ); } else if( pid ) { GetExeNameFromPid( pid, exe_name, PATH_MAX ); Output( MsgArray[MSG_SAMPLE_1 - ERR_FIRST_MESSAGE] ); Output( exe_name ); Output( "\n" ); } if( (pid != -1) && (pid != 0) ) { /* wait until it hits _start (upon execve) or gives us a SIGSTOP (if attached) */ if( waitpid( pid, &status, 0 ) < 0 ) goto fail; if( !WIFSTOPPED( status ) ) goto fail; if( Attached ) { if( WSTOPSIG( status ) != SIGSTOP ) { goto fail; } } else { if( WSTOPSIG( status ) != SIGTRAP ) { goto fail; } } DbgDyn = GetDebuggeeDynSection( exe_name ); errno = 0; } if( errno != 0 ) { pid = 0; } else { /* record information about main executable and initialize shared * library tracking */ InitLibMap(); CodeLoad( exe_name, 0, SAMP_MAIN_LOAD ); SampleLoop( pid ); FiniLibMap(); } return; fail: if( pid != 0 && pid != -1 ) { if( Attached ) { ptrace( PTRACE_DETACH, pid, NULL, NULL ); Attached = false; } else { ptrace( PTRACE_KILL, pid, NULL, NULL ); waitpid( pid, &status, 0 ); } } InternalError( MsgArray[MSG_SAMPLE_5 - ERR_FIRST_MESSAGE] ); }
void StartProg( const char *cmd, const char *prog, char *full_args, char *dos_args ) { const char *src; char *dst; USHORT drive; ULONG map; USHORT len; USHORT tid; USHORT rc; char buff[BSIZE]; seg_offset where; char *cmd_tail; /* unused parameters */ (void)cmd; MaxThread = 0; GrowArrays( 1 ); src = prog; dst = UtilBuff; DosQCurDisk( &drive, &map ); if( src[0] == '\0' || src[1] == '\0' || src[1] != ':' ) { *dst++ = drive - 1 + 'A'; *dst++ = ':'; } else { *dst++ = *src++; *dst++ = *src++; } if( src[0] != '\\' ) { ++dst; len = BUFF_SIZE - ( dst - UtilBuff ); DosQCurDir( drive, (PBYTE)dst, &len ); dst[-1] = '\\'; if( *dst == '\\' || *dst == '\0' ) { *dst = '\0'; } else { while( *dst != '\0' ) { ++dst; } *dst++ = '\\'; } } strcpy( dst, src ); dst = UtilBuff + strlen( UtilBuff ) + 1; cmd_tail = dst; strcpy( dst, full_args ); dst += strlen( dst ); *++dst = '\0'; /* Need two nulls at end */ LoadProg( UtilBuff, cmd_tail ); Output( MsgArray[MSG_SAMPLE_1 - ERR_FIRST_MESSAGE] ); Output( UtilBuff ); Output( "\r\n" ); Buff.pid = Pid; Buff.tid = 1; Buff.cmd = PT_CMD_STOP; LibLoadPTrace( &Buff ); if( OSVer < 0x1400 ) { /* OS/2 2.x already dumped out MainMod as a Module load */ CodeLoad( &Buff, MainMod, ExeName, SAMP_MAIN_LOAD ); } InitialCS = Buff.u.r.CS; rc = DosCreateThread( Sleeper, (PUSHORT)&tid, Stack + STACK_SIZE ); if( rc != 0 ) { InternalError( MsgArray[MSG_SAMPLE_4 - ERR_FIRST_MESSAGE] ); } rc = DosSetPrty( PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, tid ); if( rc != 0 ) { InternalError( MsgArray[MSG_SAMPLE_5 - ERR_FIRST_MESSAGE] ); } Buff.pid = Pid; Buff.tid = 1; for( ;; ) { Buff.cmd = PT_CMD_GO; if( LibLoadPTrace( &Buff ) != 0 ) { InternalError( MsgArray[MSG_SAMPLE_7 - ERR_FIRST_MESSAGE] ); } if( Buff.cmd == PT_RET_BREAK && Buff.u.r.DX != 0 ) { /* a mark */ len = 0; Buff.segv = Buff.u.r.DX; Buff.offv = Buff.u.r.AX; for( ;; ) { Buff.cmd = PT_CMD_READ_MEM_D; DosPTrace( &Buff ); buff[len] = Buff.value; if( Buff.cmd != PT_RET_SUCCESS ) buff[len] = '\0'; if( len == BSIZE ) buff[len] = '\0'; if( buff[len] == '\0' ) break; ++len; Buff.offv++; } where.segment = Buff.u.r.CS; where.offset = Buff.u.r.IP; WriteMark( buff, where ); Buff.cmd = PT_CMD_READ_REGS; DosPTrace( &Buff ); Buff.u.r.IP++; Buff.cmd = PT_CMD_WRITE_REGS; DosPTrace( &Buff ); continue; } else if( Buff.cmd == PT_RET_BREAK ) { /* common info pass */ CommonAddr.segment = Buff.u.r.CX; CommonAddr.offset = Buff.u.r.BX; Buff.cmd = PT_CMD_READ_REGS; DosPTrace( &Buff ); Buff.u.r.IP++; Buff.cmd = PT_CMD_WRITE_REGS; DosPTrace( &Buff ); continue; } if( Buff.cmd == PT_RET_FUNERAL ) break; if( Buff.cmd != PT_RET_LIB_LOADED && Buff.cmd != PT_RET_STOPPED && Buff.cmd != PT_RET_TRD_TERMINATE ) { InternalError( MsgArray[MSG_SAMPLE_6 - ERR_FIRST_MESSAGE] ); break; } RecordSample( Buff.u.r.IP, Buff.u.r.CS, Buff.tid ); } report(); }