コード例 #1
1
bool handle_wait(pid_t pid, int status, int count, int *continued, int *terminated)
{
	unsigned int alarm_remaining_sec = waitproc_flags_test(WAITPROC_FLAG_ALARMSET) ? alarm(0) : 0;

	if (pid != -1) {
		struct flagged_int *p = get_flagged_int(&waitproc_options.pids, pid);
		assert(p);

		if (WIFSTOPPED(status)) {
			long r = WSTOPSIG(status);
			assert(p->valid);
			switch (r) {
				case SIGSTOP:
					if (p->state == STATE_ATTACHED) {
						p->state = STATE_CONTINUED;
						r = 0;
						assert(*continued < count);
						if (++(*continued) == count)
							set_alarm();
					} else {
						r = SIGCONT;
					}
					break;

				case SIGTSTP:
					r = SIGCONT;
					break;

				default:
					// forward the signal
					break;
			}
			if (r >= 0) {
				assert(p->state >= STATE_ATTACHED);
				r = ptrace(PTRACE_CONT, pid, 0, r);
				assert(r == 0);
			}
		} else if (WIFEXITED(status) || WIFSIGNALED(status)) {
			assert(p->valid && p->state < STATE_TERMINATED);
			p->state = STATE_TERMINATED;
			p->valid = false;
			print_terminated_process(pid);
			if (++(*terminated) == count)
				return false;
		}
	} else switch (errno) {
		case EINTR:
			if (waitproc_options.last_signal == SIGALRM) {
				waitproc_options.last_signal = SIGINVALID;
				if (DEBUG || !alarm_remaining_sec)
					return false;
			} else {
				fputs("Interrupted by unexpected signal\n", stderr);
				UNEXPECTED_STATE();
			}
			break;

		case ECHILD:
			*terminated = count;
			return false;

		default:
			UNEXPECTED_STATE();
			break;
	}

	assert(*terminated < count);

	if (alarm_remaining_sec)
		alarm(alarm_remaining_sec);

	return true;
}
コード例 #2
0
ファイル: main.cpp プロジェクト: andigor/test-sqlite-caching
void trace(pid_t child, std::vector<std::string>& files, std::mutex & mutex)
{
  waitpid(-1, NULL, __WALL);

  ptrace(PTRACE_ATTACH, child, 0, 0);
  ptrace(PTRACE_SETOPTIONS, child, NULL, PTRACE_O_TRACEFORK 
                                       | PTRACE_O_TRACEVFORK 
                                       | PTRACE_O_TRACECLONE 
                                       | PTRACE_O_TRACEEXIT 
                                       | PTRACE_O_EXITKILL);

  pid_t pid = child;
  while (true) {
    int status;

    ptrace(PTRACE_SYSCALL, pid, 0, 0);
    pid = waitpid(-1, &status, __WALL);

    if(WIFEXITED(status))
    { 
      break;
    }
    else if (WIFSTOPPED(status))
    {   
        struct user_regs_struct regs;
        ptrace(PTRACE_GETREGS, pid, 0, &regs);
        struct regs {
#ifdef __x86_64__
          unsigned long 
#endif
          long
            err, 
            syscall, 
            arg0;
        } regs_ = { 
#ifdef __x86_64__
          regs.rax, regs.orig_rax, regs.rdi
#else
          regs.eax, regs.orig_eax, regs.ebx
#endif
        };
        if (regs_.err == (unsigned long)-ENOSYS) { //syscall_enter stop
          if (regs_.syscall == __NR_open) {
            std::string file_name;
            long word = ptrace(PTRACE_PEEKDATA, pid, regs_.arg0, NULL);
            char * tmp = (char *)&word;
            while (*tmp != '\0') {
              file_name.push_back(*tmp);
              ++tmp;
              if (tmp == (char *)(&word + 1)) {
                regs_.arg0 += sizeof(word);
                word = ptrace(PTRACE_PEEKDATA, pid, regs_.arg0, NULL);
                tmp = (char *)&word;
              }
            }
            {
              std::lock_guard<std::mutex> l(mutex);
              files.push_back(file_name);
            }
          }
        }
        else { //syscall_exit stop
        }
    }
  }
}
コード例 #3
0
int restore_fpx_registers(int pid, unsigned long *fp_regs)
{
	if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0)
		return -errno;
	return 0;
}
コード例 #4
0
ファイル: ps_proc.c プロジェクト: EqualInformation/openjdk-8
// fill in ptrace_lwpinfo for lid
static bool process_get_lwp_info(struct ps_prochandle *ph, lwpid_t lwp_id, void *linfo) {
  errno = 0;
  ptrace(PT_LWPINFO, lwp_id, linfo, sizeof(struct ptrace_lwpinfo));

  return (errno == 0)? true: false;
}
コード例 #5
0
ファイル: sys.c プロジェクト: smillaedler/rr
/**
 * Detaches the child process from monitoring. This method must only be
 * invoked, if the thread exits. We do not check errors here, since the
 * thread could have already exited.
 */
void sys_ptrace_detach(pid_t pid)
{
	ptrace(PTRACE_DETACH, pid, 0, 0);
}
コード例 #6
0
static void trace_me () {
#if __APPLE__
	signal (SIGTRAP, SIG_IGN); //NEED BY STEP
#endif
#if __APPLE__ || __BSD__
/* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */
	signal (SIGABRT, inferior_abort_handler);
	if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) {
#else
	if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) {
#endif
		r_sys_perror ("ptrace-traceme");
		exit (MAGIC_EXIT);
	}
}

// __UNIX__ (not windows)
static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) {
	bool runprofile = io->runprofile && *(io->runprofile);
	char **argv;
#if __APPLE__ && !__POWERPC__
	if (!runprofile) {
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
		posix_spawn_file_actions_t fileActions;
		ut32 ps_flags = POSIX_SPAWN_SETSIGDEF |
				POSIX_SPAWN_SETSIGMASK;
   		sigset_t no_signals;
    		sigset_t all_signals;
    		sigemptyset (&no_signals);
    		sigfillset (&all_signals);
		posix_spawnattr_t attr = {0};
		size_t copied = 1;
		cpu_type_t cpu;
		pid_t p = -1;
		int ret, useASLR = io->aslr;
		char *_cmd = io->args ?
				r_str_concatf (strdup (cmd), " %s", io->args) :
				strdup (cmd);
		argv = r_str_argv (_cmd, NULL);
		if (!argv) {
			free (_cmd);
			return -1;
		}
		if (!*argv) {
			r_str_argv_free (argv);
			free (_cmd);
			eprintf ("Invalid execvp\n");
			return -1;
		}
		posix_spawnattr_init (&attr);
		if (useASLR != -1) {
			if (!useASLR) ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
		}

		posix_spawn_file_actions_init (&fileActions);
		posix_spawn_file_actions_addinherit_np (&fileActions, STDIN_FILENO);
		posix_spawn_file_actions_addinherit_np (&fileActions, STDOUT_FILENO);
		posix_spawn_file_actions_addinherit_np (&fileActions, STDERR_FILENO);
		ps_flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
		ps_flags |= POSIX_SPAWN_START_SUSPENDED;

   		posix_spawnattr_setsigmask(&attr, &no_signals);
    		posix_spawnattr_setsigdefault(&attr, &all_signals);

		(void)posix_spawnattr_setflags (&attr, ps_flags);
#if __i386__ || __x86_64__
		cpu = CPU_TYPE_I386;
		if (bits == 64) cpu |= CPU_ARCH_ABI64;
#else
		cpu = CPU_TYPE_ANY;
#endif
		posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &copied);
		{
			char *dst = r_file_readlink (argv[0]);
			if (dst) {
				argv[0] = dst;
			}
		}
		ret = posix_spawnp (&p, argv[0], &fileActions, &attr, argv, NULL);
		switch (ret) {
		case 0:
			// eprintf ("Success\n");
			break;
		case 22:
			eprintf ("posix_spawnp: Invalid argument\n");
			break;
		case 86:
			eprintf ("Unsupported architecture\n");
			break;
		default:
			eprintf ("posix_spawnp: unknown error %d\n", ret);
			perror ("posix_spawnp");
			break;
		}
		posix_spawn_file_actions_destroy (&fileActions);
		r_str_argv_free (argv);
		free (_cmd);
		return p;
	}
