Exemplo n.º 1
0
int
proc_bkptset(struct proc_handle *phdl, uintptr_t address,
             unsigned long *saved)
{
    struct ptrace_io_desc piod;
    unsigned long paddr, caddr;
    int ret = 0;

    *saved = 0;
    if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD ||
            phdl->status == PS_IDLE) {
        errno = ENOENT;
        return (-1);
    }

    DPRINTFX("adding breakpoint at 0x%lx", address);

    if (phdl->status != PS_STOP)
        if (proc_stop(phdl) != 0)
            return (-1);

    /*
     * Read the original instruction.
     */
    caddr = address;
    paddr = 0;
    piod.piod_op = PIOD_READ_I;
    piod.piod_offs = (void *)caddr;
    piod.piod_addr = &paddr;
    piod.piod_len  = BREAKPOINT_INSTR_SZ;
    if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) {
        DPRINTF("ERROR: couldn't read instruction at address 0x%"
                PRIuPTR, address);
        ret = -1;
        goto done;
    }
    *saved = paddr;
    /*
     * Write a breakpoint instruction to that address.
     */
    caddr = address;
    paddr = BREAKPOINT_INSTR;
    piod.piod_op = PIOD_WRITE_I;
    piod.piod_offs = (void *)caddr;
    piod.piod_addr = &paddr;
    piod.piod_len  = BREAKPOINT_INSTR_SZ;
    if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) {
        DPRINTF("ERROR: couldn't write instruction at address 0x%"
                PRIuPTR, address);
        ret = -1;
        goto done;
    }

done:
    if (phdl->status != PS_STOP)
        /* Restart the process if we had to stop it. */
        proc_cont(phdl);

    return (ret);
}
Exemplo n.º 2
0
int main(int argc, char *argv[]) {
	if (argc != 3) {
		return 1;
	}
	int pid = atoi(argv[1]);
	unsigned long addr = strtol(argv[2], NULL, 16);
	struct proc *p = attach(pid);
	printf("attach %d\n", p->pid);
	proc_mprotect(p, (void *)(addr & -0x1000), PROT_READ);
	printf("begin...\n");
	assert(p->stat<UNTRACED && p->stat>RUNNING);
	proc_cont(p, 0);
	while (1) {
		proc_wait(p);
		//printf("stat %d\n", p->stat);
		if (p->stat == SIGNAL_DELIVER_STOP) {
			if (WSTOPSIG(p->status) == SIGSEGV) {
				siginfo_t siginfo;
				ptrace(PTRACE_GETSIGINFO, p->pid, NULL, &siginfo);
				printf("memory address %p\n", siginfo.si_addr);
				if (siginfo.si_addr == (void *)addr) {
					proc_mprotect(p, (void *)(addr & -0x1000), PROT_READ|PROT_WRITE);
					ptrace(PTRACE_SINGLESTEP, p->pid, NULL, NULL);
					proc_wait(p);
					//fprintf(stderr, "%d %x\n", p->stat, p->status);
					proc_write(p, (void *)addr, (char *)&locked, 4);
					proc_mprotect(p, (void *)(addr & -0x1000), PROT_READ);
				} else {
					if (siginfo.si_addr >= (void *)(addr & ~0xfff) && siginfo.si_addr < (void *)((addr + 0xfff) & ~0xfff)) {
						proc_mprotect(p, (void *)(addr & -0x1000), PROT_READ|PROT_WRITE);
						ptrace(PTRACE_SINGLESTEP, p->pid, NULL, NULL);
						proc_wait(p);
						proc_mprotect(p, (void *)(addr & -0x1000), PROT_READ);
					}
				}
			}
		}
		proc_cont(p, 0);
	}
	//proc_exit(p, 42);
	proc_detach(p);
}
Exemplo n.º 3
0
int
proc_bkptdel(struct proc_handle *phdl, uintptr_t address,
             unsigned long saved)
{
    struct ptrace_io_desc piod;
    unsigned long paddr, caddr;
    int ret = 0;

    if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD ||
            phdl->status == PS_IDLE) {
        errno = ENOENT;
        return (-1);
    }

    DPRINTFX("removing breakpoint at 0x%lx", address);

    if (phdl->status != PS_STOP)
        if (proc_stop(phdl) != 0)
            return (-1);

    /*
     * Overwrite the breakpoint instruction that we setup previously.
     */
    caddr = address;
    paddr = saved;
    piod.piod_op = PIOD_WRITE_I;
    piod.piod_offs = (void *)caddr;
    piod.piod_addr = &paddr;
    piod.piod_len  = BREAKPOINT_INSTR_SZ;
    if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) {
        DPRINTF("ERROR: couldn't write instruction at address 0x%"
                PRIuPTR, address);
        ret = -1;
    }

    if (phdl->status != PS_STOP)
        /* Restart the process if we had to stop it. */
        proc_cont(phdl);

    return (ret);
}
Exemplo n.º 4
0
static void handle_command(void)
{
	int ret;
	mt_msg cmd;
	void *payload = NULL;

	ret = safe_read(server_fd, &cmd, sizeof(cmd));

	if (ret != sizeof(cmd)) {
		if (ret > 0)
			error("cmd read wrong size %d\n", ret);
		close(server_fd);
		server_fd = -1;
		return;
	}

	if (cmd.payload_len) {
		payload = malloc(cmd.payload_len);

		if (safe_read(server_fd, payload, cmd.payload_len) != cmd.payload_len) {
			fprintf(stderr, "can't read payload_len (%u)\n", cmd.payload_len);
			goto finish;
		}
	}

	switch(cmd.operation) {
	case MT_SCAN:
	 {
		unsigned long data_len;
		void * data = mem_scan(&cmd, payload, &data_len);

		ret = TEMP_FAILURE_RETRY(sem_wait(&shm->sem));
		if (!ret) {
			MT_SEND_MSG(MT_SCAN, cmd.pid, 0, data_len, data, 0, NULL);
			sem_post(&shm->sem);
		}
		break;
	 }
	case MT_XMAP:
	 {
		void *xmap_base = NULL;
		unsigned int xmap_size = 0;

		xmap_base = get_executable_mappings(cmd.pid, &xmap_size);

		ret = TEMP_FAILURE_RETRY(sem_wait(&shm->sem));
		if (!ret) {
			MT_SEND_MSG(MT_XMAP, cmd.pid, cmd.tid, xmap_size, xmap_base, 0, NULL);
			sem_post(&shm->sem);
		}
		free(xmap_base);
		break;
	 }
	case MT_START:
		shm->info.do_trace = 1;
		break;
	case MT_STOP:
		shm->info.do_trace = 0;
		break;
	case MT_CONT:
		proc_cont(cmd.pid);
		break;
	case MT_INFO:
		ret = TEMP_FAILURE_RETRY(sem_wait(&shm->sem));
		if (!ret) {
			MT_SEND_MSG(MT_INFO, cmd.pid, cmd.tid, sizeof(shm->info), &shm->info, 0, NULL);
			sem_post(&shm->sem);
		}
		break;
	default:
		break;
	}
finish:
	if (payload)
		free(payload);
}