Beispiel #1
0
/**
 * @brief PPP callback to retrieve current process info for the running OS.
 */
void on_get_current_process(CPUState *env, OsiProc **out_p) {
	OsiProc *p;
	PTR ts;

	p = (OsiProc *)g_malloc0(sizeof(OsiProc));
	ts = get_task_struct(env, (_ESP & THREADINFO_MASK));
	fill_osiproc(env, p, ts);

	*out_p = p;
}
Beispiel #2
0
/**
 * @brief PPP callback to retrieve current process info for the running OS.
 */
void on_get_current_process(CPUState *env, OsiProc **out_p) {
	OsiProc *p = NULL;
	PTR ts;

	//	target_long asid = panda_current_asid(env);
	ts = get_task_struct(env, (_ESP & THREADINFO_MASK));
	if (ts) {
		// valid task struct
		// got a reasonable looking process.
		// return it and save in cache
		p = (OsiProc *)g_malloc0(sizeof(OsiProc));
		fill_osiproc(env, p, ts);
	}
	*out_p = p;
}
Beispiel #3
0
/**
 * @brief PPP callback to retrieve process list from the running OS.
 */
void on_get_processes(CPUState *env, OsiProcs **out_ps) {
	PTR ts_first, ts_current;
	OsiProcs *ps;
	OsiProc *p;
	uint32_t ps_capacity = 16;

	ts_first = ts_current = get_task_struct(env, (_ESP & THREADINFO_MASK));
	if (ts_current == (PTR)NULL) goto error0;

	// When thread_group points to itself, the task_struct belongs to a thread
	// (see kernel_structs.md for details). This will trigger an infinite loop
	// in the traversal loop.
	// Following next will lead us to a task_struct belonging to a process and
	// help avoid the condition.
	if (ts_current+ki.task.thread_group_offset != get_thread_group(env, ts_current)) {
		ts_first = ts_current = get_task_struct_next(env, ts_current);
	}

	ps = (OsiProcs *)g_malloc0(sizeof(OsiProcs));
	ps->proc = g_new(OsiProc, ps_capacity);
	do {
		if (ps->num == ps_capacity) {
			ps_capacity *= 2;
			ps->proc = g_renew(OsiProc, ps->proc, ps_capacity);
		}

		p = &ps->proc[ps->num++];

		// Garbage in p->name will cause fill_osiproc() to segfault.
		memset(p, 0, sizeof(OsiProc));
		fill_osiproc(env, p, ts_current);

#if 0
		/*********************************************************/
		// Test of fd -> name resolution.
		/*********************************************************/
		for (int fdn=0; fdn<10; fdn++) {
			char *s = get_fd_name(env, ts_current, fdn);
			LOG_INFO("%s fd%d -> %s", p->name, fdn, s);
			g_free(s);
		}
		/*********************************************************/
#endif

		ts_current = get_task_struct_next(env, ts_current);
	} while(ts_current != (PTR)NULL && ts_current != ts_first);

	// memory read error
	if (ts_current == (PTR)NULL) goto error1;

	*out_ps = ps;
	return;

error1:
	do {
		ps->num--;
		g_free(ps->proc[ps->num].name);
	} while (ps->num != 0);
	g_free(ps->proc);
	g_free(ps);
error0:
	*out_ps = NULL;
	return;
}
Beispiel #4
0
/**
 * @brief PPP callback to retrieve process list from the running OS.
 */
void on_get_processes(CPUState *env, OsiProcs **out_ps) {
	PTR ts_first, ts_current;
	OsiProcs *ps;
	OsiProc *p;
	uint32_t ps_capacity = 16;
#ifdef OSI_LINUX_LIST_THREADS
	PTR tg_first, tg_next;
#endif

	// Get a task_struct of a process to start iterating the process list. If
	// current task is a thread (ts->t_group != &ts->t_group), follow ts->next
	// to get to a process.
	// Always starting the traversal with a process has the benefits of:
	// 	a. Simplifying the traversal when OSI_LINUX_LIST_THREADS is disabled.
	//  b. Avoiding an infinite loop when OSI_LINUX_LIST_THREADS is enabled and
	//	 the current task is a thread.
	// See kernel_structs.md for details.
	ts_first = ts_current = get_task_struct(env, (_ESP & THREADINFO_MASK));
	if (ts_current == (PTR)NULL) goto error0;
	if (ts_current+ki.task.thread_group_offset != get_thread_group(env, ts_current)) {
		ts_first = ts_current = get_task_struct_next(env, ts_current);
	}

	ps = (OsiProcs *)g_malloc0(sizeof(OsiProcs));
	ps->proc = g_new(OsiProc, ps_capacity);
	do {
		if (ps->num == ps_capacity) {
			ps_capacity *= 2;
			ps->proc = g_renew(OsiProc, ps->proc, ps_capacity);
		}
		p = &ps->proc[ps->num++];
		memset(p, 0, sizeof(OsiProc));	// fill_osiproc() expects p to be zeroed-out.
		fill_osiproc(env, p, ts_current);

#ifdef OSI_LINUX_LIST_THREADS
		// Traverse thread group list.
		// It is assumed that ts_current is a thread group leader.
		tg_first = ts_current+ki.task.thread_group_offset;
		while ((tg_next = get_thread_group(env, ts_current)) != tg_first) {
			ts_current = tg_next-ki.task.thread_group_offset;
			if (ps->num == ps_capacity) {
				ps_capacity *= 2;
				ps->proc = g_renew(OsiProc, ps->proc, ps_capacity);
			}
			p = &ps->proc[ps->num++];
			memset(p, 0, sizeof(OsiProc)); // fill_osiproc() expects p to be zeroed-out.
			fill_osiproc(env, p, ts_current);
		}
		ts_current = tg_first-ki.task.thread_group_offset;
#endif

#if 0
		/*********************************************************/
		// Test of fd -> name resolution.
		/*********************************************************/
		for (int fdn=0; fdn<256; fdn++) {
			char *s = get_fd_name(env, ts_current, fdn);
			LOG_INFO("%s fd%d -> %s", p->name, fdn, s);
			g_free(s);
		}
		/*********************************************************/
#endif

		ts_current = get_task_struct_next(env, ts_current);
	} while(ts_current != (PTR)NULL && ts_current != ts_first);

	// memory read error
	if (ts_current == (PTR)NULL) goto error1;

	*out_ps = ps;
	return;

error1:
	do {
		ps->num--;
		g_free(ps->proc[ps->num].name);
	} while (ps->num != 0);
	g_free(ps->proc);
	g_free(ps);
error0:
	*out_ps = NULL;
	return;
}