#endif
	int ret, status, child_pid;

	child_pid = r_sys_fork ();
	switch (child_pid) {
	case -1:
		perror ("fork_and_ptraceme");
		break;
	case 0:
		if (runprofile) {
			char *expr = NULL;
			int i;
			RRunProfile *rp = r_run_new (NULL);
			argv = r_str_argv (cmd, NULL);
			for (i = 0; argv[i]; i++) {
				rp->_args[i] = argv[i];
			}
			rp->_args[i] = NULL;
			rp->_program = argv[0];
			rp->_dodebug = true;
			if (io->runprofile && *io->runprofile) {
				if (!r_run_parsefile (rp, io->runprofile)) {
					eprintf ("Can't find profile '%s'\n",
						io->runprofile);
					exit (MAGIC_EXIT);
				}
			}
			if (bits == 64)
				r_run_parseline (rp, expr=strdup ("bits=64"));
			else if (bits == 32)
				r_run_parseline (rp, expr=strdup ("bits=32"));
			free (expr);
			if (r_run_config_env (rp)) {
				eprintf ("Can't config the environment.\n");
				exit (1);
			}
			trace_me ();
			r_run_start (rp);
			r_run_free (rp);
			r_str_argv_free (argv);
			exit (1);
		} else {
			char *_cmd = io->args ?
				r_str_concatf (strdup (cmd), " %s", io->args) :
				strdup (cmd);

			trace_me ();
			argv = r_str_argv (_cmd, NULL);
			if (!argv) {
				free (_cmd);
				return -1;
			}
			if (argv && *argv) {
				int i;
				for (i = 3; i < 1024; i++)
					(void)close (i);
				execvp (argv[0], argv);
			} else {
				eprintf ("Invalid execvp\n");
			}
			r_str_argv_free (argv);
			free (_cmd);
		}
		perror ("fork_and_attach: execv");
		//printf(stderr, "[%d] %s execv failed.\n", getpid(), ps.filename);
		exit (MAGIC_EXIT); /* error */
		return 0; // invalid pid // if exit is overriden.. :)
	default:
		/* XXX: clean this dirty code */
		do {
			ret = wait (&status);
			if (ret == -1) return -1;
			if (ret != child_pid) {
				eprintf ("Wait event received by "
					"different pid %d\n", ret);
			}
		} while (ret != child_pid);
		if (WIFSTOPPED (status)) {
			eprintf ("Process with PID %d started...\n", (int)child_pid);
		}
		if (WEXITSTATUS (status) == MAGIC_EXIT) {
			child_pid = -1;
		}
		// XXX kill (pid, SIGSTOP);
		break;
	}
	return child_pid;
}
コード例 #7
0
ファイル: amd64-linux32.c プロジェクト: Alkzndr/freebsd
long
amd64_linux32_syscall_exit(struct trussinfo *trussinfo,
    int syscall_num __unused)
{
	struct reg regs;
	struct linux_syscall *fsc;
	struct syscall *sc;
	lwpid_t tid;
	long retval;
	int errorp, i;

	if (trussinfo->curthread->fsc == NULL)
		return (-1);

	tid = trussinfo->curthread->tid;

	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
		return (-1);
	}

	retval = regs.r_rax;
	errorp = !!(regs.r_rflags & PSL_C);

	/*
	 * This code, while simpler than the initial versions I used, could
	 * stand some significant cleaning.
	 */

	fsc = trussinfo->curthread->fsc;
	sc = fsc->sc;
	if (!sc) {
		for (i = 0; i < fsc->nargs; i++)
			asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]);
	} else {
		/*
		 * Here, we only look for arguments that have OUT masked in --
		 * otherwise, they were handled in the syscall_entry function.
		 */
		for (i = 0; i < sc->nargs; i++) {
			char *temp;
			if (sc->args[i].type & OUT) {
				/*
				 * If an error occurred, then don't bother
				 * getting the data; it may not be valid.
				 */
				if (errorp) {
					asprintf(&temp, "0x%lx",
					    fsc->args[sc->args[i].offset]);
				} else {
					temp = print_arg(&sc->args[i],
					    fsc->args, retval, trussinfo);
				}
				fsc->s_args[i] = temp;
			}
		}
	}

	/*
	 * It would probably be a good idea to merge the error handling,
	 * but that complicates things considerably.
	 */
	if (errorp) {
		for (i = 0;
		    (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++) {
			if (retval == bsd_to_linux_errno[i])
				break;
		}
	}

	if (fsc->name != NULL && (strcmp(fsc->name, "linux_execve") == 0 ||
	    strcmp(fsc->name, "exit") == 0))
		trussinfo->curthread->in_syscall = 1;

	print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp,
	    errorp ? i : retval, fsc->sc);
	free_fsc(fsc);

	return (retval);
}
コード例 #8
0
ファイル: powerpc64-fbsd.c プロジェクト: edgar-pek/PerspicuOS
void
powerpc64_syscall_entry(struct trussinfo *trussinfo, int nargs) {
  char buf[32];
  struct reg regs;
  void *args;
  int syscall_num;
  int i;
  unsigned int regargs;
  struct syscall *sc;

  cpid = trussinfo->curthread->tid;

  clear_fsc();
  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
    fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
    return;
  }

  /*
   * FreeBSD has two special kinds of system call redirctions --
   * SYS_syscall, and SYS___syscall.  The former is the old syscall()
   * routine, basically; the latter is for quad-aligned arguments.
   */
  regargs = NARGREG;
  syscall_num = regs.fixreg[0];
  args = &regs.fixreg[3];
  if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) {
    args = &regs.fixreg[4];
    regargs -= 1;
    syscall_num = regs.fixreg[3];
  }

  fsc.number = syscall_num;
  fsc.name =
    (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num];
  if (!fsc.name) {
    fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
  }

  if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
   && ((!strcmp(fsc.name, "fork")
    || !strcmp(fsc.name, "rfork")
    || !strcmp(fsc.name, "vfork"))))
  {
    trussinfo->curthread->in_fork = 1;
  }

  if (nargs == 0)
    return;

  fsc.args = malloc((1+nargs) * sizeof(unsigned long));

  if (nargs > regargs) {
    struct ptrace_io_desc iorequest;
    memmove(&fsc.args[0], args, regargs * sizeof(fsc.args[0]));

    iorequest.piod_op = PIOD_READ_D;
    iorequest.piod_offs = (void *)(regs.fixreg[1] + 48);
    iorequest.piod_addr = &fsc.args[regargs];
    iorequest.piod_len = (nargs - regargs) * sizeof(fsc.args[0]);
    ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0);
    if (iorequest.piod_len == 0)
       return;
  } else {
    memmove(&fsc.args[0], args, nargs * sizeof(fsc.args[0]));
  }

  sc = get_syscall(fsc.name);
  if (sc) {
    fsc.nargs = sc->nargs;
  } else {
#if DEBUG
    fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n",
	   fsc.name, nargs);
#endif
    fsc.nargs = nargs;
  }

  fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*));
  fsc.sc = sc;

  /*
   * At this point, we set up the system call arguments.
   * We ignore any OUT ones, however -- those are arguments that
   * are set by the system call, and so are probably meaningless
   * now.  This doesn't currently support arguments that are
   * passed in *and* out, however.
   */

  if (fsc.name) {

#if DEBUG
    fprintf(stderr, "syscall %s(", fsc.name);
#endif
    for (i = 0; i < fsc.nargs; i++) {
#if DEBUG
      fprintf(stderr, "0x%x%s",
	      sc
	      ? fsc.args[sc->args[i].offset]
	      : fsc.args[i],
	      i < (fsc.nargs - 1) ? "," : "");
#endif
      if (sc && !(sc->args[i].type & OUT)) {
	fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo);
      }
    }
#if DEBUG
    fprintf(stderr, ")\n");
#endif
  }

#if DEBUG
  fprintf(trussinfo->outfile, "\n");
#endif

  if (fsc.name && (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {

    /* XXX
     * This could be done in a more general
     * manner but it still wouldn't be very pretty.
     */
    if (!strcmp(fsc.name, "execve")) {
        if ((trussinfo->flags & EXECVEARGS) == 0)
          if (fsc.s_args[1]) {
            free(fsc.s_args[1]);
            fsc.s_args[1] = NULL;
          }
        if ((trussinfo->flags & EXECVEENVS) == 0)
          if (fsc.s_args[2]) {
            free(fsc.s_args[2]);
            fsc.s_args[2] = NULL;
          }
    }
  }

  return;
}
コード例 #9
0
ファイル: powerpc64-fbsd.c プロジェクト: edgar-pek/PerspicuOS
long
powerpc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
{
  struct reg regs;
  long retval;
  int i;
  int errorp;
  struct syscall *sc;

  if (fsc.name == NULL)
	return (-1);

  cpid = trussinfo->curthread->tid;

  if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0) {
    fprintf(trussinfo->outfile, "\n");
    return (-1);
  }
  retval = regs.fixreg[3];
  errorp = !!(regs.cr & 0x10000000);

  /*
   * This code, while simpler than the initial versions I used, could
   * stand some significant cleaning.
   */

  sc = fsc.sc;
  if (!sc) {
    for (i = 0; i < fsc.nargs; i++)
      asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]);
  } else {
    /*
     * Here, we only look for arguments that have OUT masked in --
     * otherwise, they were handled in the syscall_entry function.
     */
    for (i = 0; i < sc->nargs; i++) {
      char *temp;
      if (sc->args[i].type & OUT) {
	/*
	 * If an error occurred, than don't bothe getting the data;
	 * it may not be valid.
	 */
	if (errorp)
	  asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
	else
	  temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo);
	fsc.s_args[i] = temp;
      }
    }
  }

  if (fsc.name != NULL &&
      (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) {
	trussinfo->curthread->in_syscall = 1;
  }


  /*
   * It would probably be a good idea to merge the error handling,
   * but that complicates things considerably.
   */

  print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp,
		    retval, fsc.sc);
  clear_fsc();

  return (retval);
}
コード例 #10
0
ファイル: ptdebug_x64.cpp プロジェクト: aurpine/DMOJ-judge
void pt_debugger_x64::poke_reg(int reg, long data) {
    ptrace(PTRACE_POKEUSER, process->getpid(), 8 * reg, data);
}
コード例 #11
0
ファイル: ghd.cpp プロジェクト: blitzcode/ghc-stack
void PTraceContinue(pid_t pid)
{
    // Child process stopped after signalling us, let it proceed
    ptrace(PT_CONTINUE, pid, (caddr_t) 1, 0);
}
コード例 #12
0
ファイル: ptdebug_x64.cpp プロジェクト: aurpine/DMOJ-judge
long pt_debugger_x64::peek_reg(int reg) {
    return ptrace(PTRACE_PEEKUSER, process->getpid(), 8 * reg, NULL);
}
コード例 #13
0
ファイル: arm-fbsd.c プロジェクト: coyizumi/cs111
void
arm_syscall_entry(struct trussinfo *trussinfo, int nargs)
{
	struct ptrace_io_desc iorequest;
	struct reg regs;
	struct freebsd_syscall *fsc;
	struct syscall *sc;
	lwpid_t tid;
	int i, syscall_num;
	register_t *ap;

	tid = trussinfo->curthread->tid;

	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
		return;
	}
	ap = &regs.r[0];

	/*
	 * FreeBSD has two special kinds of system call redirctions --
	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
	 * routine, basically; the latter is for quad-aligned arguments.
	 */
#ifdef __ARM_EABI__
	syscall_num = regs.r[7];
#else
	if ((syscall_num = ptrace(PT_READ_I, tid, 
	    (caddr_t)(regs.r[_REG_PC] - INSN_SIZE), 0)) == -1) {
		fprintf(trussinfo->outfile, "-- CANNOT READ PC --\n");
		return;
	}
	syscall_num = syscall_num & 0x000fffff;
