static int __write_pid( char *pidpath ) {
	FILE *pidfile;
	__abort(0,__get_pid(pidpath)>0,"");
	__abort(-1,(pidfile = fopen( pidpath, "w"))==NULL,"");
	fprintf( pidfile, "%d\n", (int) getpid( ) ),fflush(pidfile),fclose(pidfile);
	return 0;
}
Exemplo n.º 2
0
static int tsk_pagesize(RIODesc *desc) {
	int tid = __get_pid (desc);
	task_t task = pid_to_task (desc, tid);
	static vm_size_t pagesize = 0;
	return pagesize
		? pagesize
		: (host_page_size (task, &pagesize) == KERN_SUCCESS)
			? pagesize : 4096;
}
Exemplo n.º 3
0
static char *__system(RIO *io, RIODesc *fd, const char *cmd) {
	if (!io || !fd || !cmd || !fd->data) {
		return NULL;
	}
	RIODescData *iodd = fd->data;
	if (iodd->magic != R_MACH_MAGIC) {
		return NULL;
	}

	task_t task = pid_to_task (fd, iodd->tid);
	/* XXX ugly hack for testing purposes */
	if (!strncmp (cmd, "perm", 4)) {
		int perm = r_str_rwx (cmd + 4);
		if (perm) {
			int pagesize = tsk_pagesize (fd);
			tsk_setperm (io, task, io->off, pagesize, perm);
		} else {
			eprintf ("Usage: =!perm [rwx]\n");
		}
		return NULL;
	}
	if (!strncmp (cmd, "pid", 3)) {
		RIODescData *iodd = fd->data;
		RIOMach *riom = iodd->data;
		const char *pidstr = cmd + 3;
		int pid = -1;
		if (*pidstr) {
			pid = __get_pid (fd);
			//return NULL;
		} else {
			eprintf ("%d\n", iodd->pid);
			return NULL;
		}
		if (!strcmp (pidstr, "0")) {
			pid = 0;
		} else {
			pid = atoi (pidstr);
			if (!pid) {
				pid = -1;
			}
		}
		if (pid != -1) {
			task_t task = pid_to_task (fd, pid);
			if (task != -1) {
				riom->task = task;
				iodd->pid = pid;
				iodd->tid = pid;
				return NULL;
			}
		}
		eprintf ("io_mach_system: Invalid pid %d\n", pid);
	} else {
		eprintf ("Try: '=!pid' or '=!perm'\n");
	}
	return NULL;
}
Exemplo n.º 4
0
static ut64 getNextValid(RIO *io, RIODesc *fd, ut64 addr) {
	struct vm_region_submap_info_64 info;
	vm_address_t address = MACH_VM_MIN_ADDRESS;
	vm_size_t size = (vm_size_t) 0;
	vm_size_t osize = (vm_size_t) 0;
	natural_t depth = 0;
	kern_return_t kr;
	int tid = __get_pid (fd);
	task_t task = pid_to_task (fd, tid);
	ut64 lower = addr;
#if __arm64__ || __aarch64__
	size = osize = 16384; // acording to frida
#else
	size = osize = 4096;
#endif
	if (the_lower != UT64_MAX) {
		return R_MAX (addr, the_lower);
	}

	for (;;) {
		mach_msg_type_number_t info_count;
		info_count = VM_REGION_SUBMAP_INFO_COUNT_64;
		memset (&info, 0, sizeof (info));
		kr = vm_region_recurse_64 (task, &address, &size,
			&depth, (vm_region_recurse_info_t) &info, &info_count);
		if (kr != KERN_SUCCESS) {
			break;
		}
		if (lower == addr) {
			lower = address;
		}
		if (info.is_submap) {
			depth++;
			continue;
		}
		if (addr >= address && addr < address + size) {
			return addr;
		}
		if (address < lower) {
			lower = address;
		}
		if (size < 1) {
			size = osize; // f**k
		}
		address += size;
		size = 0;
	}
	the_lower = lower;
	return lower;
}
Exemplo n.º 5
0
struct pid *krg_get_pid(int nr)
{
	struct pid_kddm_object *obj;
	struct pid *pid;

	rcu_read_lock();
	pid = find_kpid(nr);
	rcu_read_unlock();
	/*
	 * No need to get a reference on pid since we know that it is used on
	 * another node: nobody will free it for the moment.
	 */

	if (!pid)
		return no_pid(nr);

	spin_lock(&pid_kddm_lock);
	obj = pid->kddm_obj;
	BUG_ON(!obj);
	BUG_ON(obj->pid != pid);

	if (likely(obj->active)) {
		obj->attach_pending++;
		spin_unlock(&pid_kddm_lock);
		return pid;
	}
	/* Slow path: we must grab the kddm object. */
	spin_unlock(&pid_kddm_lock);

	obj = _kddm_grab_object_no_ft(pid_kddm_set, nr);
	if (IS_ERR(obj))
		return NULL;
	BUG_ON(obj != pid->kddm_obj);
	BUG_ON(obj->pid != pid);

	spin_lock(&pid_kddm_lock);
	__get_pid(obj);
	spin_unlock(&pid_kddm_lock);

	_kddm_put_object(pid_kddm_set, nr);

