Example #1
0
/**
 * @brief PPP callback to retrieve OsiModules from the running OS.
 *
 * Current implementation returns all the memory areas mapped by the
 * process and the files they were mapped from. Libraries that have
 * many mappings will appear multiple times.
 *
 * @todo Remove duplicates from results.
 */
void on_get_libraries(CPUState *env, OsiProc *p, OsiModules **out_ms) {
	PTR ts_first, ts_current;
	target_ulong current_pid;
	OsiModules *ms;
	OsiModule *m;
	uint32_t ms_capacity = 16;

	PTR vma_first, vma_current;

	// Find the process with the indicated pid.
	ts_first = ts_current = get_task_struct(env, (_ESP & THREADINFO_MASK));
	if (ts_current == (PTR)NULL) goto error0;

	do {
		if ((current_pid = get_pid(env, ts_current)) == p->pid) break;
		ts_current = get_task_struct_next(env, ts_current);
	} while(ts_current != (PTR)NULL && ts_current != ts_first);

	// memory read error or process not found
	if (ts_current == (PTR)NULL || current_pid != p->pid) goto error0;

	// Read the module info for the process.
	vma_first = vma_current = get_vma_first(env, ts_current);
	if (vma_current == (PTR)NULL) goto error0;

	ms = (OsiModules *)g_malloc0(sizeof(OsiModules));
	ms->module = g_new(OsiModule, ms_capacity);
	do {
		if (ms->num == ms_capacity) {
			ms_capacity *= 2;
			ms->module = g_renew(OsiModule, ms->module, ms_capacity);
		}

		m = &ms->module[ms->num++];
		memset(m, 0, sizeof(OsiModule));
		fill_osimodule(env, m, vma_current);

		vma_current = get_vma_next(env, vma_current);
	} while(vma_current != (PTR)NULL && vma_current != vma_first);

	*out_ms = ms;
	return;

error0:
	*out_ms = NULL;
	return;
}
Example #2
0
/**
 * @brief PPP callback to retrieve OsiModules from the running OS.
 *
 * Current implementation returns all the memory areas mapped by the
 * process and the files they were mapped from. Libraries that have
 * many mappings will appear multiple times.
 *
 * @todo Remove duplicates from results.
 */
void on_get_libraries(CPUState *env, OsiProc *p, OsiModules **out_ms) {
	PTR ts_first, ts_current;
	target_ulong current_pid;
	OsiModules *ms;
	OsiModule *m;
	uint32_t ms_capacity = 16;
	PTR vma_first, vma_current;
#ifdef OSI_LINUX_LIST_THREADS
	PTR tg_first, tg_next;
#endif

	// Get a starting process.
	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);
	}

	// Find the process that matches p->pid.
	// XXX: We could probably just use p->offset instead of traversing
	//	  the process list.
	// XXX: An infinite loop will be triggered if p is a thread and
	//		OSI_LINUX_LIST_THREADS is not enabled.
	do {
		if ((current_pid = get_pid(env, ts_current)) == p->pid) goto pid_found;
#ifdef OSI_LINUX_LIST_THREADS
		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 ((current_pid = get_pid(env, ts_current)) == p->pid) goto pid_found;
		}
		ts_current = tg_first-ki.task.thread_group_offset;
#endif
		ts_current = get_task_struct_next(env, ts_current);
	} while(ts_current != (PTR)NULL && ts_current != ts_first);
pid_found:

	// memory read error or process not found
	if (ts_current == (PTR)NULL || current_pid != p->pid) goto error0;

	// Read the module info for the process.
	vma_first = vma_current = get_vma_first(env, ts_current);
	if (vma_current == (PTR)NULL) goto error0;

	ms = (OsiModules *)g_malloc0(sizeof(OsiModules));
	ms->module = g_new(OsiModule, ms_capacity);
	do {
		if (ms->num == ms_capacity) {
			ms_capacity *= 2;
			ms->module = g_renew(OsiModule, ms->module, ms_capacity);
		}

		m = &ms->module[ms->num++];
		memset(m, 0, sizeof(OsiModule));
		fill_osimodule(env, m, vma_current);

		vma_current = get_vma_next(env, vma_current);
	} while(vma_current != (PTR)NULL && vma_current != vma_first);

	*out_ms = ms;
	return;

error0:
	*out_ms = NULL;
	return;
}