#endif
	switch (syscall_num) {
	case SYS_syscall:
		syscall_num = *ap++;
		nargs--;
		break;
	case SYS___syscall:
		syscall_num = ap[_QUAD_LOWWORD];
		ap += 2;
		nargs -= 2;
		break;
	}

	fsc = alloc_fsc();
	if (fsc == NULL)
		return;
	fsc->number = syscall_num;
	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
	    NULL : syscallnames[syscall_num];
	if (!fsc->name) {
		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
		    syscall_num);
	}

	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
	    (strcmp(fsc->name, "fork") == 0 ||
	    strcmp(fsc->name, "rfork") == 0 ||
	    strcmp(fsc->name, "vfork") == 0))
		trussinfo->curthread->in_fork = 1;

	if (nargs == 0)
		return;

	fsc->args = malloc((1 + nargs) * sizeof(unsigned long));
	switch (nargs) {
	default:
		/*
		 * The OS doesn't seem to allow more than 10 words of
		 * parameters (yay!).	So we shouldn't be here.
		 */
		warn("More than 10 words (%d) of arguments!\n", nargs);
		break;
	case 10:
	case 9:
	case 8:
	case 7:
	case 6:
	case 5:
		/*
		 * If there are 7-10 words of arguments, they are placed
		 * on the stack, as is normal for other processors.
		 * The fall-through for all of these is deliberate!!!
		 */
		// XXX BAD constant used here
		iorequest.piod_op = PIOD_READ_D;
		iorequest.piod_offs = (void *)(regs.r[_REG_SP] +
		    4 * sizeof(uint32_t));
		iorequest.piod_addr = &fsc->args[4];
		iorequest.piod_len = (nargs - 4) * sizeof(fsc->args[0]);
		ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
		if (iorequest.piod_len == 0)
			return;
	case 4:	fsc->args[3] = ap[3];
	case 3:	fsc->args[2] = ap[2];
	case 2:	fsc->args[1] = ap[1];
	case 1:	fsc->args[0] = ap[0];
	case 0: break;
	}

	sc = NULL;
	if (fsc->name)
		sc = get_syscall(fsc->name);
	if (sc)
		fsc->nargs = sc->nargs;
	else {
#if DEBUG
		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
		    "args to %d\n", fsc->name, nargs);
#endif
		fsc->nargs = nargs;
	}

	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
	fsc->sc = sc;

	/*
	 * At this point, we set up the system call arguments.
	 * We ignore any OUT ones, however -- those are arguments that
	 * are set by the system call, and so are probably meaningless
	 * now.	This doesn't currently support arguments that are
	 * passed in *and* out, however.
	 */

	if (fsc->name) {
#if DEBUG
		fprintf(stderr, "syscall %s(", fsc->name);
#endif
		for (i = 0; i < fsc->nargs; i++) {
#if DEBUG
			fprintf(stderr, "0x%x%s", sc ?
			    fsc->args[sc->args[i].offset] : fsc->args[i],
			    i < (fsc->nargs - 1) ? "," : "");
#endif
			if (sc && !(sc->args[i].type & OUT)) {
				fsc->s_args[i] = print_arg(&sc->args[i],
				    fsc->args, 0, trussinfo);
			}
		}
#if DEBUG
		fprintf(stderr, ")\n");
#endif
	}

#if DEBUG
	fprintf(trussinfo->outfile, "\n");