	return pid;
}
Exemplo n.º 6
0
static int mach_write_at(RIO *io, RIODesc *desc, const void *buf, int len, ut64 addr) {
	vm_address_t vaddr = addr;
	vm_address_t pageaddr;
	vm_size_t pagesize;
	vm_size_t total_size;
	int operms = 0;
	int pid = __get_pid (desc);
	if (!desc || pid < 0) {
		return 0;
	}
	task_t task = pid_to_task (desc, pid);

	if (len < 1 || task_is_dead (desc, task)) {
		return 0;
	}
	pageaddr = tsk_getpagebase (desc, addr);
	pagesize = tsk_pagesize (desc);
	total_size = (len > pagesize)
		? pagesize * (1 + (len / pagesize))
		: pagesize;
	if (tsk_write (task, vaddr, buf, len)) {
		return len;
	}
	operms = tsk_getperm (io, task, pageaddr);
	if (!tsk_setperm (io, task, pageaddr, total_size, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY)) {
		eprintf ("io.mach: Cannot set page perms for %d byte(s) at 0x%08"
			PFMT64x"\n", (int)pagesize, (ut64)pageaddr);
		return -1;
	}
	if (!tsk_write (task, vaddr, buf, len)) {
		eprintf ("io.mach: Cannot write on memory\n");
		len = -1;
	}
	if (operms) {
		if (!tsk_setperm (io, task, pageaddr, total_size, operms)) {
			eprintf ("io.mach: Cannot restore page perms\n");
			return -1;
		}
	}
	return len;
}
Exemplo n.º 7
0
static int stop_child(euca_opts *args) {
	int pid = __get_pid(GETARG(args, pidfile)), rc = 0, i;
	if (pid <= 0)
		return -1;
	fprintf(stderr, "Waiting for process to terminate: pid=%d .", pid);
	for (i = 0; i < 60 && (rc = kill(pid, SIGTERM)) != -1; i++) {
		usleep(1000 * 1000), fprintf(stderr, "."), fflush(stderr);
	}
	if (i == 0) {
		i = errno;
		__die(rc == -1 && i == ESRCH, "No process with the specified pid=%d",
				pid);
		__die(rc == -1 && i == EPERM, "Do not have permission to kill pid=%d",
				pid);
	} else if (i == 60) {
		__debug("Forcefully terminating hung process.");
		kill(pid, SIGKILL);
	} else {
		fprintf(stderr, "\nTerminated process with pid=%d\n", pid);
	}
	return 0;
}
Exemplo n.º 8
0
static struct pid *no_pid(int nr)
{
	struct pid_namespace *ns;
	struct pid_kddm_object *obj;
	struct pid *pid;

	obj = _kddm_grab_object_no_ft(pid_kddm_set, nr);
	if (IS_ERR(obj))
		return NULL;
	BUG_ON(!obj);

	spin_lock(&pid_kddm_lock);
	rcu_read_lock();
	pid = find_kpid(nr); /* Double check once locked */
	rcu_read_unlock();
	/*
	 * No need to get a reference on pid since we know that it is used on
	 * another node: nobody will free it for the moment.
	 */

	if (!pid) {
		ns = find_get_krg_pid_ns();
		pid = __alloc_pid(ns, &nr);
		put_pid_ns(ns);
		if (!pid)
			goto out_unlock;
		obj->pid = pid;
		pid->kddm_obj = obj;
	}
	BUG_ON(pid->kddm_obj != obj);

	__get_pid(obj);

out_unlock:
	spin_unlock(&pid_kddm_lock);
	_kddm_put_object(pid_kddm_set, nr);

	return pid;
}
static int stop_child( euca_opts *args ) {
	int pid = __get_pid( GETARG(args,pidfile) );
	if( pid <= 0 ) return -1;
	kill( pid, SIGTERM );
	return wait_child(args,pid);
}
Exemplo n.º 10
0
static int __read(RIO *io, RIODesc *desc, ut8 *buf, int len) {
	vm_size_t size = 0;
	int blen, err, copied = 0;
	int blocksize = 32;
	RIODescData *dd = (RIODescData *)desc->data;
	if (!io || !desc || !buf || !dd) {
		return -1;
	}
	if (dd ->magic != r_str_hash ("mach")) {
		return -1;
	}
	memset (buf, 0xff, len);
	int pid = __get_pid (desc);
	task_t task = pid_to_task (desc, pid);
	if (task_is_dead (desc, pid)) {
		return -1;
	}
	if (pid == 0) {
		if (io->off < 4096) {
			return len;
		}
	}
	copied = getNextValid (io, desc, io->off) - io->off;
	if (copied < 0) {
		copied = 0;
	}
	while (copied < len) {
		blen = R_MIN ((len - copied), blocksize);
		//blen = len;
		err = vm_read_overwrite (task,
			(ut64)io->off + copied, blen,
			(pointer_t)buf + copied, &size);
		switch (err) {
		case KERN_PROTECTION_FAILURE:
			//eprintf ("r_io_mach_read: kern protection failure.\n");
			break;
		case KERN_INVALID_ADDRESS:
			if (blocksize == 1) {
				memset (buf+copied, 0xff, len-copied);
				return size+copied;
			}
			blocksize = 1;
			blen = 1;
			buf[copied] = 0xff;
			break;
		}
		if (err == -1 || size < 1) {
			return -1;
		}
		if (size == 0) {
			if (blocksize == 1) {
				memset (buf + copied, 0xff, len - copied);
				return len;
			}
			blocksize = 1;
			blen = 1;
			buf[copied] = 0xff;
		}
		copied += blen;
	}
	return len;
}