#endif

	if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 ||
	    strcmp(fsc->name, "exit") == 0)) {
		/*
		 * XXX
		 * This could be done in a more general
		 * manner but it still wouldn't be very pretty.
		 */
		if (strcmp(fsc->name, "execve") == 0) {
			if ((trussinfo->flags & EXECVEARGS) == 0) {
				if (fsc->s_args[1]) {
					free(fsc->s_args[1]);
					fsc->s_args[1] = NULL;
				}
			}
			if ((trussinfo->flags & EXECVEENVS) == 0) {
				if (fsc->s_args[2]) {
					free(fsc->s_args[2]);
					fsc->s_args[2] = NULL;
				}
			}
		}
	}
	trussinfo->curthread->fsc = fsc;
}
コード例 #14
0
ファイル: ptx4-nat.c プロジェクト: jichu4n/prc-tools-remix
/* this could use elf_interpreter() from elfread.c */
int
proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
{
  vaddr_t curseg, memptr;
  pt_vseg_t pv;
  int rv, cmperr;
  sec_ptr interp_sec;
  char *interp_content;
  int interp_fd, funcstat;
  unsigned int size;
  char buf1[NBPG], buf2[NBPG];

  /*
   * The following is really vile.  We can get the name of the
   * shared library from the exec_bfd, and we can get a list of
   * each virtual memory segment, but there is no simple way to
   * find the mapped segment from the shared library (ala
   * procfs's PIOCOPENMEM).  As a pretty nasty kludge, we
   * compare the virtual memory segment to the contents of the
   * .interp file.  If they match, we assume that we've got the
   * right one.
   */

  /*
   * TODO: for attach, use XPT_OPENT to get the executable, in
   * case we're attached without knowning the executable's
   * filename.
   */

#ifdef VERBOSE_DEBUG
  printf ("proc_iter\n");
#endif
  interp_sec = bfd_get_section_by_name (exec_bfd, ".interp");
  if (!interp_sec)
    {
      return 0;
    }

  size = bfd_section_size (exec_bfd, interp_sec);
  interp_content = alloca (size);
  if (0 == bfd_get_section_contents (exec_bfd, interp_sec,
				     interp_content, (file_ptr) 0, size))
    {
      return 0;
    }

#ifdef VERBOSE_DEBUG
  printf ("proc_iter: \"%s\"\n", interp_content);
#endif
  interp_fd = open (interp_content, O_RDONLY, 0);
  if (-1 == interp_fd)
    {
      return 0;
    }

  curseg = 0;
  while (1)
    {
      rv = ptrace (PT_NEXT_VSEG, PIDGET (inferior_ptid), &pv, curseg);
#ifdef VERBOSE_DEBUG
      printf ("PT_NEXT_VSEG: rv %d errno %d\n", rv, errno);
#endif
      if (-1 == rv)
	break;
      if (0 == rv)
	break;
#ifdef VERBOSE_DEBUG
      printf ("pv.pv_start 0x%x pv_size 0x%x pv_prot 0x%x\n",
	      pv.pv_start, pv.pv_size, pv.pv_prot);
#endif
      curseg = pv.pv_start + pv.pv_size;

      rv = lseek (interp_fd, 0, SEEK_SET);
      if (-1 == rv)
	{
	  perror ("lseek");
	  close (interp_fd);
	  return 0;
	}
      for (memptr = pv.pv_start; memptr < pv.pv_start + pv.pv_size;
	   memptr += NBPG)
	{
#ifdef VERBOSE_DEBUG
	  printf ("memptr 0x%x\n", memptr);
#endif
	  rv = read (interp_fd, buf1, NBPG);
	  if (-1 == rv)
	    {
	      perror ("read");
	      close (interp_fd);
	      return 0;
	    }
	  rv = ptrace (PT_RDATA_PAGE, PIDGET (inferior_ptid), buf2,
		       memptr);
	  if (-1 == rv)
	    {
	      perror ("ptrace");
	      close (interp_fd);
	      return 0;
	    }
	  cmperr = memcmp (buf1, buf2, NBPG);
	  if (cmperr)
	    break;
	}
      if (0 == cmperr)
	{
	  /* this is it */
	  funcstat = (*func) (interp_fd, pv.pv_start);
	  break;
	}
    }
  close (interp_fd);
  return 0;
}
コード例 #15
0
ファイル: regs.c プロジェクト: KapJlcoH/ltrace
void
set_return_addr(Process *proc, void *addr) {
	ptrace(PTRACE_POKETEXT, proc->pid, proc->stack_pointer, addr);
}
コード例 #16
0
unsigned ReqProg_load( void )
{
    char                        **args;
    char                        *parms;
    char                        *parm_start;
    int                         i;
    char                        exe_name[PATH_MAX];
    char                        *name;
    pid_t                       save_pgrp;
    prog_load_req               *acc;
    prog_load_ret               *ret;
    unsigned                    len;
    int                         status;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );

    last_sig = -1;
    have_rdebug = FALSE;
    dbg_dyn = NULL;
    at_end = FALSE;
    parms = (char *)GetInPtr( sizeof( *acc ) );
    parm_start = parms;
    len = GetTotalSize() - sizeof( *acc );
    if( acc->true_argv ) {
        i = 1;
        for( ;; ) {
            if( len == 0 ) break;
            if( *parms == '\0' ) {
                i++;
            }
            ++parms;
            --len;
        }
        args = alloca( i * sizeof( *args ) );
        parms = parm_start;
        len = GetTotalSize() - sizeof( *acc );
        i = 1;
        for( ;; ) {
            if( len == 0 ) break;
            if( *parms == '\0' ) {
                args[i++] = parms + 1;
            }
            ++parms;
            --len;
        }
        args[i - 1] = NULL;
    } else {
        while( *parms != '\0' ) {
            ++parms;
            --len;
        }
        ++parms;
        --len;
        i = SplitParms( parms, NULL, len );
        args = alloca( (i + 2)  * sizeof( *args ) );
        args[SplitParms( parms, &args[1], len ) + 1] = NULL;
    }
    args[0] = parm_start;
    attached = TRUE;
    pid = RunningProc( args[0], &name );
    if( pid == 0 || ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) {
        attached = FALSE;
        args[0] = name;
        if( FindFilePath( TRUE, args[0], exe_name ) == 0 ) {
            exe_name[0] = '\0';
        }
        save_pgrp = getpgrp();
        setpgid( 0, OrigPGrp );
        pid = fork();
        if( pid == -1 )
            return( 0 );
        if( pid == 0 ) {
            if( ptrace( PTRACE_TRACEME, 0, NULL, NULL ) < 0 ) {
                exit( 1 );
            }
            execve( exe_name, (const char **)args, (const char **)dbg_environ );
            exit( 1 ); /* failsafe */
        }
        setpgid( 0, save_pgrp );
    } else if( pid ) {
        GetExeNameFromPid( pid, exe_name, PATH_MAX );
    }
    ret->flags = 0;
    ret->mod_handle = 0;
    if( (pid != -1) && (pid != 0) ) {
        int status;

        ret->task_id = pid;
        ret->flags |= LD_FLAG_IS_PROT | LD_FLAG_IS_32;
        /* 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 ) {
            ret->flags |= LD_FLAG_IS_STARTED;
            if( WSTOPSIG( status ) != SIGSTOP )
                goto fail;
        } else {
            if( WSTOPSIG( status ) != SIGTRAP )
                goto fail;
        }

#if defined( MD_x86 )
        if( !GetFlatSegs( &flatCS, &flatDS ) )
            goto fail;
#endif

        dbg_dyn = GetDebuggeeDynSection( exe_name );
        AddProcess();
        errno = 0;
    }
    ret->err = errno;
    if( ret->err != 0 ) {
        pid = 0;
    }
    CONV_LE_32( ret->err );
    CONV_LE_32( ret->task_id );
    CONV_LE_32( ret->mod_handle );
    return( sizeof( *ret ) );
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 );
        }
    }
    pid = 0;
    CONV_LE_32( ret->err );
    CONV_LE_32( ret->task_id );
    CONV_LE_32( ret->mod_handle );
    return( 0 );
}
コード例 #17
0
bool run_test(int cpu)
{
	int status;
	pid_t pid = fork();
	pid_t wpid;

	if (pid < 0) {
		ksft_print_msg("fork() failed: %s\n", strerror(errno));
		return false;
	}
	if (pid == 0)
		child(cpu);

	wpid = waitpid(pid, &status, __WALL);
	if (wpid != pid) {
		ksft_print_msg("waitpid() failed: %s\n", strerror(errno));
		return false;
	}
	if (!WIFSTOPPED(status)) {
		ksft_print_msg("child did not stop: %s\n", strerror(errno));
		return false;
	}
	if (WSTOPSIG(status) != SIGSTOP) {
		ksft_print_msg("child did not stop with SIGSTOP: %s\n",
			strerror(errno));
		return false;
	}

	if (ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL) < 0) {
		if (errno == EIO) {
			ksft_exit_skip(
				"ptrace(PTRACE_SINGLESTEP) not supported on this architecture: %s\n",
				strerror(errno));
		}
		ksft_print_msg("ptrace(PTRACE_SINGLESTEP) failed: %s\n",
			strerror(errno));
		return false;
	}

	wpid = waitpid(pid, &status, __WALL);
	if (wpid != pid) {
		ksft_print_msg("waitpid() failed: $s\n", strerror(errno));
		return false;
	}
	if (WIFEXITED(status)) {
		ksft_print_msg("child did not single-step: %s\n",
			strerror(errno));
		return false;
	}
	if (!WIFSTOPPED(status)) {
		ksft_print_msg("child did not stop: %s\n", strerror(errno));
		return false;
	}
	if (WSTOPSIG(status) != SIGTRAP) {
		ksft_print_msg("child did not stop with SIGTRAP: %s\n",
			strerror(errno));
		return false;
	}

	if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0) {
		ksft_print_msg("ptrace(PTRACE_CONT) failed: %s\n",
			strerror(errno));
		return false;
	}

	wpid = waitpid(pid, &status, __WALL);
	if (wpid != pid) {
		ksft_print_msg("waitpid() failed: %s\n", strerror(errno));
		return false;
	}
	if (!WIFEXITED(status)) {
		ksft_print_msg("child did not exit after PTRACE_CONT: %s\n",
			strerror(errno));
		return false;
	}

	return true;
}
コード例 #18
0
static unsigned ProgRun( int step )
{
    static int          ptrace_sig = 0;
    static int          ld_state = 0;
    user_regs_struct    regs;
    int                 status;
    prog_go_ret         *ret;
    void                (*old)(int);
    int                 debug_continue;

    if( pid == 0 )
        return( 0 );
    ret = GetOutPtr( 0 );

    if( at_end ) {
        ptrace_sig = 0;
        ret->conditions = COND_TERMINATE;
        goto end;
    }

    /* we only want child-generated SIGINTs now */
    do {
        old = setsig( SIGINT, SIG_IGN );
        if( step ) {
            Out( "PTRACE_SINGLESTEP\n" );
            if( ptrace( PTRACE_SINGLESTEP, pid, NULL, (void *)ptrace_sig ) == -1 )
                perror( "PTRACE_SINGLESTEP" );
        } else {
            Out( "PTRACE_CONT\n" );
            if( ptrace( PTRACE_CONT, pid, NULL, (void *)ptrace_sig ) == -1 )
                perror( "PTRACE_CONT" );
        }
        waitpid( pid, &status, 0 );
        setsig( SIGINT, old );

#if defined( MD_x86 )
        ptrace( PTRACE_GETREGS, pid, NULL, &regs );
#elif defined( MD_ppc )
        regs.eip = ptrace( PTRACE_PEEKUSER, pid, REGSIZE * PT_NIP, NULL );
        regs.esp = ptrace( PTRACE_PEEKUSER, pid, REGSIZE * PT_R1, NULL );
#elif defined( MD_mips )
        regs.eip = ptrace( PTRACE_PEEKUSER, pid, (void *)PC, NULL );
        regs.esp = ptrace( PTRACE_PEEKUSER, pid, (void *)29, NULL );
#endif
        Out( " eip " );
        OutNum( regs.eip );
        Out( "\n" );

        debug_continue = FALSE;
        if( WIFSTOPPED( status ) ) {
            switch( ( ptrace_sig = WSTOPSIG( status ) ) ) {
            case SIGSEGV:
            case SIGILL:
            case SIGFPE:
            case SIGABRT:
            case SIGBUS:
            case SIGQUIT:
            case SIGSYS:
                last_sig = ptrace_sig;
                ret->conditions = COND_EXCEPTION;
                ptrace_sig = 0;
                break;
            case SIGINT:
                ret->conditions = COND_USER;
                ptrace_sig = 0;
                break;
            case SIGTRAP:
                ret->conditions = step ? COND_TRACE : COND_BREAK;
                Out( "sigtrap\n" );
                ptrace_sig = 0;
                break;
            default:
                /* For signals that we do not wish to handle, we need
                 * to continue the debuggee until we get a signal
                 * that we need to handle
                 */
                Out( "Unknown signal " );
                OutNum( ptrace_sig );
                Out( "\n" );
                debug_continue = TRUE;
                break;
            }
        } else if( WIFEXITED( status ) ) {
            Out( "WIFEXITED\n" );
            at_end = TRUE;
            ret->conditions = COND_TERMINATE;
            ptrace_sig = 0;
            goto end;
        }
    } while( debug_continue );

    if( ret->conditions == COND_BREAK ) {
#if defined( MD_x86 )
        if( regs.eip == rdebug.r_brk + sizeof( old_ld_bp ) ) {
#elif defined( MD_ppc ) || defined( MD_mips )
        if( regs.eip == rdebug.r_brk ) {
#endif
            int         psig = 0;
            void        (*oldsig)(int);
            bp_t        opcode = BRK_POINT;

            /* The dynamic linker breakpoint was hit, meaning that
             * libraries are being loaded or unloaded. This gets a bit
             * tricky because we must restore the original code that was
             * at the breakpoint and execute it, but we still want to
             * keep the breakpoint.
             */
            WriteMem( pid, &old_ld_bp, rdebug.r_brk, sizeof( old_ld_bp ) );
            ReadMem( pid, &rdebug, (addr48_off)dbg_rdebug, sizeof( rdebug ) );
            Out( "ld breakpoint hit, state is " );
            switch( rdebug.r_state ) {
            case RT_ADD:
                Out( "RT_ADD\n" );
                ld_state = RT_ADD;
                AddOneLib( rdebug.r_map );
                break;
            case RT_DELETE:
                Out( "RT_DELETE\n" );
                ld_state = RT_DELETE;
                break;
            case RT_CONSISTENT:
                Out( "RT_CONSISTENT\n" );
                if( ld_state == RT_DELETE )
                    DelOneLib( rdebug.r_map );
                ld_state = RT_CONSISTENT;
                break;
            default:
                Out( "error!\n" );
                break;
            }
            regs.orig_eax = -1;
#if defined( MD_x86 )
            regs.eip--;
            ptrace( PTRACE_SETREGS, pid, NULL, &regs );
#endif
            oldsig = setsig( SIGINT, SIG_IGN );
            ptrace( PTRACE_SINGLESTEP, pid, NULL, (void *)psig );
            waitpid( pid, &status, 0 );
            setsig( SIGINT, oldsig );
            WriteMem( pid, &opcode, rdebug.r_brk, sizeof( old_ld_bp ) );
            ret->conditions = COND_LIBRARIES;
        } else {
#if defined( MD_x86 )
            Out( "decrease eip(sigtrap)\n" );
            regs.orig_eax = -1;
            regs.eip--;
            ptrace( PTRACE_SETREGS, pid, NULL, &regs );
#endif
        }
    }
    orig_eax = regs.orig_eax;
    last_eip = regs.eip;
    ret->program_counter.offset = regs.eip;
    ret->program_counter.segment = regs.cs;
    ret->stack_pointer.offset = regs.esp;
    ret->stack_pointer.segment = regs.ss;
    ret->conditions |= COND_CONFIG;

    /* If debuggee has dynamic section, try getting the r_debug struct
     * every time the debuggee stops. The r_debug data may not be available
     * immediately after the debuggee process loads.
     */
    if( !have_rdebug && (dbg_dyn != NULL) ) {
        if( Get_ld_info( pid, dbg_dyn, &rdebug, &dbg_rdebug ) ) {
            bp_t        opcode;

            AddInitialLibs( rdebug.r_map );
            have_rdebug = TRUE;
            ret->conditions |= COND_LIBRARIES;

            /* Set a breakpoint in dynamic linker. That way we can be
             * informed on dynamic library load/unload events.
             */
            ReadMem( pid, &old_ld_bp, rdebug.r_brk, sizeof( old_ld_bp ) );
            Out( "Setting ld breakpoint at " );
            OutNum( rdebug.r_brk );
            Out( " old opcode was " );
            OutNum( old_ld_bp );
            Out( "\n" );
            opcode = BRK_POINT;
            WriteMem( pid, &opcode, rdebug.r_brk, sizeof( opcode ) );
        }
    }
 end:
    CONV_LE_32( ret->stack_pointer.offset );
    CONV_LE_16( ret->stack_pointer.segment );
    CONV_LE_32( ret->program_counter.offset );
    CONV_LE_16( ret->program_counter.segment );
    CONV_LE_16( ret->conditions );
    return( sizeof( *ret ) );
}

unsigned ReqProg_step( void )
{
    return( ProgRun( TRUE ) );
}

unsigned ReqProg_go( void )
{
    return( ProgRun( FALSE ) );
}

unsigned ReqRedirect_stdin( void  )
{
    redirect_stdin_ret *ret;

    ret = GetOutPtr( 0 );
    ret->err = 1;
    return( sizeof( *ret ) );
}
コード例 #19
0
ファイル: amd64-linux32.c プロジェクト: Alkzndr/freebsd
void
amd64_linux32_syscall_entry(struct trussinfo *trussinfo, int nargs)
{
	struct reg regs;
	struct linux_syscall *fsc;
	struct syscall *sc;
	lwpid_t tid;
	int i, syscall_num;

	tid = trussinfo->curthread->tid;

	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
		return;
	}

	syscall_num = regs.r_rax;

	fsc = alloc_fsc();
	if (fsc == NULL)
		return;
	fsc->number = syscall_num;
	fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ?
	    NULL : linux32_syscallnames[syscall_num];
	if (!fsc->name) {
		fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n",
		    syscall_num);
	}

	if (fsc->name && (trussinfo->flags & FOLLOWFORKS) &&
	    (strcmp(fsc->name, "linux_fork") == 0 ||
	    strcmp(fsc->name, "linux_vfork") == 0))
		trussinfo->curthread->in_fork = 1;

	if (nargs == 0)
		return;

	/*
	 * Linux passes syscall arguments in registers, not
	 * on the stack.  Fortunately, we've got access to the
	 * register set.  Note that we don't bother checking the
	 * number of arguments.	And what does linux do for syscalls
	 * that have more than five arguments?
	 */

	fsc->args[0] = regs.r_rbx;
	fsc->args[1] = regs.r_rcx;
	fsc->args[2] = regs.r_rdx;
	fsc->args[3] = regs.r_rsi;
	fsc->args[4] = regs.r_rdi;

	sc = get_syscall(fsc->name);
	if (sc)
		fsc->nargs = sc->nargs;
	else {
#if DEBUG
		fprintf(trussinfo->outfile, "unknown syscall %s -- setting "
		    "args to %d\n", fsc->name, nargs);
#endif
		fsc->nargs = nargs;
	}

	fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *));
	fsc->sc = sc;

	/*
	 * At this point, we set up the system call arguments.
	 * We ignore any OUT ones, however -- those are arguments that
	 * are set by the system call, and so are probably meaningless
	 * now.	This doesn't currently support arguments that are
	 * passed in *and* out, however.
	 */

	if (fsc->name) {
#if DEBUG
		fprintf(stderr, "syscall %s(", fsc->name);
#endif
		for (i = 0; i < fsc->nargs; i++) {
#if DEBUG
			fprintf(stderr, "0x%x%s", sc ?
			    fsc->args[sc->args[i].offset] : fsc->args[i],
			    i < (fsc->nargs - 1) ? "," : "");
#endif
			if (sc && !(sc->args[i].type & OUT)) {
				fsc->s_args[i] = print_arg(&sc->args[i],
				    fsc->args, 0, trussinfo);
			}
		}
#if DEBUG
		fprintf(stderr, ")\n");
#endif
	}

#if DEBUG
	fprintf(trussinfo->outfile, "\n");
#endif

	if (fsc->name != NULL && (strcmp(fsc->name, "linux_execve") == 0 ||
	    strcmp(fsc->name, "exit") == 0)) {
		/*
		 * XXX
		 * This could be done in a more general
		 * manner but it still wouldn't be very pretty.
		 */
		if (strcmp(fsc->name, "linux_execve") == 0) {
			if ((trussinfo->flags & EXECVEARGS) == 0) {
				if (fsc->s_args[1]) {
					free(fsc->s_args[1]);
					fsc->s_args[1] = NULL;
				}
			}
			if ((trussinfo->flags & EXECVEENVS) == 0) {
				if (fsc->s_args[2]) {
					free(fsc->s_args[2]);
					fsc->s_args[2] = NULL;
				}
			}
		}
	}
	trussinfo->curthread->fsc = fsc;
}
コード例 #20
0
ファイル: linux-low.c プロジェクト: jichu4n/prc-tools-remix
static void
linux_resume_one_process (struct inferior_list_entry *entry,
			  int step, int signal)
{
  struct process_info *process = (struct process_info *) entry;
  struct thread_info *saved_inferior;

  if (process->stopped == 0)
    return;

  /* If we have pending signals or status, and a new signal, enqueue the
     signal.  Also enqueue the signal if we are waiting to reinsert a
     breakpoint; it will be picked up again below.  */
  if (signal != 0
      && (process->status_pending_p || process->pending_signals != NULL
	  || process->bp_reinsert != 0))
    {
      struct pending_signals *p_sig;
      p_sig = malloc (sizeof (*p_sig));
      p_sig->prev = process->pending_signals;
      p_sig->signal = signal;
      process->pending_signals = p_sig;
    }

  if (process->status_pending_p)
    return;

  saved_inferior = current_inferior;
  current_inferior = get_process_thread (process);

  if (debug_threads)
    fprintf (stderr, "Resuming process %d (%s, signal %d, stop %s)\n", inferior_pid,
	     step ? "step" : "continue", signal,
	     process->stop_expected ? "expected" : "not expected");

  /* This bit needs some thinking about.  If we get a signal that
     we must report while a single-step reinsert is still pending,
     we often end up resuming the thread.  It might be better to
     (ew) allow a stack of pending events; then we could be sure that
     the reinsert happened right away and not lose any signals.

     Making this stack would also shrink the window in which breakpoints are
     uninserted (see comment in linux_wait_for_process) but not enough for
     complete correctness, so it won't solve that problem.  It may be
     worthwhile just to solve this one, however.  */
  if (process->bp_reinsert != 0)
    {
      if (debug_threads)
	fprintf (stderr, "  pending reinsert at %08lx", (long)process->bp_reinsert);
      if (step == 0)
	fprintf (stderr, "BAD - reinserting but not stepping.\n");
      step = 1;

      /* Postpone any pending signal.  It was enqueued above.  */
      signal = 0;
    }

  check_removed_breakpoint (process);

  if (debug_threads && the_low_target.get_pc != NULL) 
    {
      fprintf (stderr, "  ");
      (long) (*the_low_target.get_pc) ();
    }

  /* If we have pending signals, consume one unless we are trying to reinsert
     a breakpoint.  */
  if (process->pending_signals != NULL && process->bp_reinsert == 0)
    {
      struct pending_signals **p_sig;

      p_sig = &process->pending_signals;
      while ((*p_sig)->prev != NULL)
	p_sig = &(*p_sig)->prev;

      signal = (*p_sig)->signal;
      free (*p_sig);
      *p_sig = NULL;
    }

  regcache_invalidate_one ((struct inferior_list_entry *)
			   get_process_thread (process));
  errno = 0;
  process->stopped = 0;
  process->stepping = step;
  ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, process->lwpid, 0, signal);

  current_inferior = saved_inferior;
  if (errno)
    perror_with_name ("ptrace");
}
コード例 #21
0
int main(int argc, char **argv) {

	int i;
	long page_size=getpagesize();
	double error;

	long long start_before,stop_after;

	void *addr[MAX_EVENTS],*addr2[MAX_EVENTS];

	struct perf_event_attr pe;

	int fd[MAX_EVENTS],fd2[MAX_EVENTS],ret1,ret2;
	int status;

	unsigned long long values[MAX_EVENTS],enabled[MAX_EVENTS],running[MAX_EVENTS];
	unsigned long long values2[MAX_EVENTS],enabled2[MAX_EVENTS],running2[MAX_EVENTS];

	int count=2;

	pid_t pid,pid2;

	quiet=test_quiet();

	if (!quiet) {
		printf("This test checks if rdpmc multi-attach works.\n\n");
	}

	/* See if we support rdpmc access */
	if (!detect_rdpmc(quiet)) {
		test_skip(test_string);
	}

	/*********************************/
	/* start and pause two children  */
	/*********************************/

	/* fork a child */
	pid = fork();
	if ( pid < 0 ) {
		fprintf(stderr,"Failed fork\n");
		test_fail(test_string);
	}
	else if (pid==0) {
		/* in child */
		exit(wait_for_attach_and_loop(1));
	}

	if ( ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) {
		fprintf(stderr,"Error attaching to %d\n",pid);
		return -1;
	}
	if ( waitpid( pid, &status, 0 ) == -1 ) {
		fprintf(stderr,"Error waitpid %d\n",pid);
		return -1;
	}
	if ( WIFSTOPPED( status ) == 0 ) {
		fprintf(stderr,"WIFSTOPPED didn't happen %d\n",pid);
		test_fail(test_string);
	}



	/* fork a second child */
	pid2 = fork();
	if ( pid2 < 0 ) {
		fprintf(stderr,"Failed fork\n");
		test_fail(test_string);
	}
	else if (pid2==0) {
		/* in child */
		exit(wait_for_attach_and_loop(2));
	}

	if ( ptrace( PTRACE_ATTACH, pid2, NULL, NULL ) == -1 ) {
		fprintf(stderr,"Error attaching to %d\n",pid2);
		return -1;
	}
	if ( waitpid( pid2, &status, 0 ) == -1 ) {
		fprintf(stderr,"Error waitpid %d\n",pid2);
		return -1;
	}
	if ( WIFSTOPPED( status ) == 0 ) {
		fprintf(stderr,"WIFSTOPPED didn't happen %d\n",pid2);
		test_fail(test_string);
	}



	/*****************************/
	/* TEST START/WORK/READ/STOP */
	/*****************************/

	/* Open event, pid1  */
	memset(&pe,0,sizeof(struct perf_event_attr));

	pe.type=PERF_TYPE_HARDWARE;
	pe.size=sizeof(struct perf_event_attr);

	fd[0]=-1;

	for(i=0;i<count;i++) {

		if (i==0) {
			pe.config=PERF_COUNT_HW_INSTRUCTIONS;
			pe.disabled=1;
			pe.pinned=1;
		}
		else {
			pe.config=PERF_COUNT_HW_CPU_CYCLES;
			pe.disabled=0;
			pe.pinned=0;
		}

		fd[i]=perf_event_open(&pe,pid,-1,fd[0],0);
		if (fd[i]<0) {
			fprintf(stderr,"Error opening event %d\n",i);
			test_fail(test_string);
		}

		/* mmap() event */
		addr[i]=mmap(NULL,page_size, PROT_READ, MAP_SHARED,fd[i],0);
		if (addr[i] == MAP_FAILED) {
			fprintf(stderr,"Error mmap()ing event %d!\n",i);
			test_fail(test_string);
		}
	}




	/* Open event, pid2  */
	memset(&pe,0,sizeof(struct perf_event_attr));

	pe.type=PERF_TYPE_HARDWARE;
	pe.size=sizeof(struct perf_event_attr);

	fd2[0]=-1;

	for(i=0;i<count;i++) {

		if (i==0) {
			pe.config=PERF_COUNT_HW_INSTRUCTIONS;
			pe.disabled=1;
			pe.pinned=1;
		}
		else {
			pe.config=PERF_COUNT_HW_CPU_CYCLES;
			pe.disabled=0;
			pe.pinned=0;
		}

		fd2[i]=perf_event_open(&pe,pid2,-1,fd2[0],0);
		if (fd2[i]<0) {
			fprintf(stderr,"Error opening event %d\n",i);
			test_fail(test_string);
		}

		/* mmap() event */
		addr2[i]=mmap(NULL,page_size, PROT_READ, MAP_SHARED,fd2[i],0);
		if (addr2[i] == MAP_FAILED) {
			fprintf(stderr,"Error mmap()ing event %d!\n",i);
			test_fail(test_string);
		}
	}


	/* start */
	start_before=rdtsc();
	ret1=ioctl(fd[0], PERF_EVENT_IOC_ENABLE,0);

	/* start up pid */
	if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
		fprintf(stderr,"Couldn't continue %d\n",pid);
		return -1;
	}
	if ( waitpid( pid, &status, 0 ) == -1 ) {
		fprintf(stderr,"Couldn't waitpid() %d\n",pid );
		return -1;
	}
	if ( WIFSTOPPED( status ) == 0 ) {
		test_fail(test_string);
	}
	if ( WSTOPSIG( status ) != SIGSTOP ) {
		test_fail(test_string);
	}


	ret1=ioctl(fd2[0], PERF_EVENT_IOC_ENABLE,0);

	/* start up pid2 */
	if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) {
		fprintf(stderr,"Couldn't continue %d\n",pid2);
		return -1;
	}
	if ( waitpid( pid2, &status, 0 ) == -1 ) {
		fprintf(stderr,"Couldn't waitpid() %d\n",pid2 );
		return -1;
	}
	if ( WIFSTOPPED( status ) == 0 ) {
		test_fail(test_string);
	}
	if ( WSTOPSIG( status ) != SIGSTOP ) {
		test_fail(test_string);
	}



	/* Wait for the SIGSTOP. */
	if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
              fprintf(stderr, "sigstop fail\n" );
              return -1;
	}

	if ( waitpid( pid, &status, 0 ) == -1 ) {
		fprintf(stderr, "waitpid() pid\n" );
		return -1;
	}
	if ( WIFSTOPPED( status ) == 0 ) {
              test_fail(test_string);
	}
	if ( WSTOPSIG( status ) != SIGSTOP ) {
              test_fail(test_string);
	}



	/* Wait for the SIGSTOP. */
	if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) {
              fprintf(stderr, "sigstop fail\n" );
              return -1;
	}

	if ( waitpid( pid2, &status, 0 ) == -1 ) {
		fprintf(stderr, "waitpid() pid\n" );
		return -1;
	}
	if ( WIFSTOPPED( status ) == 0 ) {
              test_fail(test_string);
	}
	if ( WSTOPSIG( status ) != SIGSTOP ) {
              test_fail(test_string);
	}


	/* read */
	for(i=0;i<count;i++) {
		values[i] = mmap_read_self(addr[i], &enabled[i], &running[i]);
	}

	/* stop */
	ret2=ioctl(fd[0], PERF_EVENT_IOC_DISABLE,0);
	ret2=ioctl(fd2[0], PERF_EVENT_IOC_DISABLE,0);

	for(i=0;i<count;i++) {
		values2[i] = mmap_read_self(addr2[i], &enabled2[i], &running2[i]);
	}

	stop_after=rdtsc();

	if (ret1<0) {
		fprintf(stderr,"Error starting!\n");
		test_fail(test_string);
	}

	if (ret2<0) {
		fprintf(stderr,"Error stopping!\n");
		test_fail(test_string);
	}

	if (values[0]<0) {
		if (!quiet) printf("rdpmc support not available.\n");
		test_yellow_no(test_string);
	}

	for(i=0;i<count;i++) {
		close(fd[i]);
		close(fd2[i]);
		munmap(addr[i],page_size);
		munmap(addr2[i],page_size);
	}

	if (!quiet) {
		printf("Trying attach: %lld cycles\n",
			stop_after-start_before);
		for(i=0;i<count;i++) {
			if (values[i]==-1) {
				printf("\t* RDPMC 1 Event %x -- rdpmc not supported\n",i);
			}
			else {
				printf("\t* RDPMC 1 Event %x -- count: %lld enabled %lld running: %lld\n",
					i,values[i],enabled[i],running[i]);
			}
		}
		for(i=0;i<count;i++) {
			if (values2[i]==-1) {
				printf("\t* RDPMC 2 Event %x -- rdpmc not supported\n",i);
			}
			else {
				printf("\t* RDPMC 2 Event %x -- count: %lld enabled %lld running: %lld\n",
					i,values2[i],enabled2[i],running2[i]);
			}

		}
	}

	if (!quiet) printf("\n");

	if ((values[0]!=-1) || (values2[0]!=-1)) {

		error=display_error(values[0],
					values[0],
					values[0],
					1000000ULL,quiet);

		if ((error>10.0) || ( error<-10.0)) {
			if (!quiet) printf("Error out of range!\n");
			test_fail(test_string);
		}

		error=display_error(values2[0],
					values2[0],
					values2[0],
					2000000ULL,quiet);

		if ((error>10.0) || ( error<-10.0)) {
			if (!quiet) printf("Error out of range!\n");
			test_fail(test_string);
		}

		if (!quiet) {
			printf("Should not have worked\n");
		}
		test_fail(test_string);
	}


	for(i=0;i<count;i++) {
		close(fd[i]);
		munmap(addr[i],page_size);
	}

	test_pass(test_string);

	return 0;
}
コード例 #22
0
ファイル: regs.c プロジェクト: KapJlcoH/ltrace
void *
get_instruction_pointer(Process *proc) {
	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_PC, 0);
}
コード例 #23
0
ファイル: sys.c プロジェクト: smillaedler/rr
void sys_ptrace_cont(pid_t pid)
{
	ptrace(PTRACE_CONT, pid, 0, 0);
}
コード例 #24
0
ファイル: regs.c プロジェクト: KapJlcoH/ltrace
void
set_instruction_pointer(Process *proc, void *addr) {
	ptrace(PTRACE_POKEUSER, proc->pid, 4 * PT_PC, addr);
}
コード例 #25
0
ファイル: shell.c プロジェクト: Estella/wraith
void check_trace(int start)
{
  if (trace == DET_IGNORE || trace == DET_WARN)
    trace = DET_DIE;
//    return;

#ifdef DEBUG
  trace = DET_IGNORE;
#endif /* DEBUG */

  if (trace == DET_IGNORE)
    return;

  pid_t parent = getpid();

  /* we send ourselves a SIGTRAP, if we recieve, we're not being traced, otherwise we are. */
  signal(SIGTRAP, got_sigtrap);
  traced = 1;
  raise(SIGTRAP);
  /* no longer need this__asm__("INT3"); //SIGTRAP */
  signal(SIGTRAP, SIG_DFL);

  if (!traced) {
    signal(SIGINT, got_sigtrap);
    traced = 1;
    raise(SIGINT);
    signal(SIGINT, SIG_DFL);
  }

  if (traced) {
    if (start) {
      kill(parent, SIGKILL);
      exit(1);
    } else
      detected(DETECT_TRACE, STR("I'm being traced!"));
  } else {
    if (!start)
      return;

#ifndef __sun__
    int x, i;

  /* now, let's attempt to ptrace ourself */
    switch ((x = fork())) {
      case -1:
        return;
      case 0:		//child
        i = ptrace(PT_ATTACH, parent, 0, 0);
        /* EPERM is given on fbsd when security.bsd.unprivileged_proc_debug=0 */
        if (i == -1 && errno != EPERM) {
          if (start) {
            kill(parent, SIGKILL);
            exit(1);
          } else
            detected(DETECT_TRACE, STR("I'm being traced!"));
        } else {
          waitpid(parent, NULL, 0);
          ptrace(PT_DETACH, parent, (char *) 1, 0);
          kill(parent, SIGCHLD);
        }
        exit(0);
      default:		//parent
        waitpid(x, NULL, 0);
    }
#endif
  }
}
コード例 #26
0
ファイル: regs.c プロジェクト: KapJlcoH/ltrace
void *
get_stack_pointer(Process *proc) {
	return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_USP, 0);
}
コード例 #27
0
ファイル: hashscan.c プロジェクト: RamJett/uthash
static void found(int fd, char* peer_sig, pid_t pid)
{
    UT_hash_table *tbl=NULL;
    UT_hash_bucket *bkts=NULL;
    UT_hash_handle hh;
    size_t i, bloom_len, bloom_bitlen,  bloom_on_bits=0,bloom_off_bits=0;
    char *peer_tbl, *peer_bloom_sig, *peer_bloom_nbits, *peer_bloombv_ptr,
         *peer_bloombv, *peer_bkts, *peer_key, *peer_hh, *key=NULL;
    const char *hash_fcn = NULL;
    unsigned char *bloombv=NULL;
    static int fileno=0;
    char keyfile[50];
    unsigned char bloom_nbits=0;
    int keyfd=-1, mode=S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
        hash_fcn_hits[NUM_HASH_FUNCS], hash_fcn_winner;
    unsigned max_chain=0;
    uint32_t bloomsig;
    int has_bloom_filter_fields = 0;

    for(i=0; i < NUM_HASH_FUNCS; i++) {
        hash_fcn_hits[i]=0;
    }

    if (getkeys) {
        snprintf(keyfile, sizeof(keyfile), "/tmp/%u-%u.key", (unsigned)pid,fileno++);
        if ( (keyfd = open(keyfile, O_WRONLY|O_CREAT|O_TRUNC, mode)) == -1) {
            fprintf(stderr, "can't open %s: %s\n", keyfile, strerror(errno));
            exit(-1);
        }
    }

    vv("found signature at peer %p\n", (void*)peer_sig);
    peer_tbl = tbl_from_sig_addr(peer_sig);
    vvv("reading table at peer %p\n", (void*)peer_tbl);

    if ( (tbl = (UT_hash_table*)malloc(sizeof(UT_hash_table))) == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(-1);
    }
#ifdef __FreeBSD__
    if (read_mem(tbl, pid, (void *)peer_tbl, sizeof(UT_hash_table)) != 0) {
#else
    if (read_mem(tbl, fd, (off_t)peer_tbl, sizeof(UT_hash_table)) != 0) {
#endif
        fprintf(stderr, "failed to read peer memory\n");
        goto done;
    }

    /* got the table. how about the buckets */
    peer_bkts = (char*)tbl->buckets;
    vvv("reading buckets at peer %p\n", (void*)peer_bkts);
    bkts = (UT_hash_bucket*)malloc(sizeof(UT_hash_bucket)*tbl->num_buckets);
    if (bkts == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(-1);
    }
#ifdef __FreeBSD__
    if (read_mem(bkts, pid, (void *)peer_bkts, sizeof(UT_hash_bucket)*tbl->num_buckets) != 0) {
#else
    if (read_mem(bkts, fd, (off_t)peer_bkts, sizeof(UT_hash_bucket)*tbl->num_buckets) != 0) {
#endif
        fprintf(stderr, "failed to read peer memory\n");
        goto done;
    }

    vvv("scanning %u peer buckets\n", tbl->num_buckets);
    for(i=0; i < tbl->num_buckets; i++) {
        vvv("bucket %u has %u items\n",  (unsigned)i, (unsigned)(bkts[i].count));
        if (bkts[i].count > max_chain) {
            max_chain = bkts[i].count;
        }
        if (bkts[i].expand_mult) {
            vvv("  bucket %u has expand_mult %u\n",  (unsigned)i, (unsigned)(bkts[i].expand_mult));
        }

        vvv("scanning bucket %u chain:\n",  (unsigned)i);
        peer_hh = (char*)bkts[i].hh_head;
        while(peer_hh) {
#ifdef __FreeBSD__
            if (read_mem(&hh, pid, (void *)peer_hh, sizeof(hh)) != 0) {
#else
            if (read_mem(&hh, fd, (off_t)peer_hh, sizeof(hh)) != 0) {
#endif
                fprintf(stderr, "failed to read peer memory\n");
                goto done;
            }
            if ((char*)hh.tbl != peer_tbl) {
                goto done;
            }
            peer_hh = (char*)hh.hh_next;
            peer_key = (char*)(hh.key);
            /* malloc space to read the key, and read it */
            if ( (key = (char*)malloc(sizeof(hh.keylen))) == NULL) {
                fprintf(stderr, "out of memory\n");
                exit(-1);
            }
#ifdef __FreeBSD__
            if (read_mem(key, pid, (void*)peer_key, hh.keylen) != 0) {
#else
            if (read_mem(key, fd, (off_t)peer_key, hh.keylen) != 0) {
#endif
                fprintf(stderr, "failed to read peer memory\n");
                goto done;
            }
            hash_fcn_hits[infer_hash_function(key,hh.keylen,hh.hashv)]++;
            /* write the key if requested */
            if (getkeys) {
                write(keyfd, &hh.keylen, sizeof(unsigned));
                write(keyfd, key, hh.keylen);
            }
            free(key);
            key=NULL;
        }
    }

    /* does it have a bloom filter?  */
    peer_bloom_sig =   peer_tbl + offsetof(UT_hash_table, bloom_sig);
    peer_bloombv_ptr = peer_tbl + offsetof(UT_hash_table, bloom_bv);
    peer_bloom_nbits = peer_tbl + offsetof(UT_hash_table, bloom_nbits);
    vvv("looking for bloom signature at peer %p\n", (void*)peer_bloom_sig);
#ifdef __FreeBSD__
    if ((read_mem(&bloomsig, pid, (void *)peer_bloom_sig, sizeof(uint32_t)) == 0)  &&
            (bloomsig == HASH_BLOOM_SIGNATURE)) {
#else
    if ((read_mem(&bloomsig, fd, (off_t)peer_bloom_sig, sizeof(uint32_t)) == 0)  &&
            (bloomsig == HASH_BLOOM_SIGNATURE)) {
#endif
        vvv("bloom signature (%x) found\n",bloomsig);
        /* bloom found. get at bv, nbits */
#ifdef __FreeBSD__
        if (read_mem(&bloom_nbits, pid, (void *)peer_bloom_nbits, sizeof(char)) == 0) {
#else
        if (read_mem(&bloom_nbits, fd, (off_t)peer_bloom_nbits, sizeof(char)) == 0) {
#endif
            /* scan bloom filter, calculate saturation */
            bloom_bitlen = (1ULL << bloom_nbits);
            bloom_len = (bloom_bitlen / 8) + ((bloom_bitlen % 8) ? 1 : 0);
            vvv("bloom bitlen is %u, bloom_bytelen is %u\n", (unsigned)bloom_bitlen, (unsigned)bloom_len);
            if ( (bloombv = (unsigned char*)malloc(bloom_len)) == NULL) {
                fprintf(stderr, "out of memory\n");
                exit(-1);
            }
            /* read the address of the bitvector in the peer, then read the bv itself */
#ifdef __FreeBSD__
            if ((read_mem(&peer_bloombv, pid, (void *)peer_bloombv_ptr, sizeof(void*)) == 0) &&
                    (read_mem(bloombv, pid, (void *)peer_bloombv, bloom_len) == 0)) {
#else
            if ((read_mem(&peer_bloombv, fd, (off_t)peer_bloombv_ptr, sizeof(void*)) == 0) &&
                    (read_mem(bloombv, fd, (off_t)peer_bloombv, bloom_len) == 0)) {
#endif
                /* calculate saturation */
                vvv("read peer bloom bitvector from %p (%u bytes)\n", (void*)peer_bloombv, (unsigned)bloom_len);
                for(i=0; i < bloom_bitlen; i++) {
                    if (HS_BIT_TEST(bloombv,(unsigned)i)) {
                        /* vvv("bit %u set\n",(unsigned)i); */
                        bloom_on_bits++;
                    } else {
                        bloom_off_bits++;
                    }
                }
                has_bloom_filter_fields = 1;
                vvv("there were %u on_bits among %u total bits\n", (unsigned)bloom_on_bits, (unsigned)bloom_bitlen);
            }
        }
    }

    /* choose apparent hash function */
    hash_fcn_winner=0;
    for(i=0; i<NUM_HASH_FUNCS; i++) {
        if (hash_fcn_hits[i] > hash_fcn_hits[hash_fcn_winner]) {
            hash_fcn_winner=i;
        }
    }
    hash_fcn = hash_fcns[hash_fcn_winner];

    /*
    Address            ideal    items  buckets mc fl bloom   sat fcn keys saved to
    ------------------ ----- -------- -------- -- -- ----- ----- --- -------------
    0x10aa4090           98% 10000000 32000000 10 ok             BER /tmp/9110-0.key
    0x10abcdef          100% 10000000 32000000  9 NX    27   12% BER /tmp/9110-1.key
    */
    printf("Address            ideal    items  buckets mc fl bloom   sat fcn keys saved to\n");
    printf("------------------ ----- -------- -------- -- -- ----- ----- --- -------------\n");
    if (has_bloom_filter_fields) {
        printf("%-18p %4.0f%% %8u %8u %2u %2s %5u %4.0f%c %3s %s\n",
               (void*)peer_tbl,
               (tbl->num_items - tbl->nonideal_items) * 100.0 / tbl->num_items,
               tbl->num_items,
               tbl->num_buckets,
               max_chain,
               tbl->noexpand ? "NX" : "ok",
               bloom_nbits,
               bloom_on_bits * 100.0 / bloom_bitlen, '%',
               hash_fcn,
               (getkeys ? keyfile : ""));
    } else {
        printf("%-18p %4.0f%% %8u %8u %2u %2s %5s %4s%c %3s %s\n",
               (void*)peer_tbl,
               (tbl->num_items - tbl->nonideal_items) * 100.0 / tbl->num_items,
               tbl->num_items,
               tbl->num_buckets,
               max_chain,
               tbl->noexpand ? "NX" : "ok",
               "",
               "", ' ',
               hash_fcn,
               (getkeys ? keyfile : ""));
    }

#if 0
    printf("read peer tbl:\n");
    printf("num_buckets: %u\n", tbl->num_buckets);
    printf("num_items: %u\n", tbl->num_items);
    printf("nonideal_items: %u (%.2f%%)\n", tbl->nonideal_items,
           tbl->nonideal_items*100.0/tbl->num_items);
    printf("expand: %s\n", tbl->noexpand ? "inhibited": "normal");
    if (getkeys) {
        printf("keys written to %s\n", keyfile);
    }
#endif

done:
    if (bkts) {
        free(bkts);
    }
    if (tbl) {
        free(tbl);
    }
    if (key) {
        free(key);
    }
    if (keyfd != -1) {
        close(keyfd);
    }
    if (bloombv) {
        free(bloombv);
    }
}


#ifdef __FreeBSD__
static void sigscan(pid_t pid, void *start, void *end, uint32_t sig)
{
    struct ptrace_io_desc io_desc;
    int page_size = getpagesize();
    char *buf;
    char *pos;

    /* make sure page_size is a multiple of the signature size, code below assumes this */
    assert(page_size % sizeof(sig) == 0);

    buf = malloc(page_size);

    if (buf == NULL) {
        fprintf(stderr, "malloc failed in sigscan()\n");
        return;
    }

    io_desc.piod_op = PIOD_READ_D;
    io_desc.piod_offs = start;
    io_desc.piod_addr = buf;
    io_desc.piod_len = page_size;

    /* read in one page after another and search sig */
    while(!ptrace(PT_IO, pid, (void *) &io_desc, 0)) {
        if (io_desc.piod_len != page_size) {
            fprintf(stderr, "PT_IO returned less than page size in sigscan()\n");
            return;
        }

        /* iterate over the the page using the signature size and look for the sig */
        for (pos = buf; pos < (buf + page_size); pos += sizeof(sig)) {
            if (*(uint32_t *) pos == sig) {
                found(pid, (char *) io_desc.piod_offs + (pos - buf), pid);
            }
        }

        /*
         * 'end' is inclusive (the address of the last valid byte), so if the current offset
         * plus a page is beyond 'end', we're already done. since all vm map entries consist
         * of entire pages and 'end' is inclusive, current offset plus one page should point
         * exactly one byte beyond 'end'. this is assert()ed below to be on the safe side.
         */
        if (io_desc.piod_offs + page_size > end) {
            assert(io_desc.piod_offs + page_size == (end + 1));
            break;
        }

        /* advance to the next page */
        io_desc.piod_offs += page_size;
    }
}
#else
static void sigscan(int fd, off_t start, off_t end, uint32_t sig, pid_t pid)
{
    int rlen;
    uint32_t u;
    off_t at=0;

    if (lseek(fd, start, SEEK_SET) == (off_t)-1) {
        fprintf(stderr, "lseek failed: %s\n", strerror(errno));
        return;
    }

    while ( (rlen = read(fd,&u,sizeof(u))) == sizeof(u)) {
        if (!memcmp(&u,&sig,sizeof(u))) {
            found(fd, (char*)(start+at),pid);
        }
        at += sizeof(u);
        if ((off_t)(at + sizeof(u)) > end-start) {
            break;
        }
    }

    if (rlen == -1) {
        //fprintf(stderr,"read failed: %s\n", strerror(errno));
        //exit(-1);
    }
}
#endif


#ifdef __FreeBSD__
static int scan(pid_t pid)
{
    vma_t *vmas=NULL, vma;
    unsigned i, num_vmas = 0;
    int ret;
    struct ptrace_vm_entry vm_entry;
    char path[MAXPATHLEN];

    vv("attaching to peer\n");
    if (ptrace(PT_ATTACH,pid,NULL,0) == -1) {
        fprintf(stderr,"failed to attach to %u: %s\n", (unsigned)pid, strerror(errno));
        exit(EXIT_FAILURE);
    }
    vv("waiting for peer to suspend temporarily\n");
    if (waitpid(pid,NULL,0) != pid) {
        fprintf(stderr,"failed to wait for pid %u: %s\n",(unsigned)pid, strerror(errno));
        goto die;
    }

    /* read memory map using ptrace */
    vv("listing peer virtual memory areas\n");
    vm_entry.pve_entry = 0;
    vm_entry.pve_path = path; /* not used but required to make vm_entry.pve_pathlen work */
    while(1) {
        /* set pve_pathlen every turn, it gets overwritten by ptrace */
        vm_entry.pve_pathlen = MAXPATHLEN;
        errno = 0;

        ret = ptrace(PT_VM_ENTRY, pid, (void *) &vm_entry, 0);

        if (ret) {
            if (errno == ENOENT) {
                /* we've reached the last entry */
                break;
            }
            fprintf(stderr, "fetching vm map entry failed: %s (%i)\n", strerror(errno), errno);
            goto die;
        }

        vvv("vmmap entry: start: %p, end: %p", (void *) vm_entry.pve_start, (void *) vm_entry.pve_end);

        /* skip unreadable or vnode-backed entries */
        if (!(vm_entry.pve_prot & VM_PROT_READ) || vm_entry.pve_pathlen > 0) {
            vvv(" -> skipped (not readable or vnode-backed)\n");
            vm_entry.pve_path[0] = 0;
            continue;
        }

        /* useful entry, add to list */
        vvv(" -> will be scanned\n");
        vma.start = (void *)vm_entry.pve_start;
        vma.end = (void *)vm_entry.pve_end;
        vmas = (vma_t *) realloc(vmas, (num_vmas + 1) * sizeof(vma_t));
        if (vmas == NULL) {
            exit(-1);
        }
        vmas[num_vmas++] = vma;
    }

    vv("peer has %u virtual memory areas\n", num_vmas);

    /* look for the hash signature */
    vv("scanning peer memory for hash table signatures\n");
    for(i=0; i<num_vmas; i++) {
        vma = vmas[i];
        sigscan(pid, vma.start, vma.end, sig);
    }

die:
    vv("detaching and resuming peer\n");
    if (ptrace(PT_DETACH, pid, NULL, 0) == -1) {
        fprintf(stderr,"failed to detach from %u: %s\n", (unsigned)pid, strerror(errno));
    }
    return 0;
}
# else
static int scan(pid_t pid)
{
    FILE *mapf;
    char mapfile[30], memfile[30], line[100];
    vma_t *vmas=NULL, vma;
    unsigned i, num_vmas = 0;
    int memfd;
    void *pstart, *pend, *unused;

    /* attach to the target process and wait for it to suspend */
    vv("attaching to peer\n");
    if (ptrace(PTRACE_ATTACH,pid,NULL,NULL) == -1) {
        fprintf(stderr,"failed to attach to %u: %s\n", (unsigned)pid, strerror(errno));
        exit(-1);
    }
    vv("waiting for peer to suspend temporarily\n");
    if (waitpid(pid,NULL,0) != pid) {
        fprintf(stderr,"failed to wait for pid %u: %s\n",(unsigned)pid, strerror(errno));
        goto die;
    }

    /* get ready to open its memory map. this gives us its valid memory areas */
    snprintf(mapfile,sizeof(mapfile),"/proc/%u/maps",(unsigned)pid);
    snprintf(memfile,sizeof(memfile),"/proc/%u/mem", (unsigned)pid);
    vv("opening peer memory map [%s]\n", mapfile);
    if ( (mapf = fopen(mapfile,"r")) == NULL) {
        fprintf(stderr,"failed to open %s: %s\n", mapfile, strerror(errno));
        goto die;
    }
    vv("listing peer virtual memory areas\n");
    while(fgets(line,sizeof(line),mapf)) {
        if (sscanf(line, "%p-%p %4c %p %5c", &pstart, &pend, vma.perms,
                   &unused, vma.device) == 5) {
            vma.start = (off_t)pstart;
            vma.end = (off_t)pend;
            if (vma.perms[0] != 'r') {
                continue;    /* only readable vma's */
            }
            if (memcmp(vma.device,"fd",2)==0) {
                continue;    /* skip mapped files */
            }
            vmas = (vma_t*)realloc(vmas, (num_vmas+1) * sizeof(vma_t));
            if (vmas == NULL) {
                exit(-1);
            }
            vmas[num_vmas++] = vma;
        }
    }
    vv("peer has %u virtual memory areas\n",num_vmas);
    fclose(mapf);

    /* ok, open up its memory and start looking around in there */
    vv("opening peer memory\n");
    if ( (memfd=open(memfile,O_RDONLY)) == -1) {
        fprintf(stderr,"failed to open %s: %s\n", memfile, strerror(errno));
        goto die;
    }
    /* look for the hash signature */
    vv("scanning peer memory for hash table signatures\n");
    for(i=0; i<num_vmas; i++) {
        vma = vmas[i];
        pstart = (void*)vma.start;
        pend = (void*)vma.end;
        /*fprintf(stderr,"scanning %p-%p %.4s %.5s\n", pstart, pend,
                  vma.perms, vma.device);*/
        sigscan(memfd, vma.start, vma.end, sig, pid);
    }

    /* done. close memory and detach. this resumes the target process */
    close(memfd);

die:
    vv("detaching and resuming peer\n");
    if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) {
        fprintf(stderr,"failed to detach from %u: %s\n", (unsigned)pid, strerror(errno));
    }
    return 0;
}
#endif


static int usage(const char *prog)
{
    fprintf(stderr,"usage: %s [-v] [-k] <pid>\n", prog);
    return -1;
}

int main(int argc, char *argv[])
{
    int opt;

    while ( (opt = getopt(argc, argv, "kv")) != -1) {
        switch (opt) {
            case 'v':
                verbose++;
                break;
            case 'k':
                getkeys++;
                break;
            default:
                return usage(argv[0]);
        }
    }

    if (optind < argc) {
        pid_t pid = atoi(argv[optind++]);
        return scan(pid);
    } else {
        return usage(argv[0]);
    }
}
コード例 #28
0
ファイル: regs.c プロジェクト: KapJlcoH/ltrace
void *
get_return_addr(Process *proc, void *stack_pointer) {
	return (void *)ptrace(PTRACE_PEEKTEXT, proc->pid, stack_pointer, 0);
}
コード例 #29
0
ファイル: registers.c プロジェクト: CSCLOG/beaglebone
int save_fp_registers(int pid, unsigned long *fp_regs)
{
	if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
		return -errno;
	return 0;
}
コード例 #30
0
ファイル: armnbsd-nat.c プロジェクト: ajinkya93/netbsd-src
static void
store_register (const struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct reg inferior_registers;
  int ret;

  ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
		(PTRACE_TYPE_ARG3) &inferior_registers, ptid_get_lwp(inferior_ptid));

  if (ret < 0)
    {
      warning (_("unable to fetch general registers"));
      return;
    }

  switch (regno)
    {
    case ARM_SP_REGNUM:
      regcache_raw_collect (regcache, ARM_SP_REGNUM,
			    (char *) &inferior_registers.r_sp);
      break;

    case ARM_LR_REGNUM:
      regcache_raw_collect (regcache, ARM_LR_REGNUM,
			    (char *) &inferior_registers.r_lr);
      break;

    case ARM_PC_REGNUM:
      if (arm_apcs_32)
	regcache_raw_collect (regcache, ARM_PC_REGNUM,
			      (char *) &inferior_registers.r_pc);
      else
	{
	  unsigned pc_val;

	  regcache_raw_collect (regcache, ARM_PC_REGNUM,
				(char *) &pc_val);
	  
	  pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
	  inferior_registers.r_pc ^= gdbarch_addr_bits_remove
				       (gdbarch, inferior_registers.r_pc);
	  inferior_registers.r_pc |= pc_val;
	}
      break;

    case ARM_PS_REGNUM:
      if (arm_apcs_32)
	regcache_raw_collect (regcache, ARM_PS_REGNUM,
			      (char *) &inferior_registers.r_cpsr);
      else
	{
	  unsigned psr_val;

	  regcache_raw_collect (regcache, ARM_PS_REGNUM,
				(char *) &psr_val);

	  psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
	  inferior_registers.r_pc = gdbarch_addr_bits_remove
				      (gdbarch, inferior_registers.r_pc);
	  inferior_registers.r_pc |= psr_val;
	}
      break;

    default:
      regcache_raw_collect (regcache, regno,
			    (char *) &inferior_registers.r[regno]);
      break;
    }

  ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
		(PTRACE_TYPE_ARG3) &inferior_registers, ptid_get_lwp(inferior_ptid));

  if (ret < 0)
    warning (_("unable to write register %d to inferior"), regno);
}