Beispiel #1
0
void
open_pid(pid_t pid) {
	Process *proc;
	char *filename;

	if (trace_pid(pid) < 0) {
		fprintf(stderr, "Cannot attach to pid %u: %s\n", pid,
			strerror(errno));
		return;
	}

	filename = pid2name(pid);

	if (!filename) {
		fprintf(stderr, "Cannot trace pid %u: %s\n", pid,
				strerror(errno));
		return;
	}

	proc = open_program(filename, pid);
	continue_process(pid);
    proc->breakpoints_enabled = 1;
    //modify for android
    attach_child_thread(proc);
}
//thread function with connections check loop
static unsigned __stdcall checkthread(void *dummy)
{

#ifdef _DEBUG
	_OutputDebugString(_T("check thread started"));
#endif
	while(1)
	{
		struct CONNECTION* conn=NULL,*connOld=first,*cur=NULL;
#ifdef _DEBUG
		_OutputDebugString(_T("checking connections table..."));
#endif
		if (WAIT_OBJECT_0 == WaitForSingleObject(killCheckThreadEvent,100))
		{
			hConnectionCheckThread=NULL;
			return 0;
		}

		conn=GetConnectionsTable();
		cur=conn;
		while(cur!=NULL) {	
			if (searchConnection(first,cur->strIntIp,cur->strExtIp,cur->intIntPort,cur->intExtPort,cur->state)==NULL && (settingStatusMask & (1 << (cur->state-1)))) {				

#ifdef _DEBUG
				TCHAR msg[1024];
				mir_sntprintf(msg,_countof(msg),_T("%s:%d\n%s:%d"),cur->strIntIp,cur->intIntPort,cur->strExtIp,cur->intExtPort);
				_OutputDebugString(_T("New connection: %s"),msg);
#endif
				pid2name(cur->Pid, cur->PName, SIZEOF(cur->PName));
				if ( WAIT_OBJECT_0 == WaitForSingleObject( hExceptionsMutex, 100 ))
				{
					if (checkFilter(connExceptions,cur))
					{
						showMsg(cur->PName,cur->Pid,cur->strIntIp,cur->strExtIp,cur->intIntPort,cur->intExtPort,cur->state);
						SkinPlaySound(PLUGINNAME_NEWSOUND);
					}
					ReleaseMutex(hExceptionsMutex);
				}
			}
			cur=cur->next;
		}

		first=conn;
		deleteConnectionsTable(connOld);
		Sleep(settingInterval);
	}
	hConnectionCheckThread=NULL;
	return 1;
}
Beispiel #3
0
int
init_connection(state_t state, int pid) {
    int fd;
    if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        return -1;
    }

    char unix_path[128] = { 0 };
    pid2name(pid, unix_path);

    struct sockaddr_un addr;
    bzero(&addr, sizeof(addr));
    addr.sun_family = AF_UNIX;
    memcpy(addr.sun_path, unix_path, strlen(unix_path) + 1);

    if (connect(fd, (struct sockaddr *)&addr, 
            strlen(unix_path) + 1 + sizeof(addr.sun_family)) == -1) {
        return -1;
    }

    return fd;
}
Beispiel #4
0
int
init_socket(state_t state) {
    struct sockaddr_un addr;

    int fd;
    if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        return -1;
    }

    char unix_path[128] = { 0 };
    pid2name(state->myid.pid, unix_path);

    unlink(unix_path);
    bzero(&addr, sizeof(addr));
    addr.sun_family = AF_UNIX;
    memcpy(addr.sun_path, unix_path, strlen(unix_path)+1);

    if (bind(fd, (struct sockaddr *)&addr, strlen(unix_path) + 1 + sizeof(addr.sun_family))
            || listen(fd, 128) < 0) 
    { return -1; }

    return fd;
}
Beispiel #5
0
static void
handle_exec(Event * event) {
	Process * proc = event->proc;
	pid_t saved_pid;

	debug(DEBUG_FUNCTION, "handle_exec(pid=%d)", proc->pid);
	if (proc->state == STATE_IGNORED) {
		untrace_pid(proc->pid);
		remove_process(proc);
		return;
	}
	output_line(proc, "--- Called exec() ---");
	proc->mask_32bit = 0;
	proc->personality = 0;
	proc->arch_ptr = NULL;
	free(proc->filename);
	proc->filename = pid2name(proc->pid);
	saved_pid = proc->pid;
	proc->pid = 0;
	breakpoints_init(proc, 0);
	proc->pid = saved_pid;
	proc->callstack_depth = 0;
	continue_process(proc->pid);
}
Beispiel #6
0
int
process_clone(struct Process *retp, struct Process *proc, pid_t pid)
{
	if (process_bare_init(retp, proc->filename, pid, 0) < 0) {
	fail1:
		fprintf(stderr, "failed to clone process %d->%d : %s\n",
			proc->pid, pid, strerror(errno));
		return -1;
	}

	retp->tracesysgood = proc->tracesysgood;
	retp->e_machine = proc->e_machine;
	retp->e_class = proc->e_class;

	/* For non-leader processes, that's all we need to do.  */
	if (retp->leader != retp)
		return 0;

	/* Clone symbols first so that we can clone and relink
	 * breakpoints.  */
	struct library *lib;
	struct library **nlibp = &retp->libraries;
	for (lib = proc->leader->libraries; lib != NULL; lib = lib->next) {
		*nlibp = malloc(sizeof(**nlibp));
		if (*nlibp == NULL
		    || library_clone(*nlibp, lib) < 0) {
		fail2:
			process_bare_destroy(retp, 0);

			/* Error when cloning.  Unroll what was done.  */
			for (lib = retp->libraries; lib != NULL; ) {
				struct library *next = lib->next;
				library_destroy(lib);
				free(lib);
				lib = next;
			}
			goto fail1;
		}

		nlibp = &(*nlibp)->next;
	}

	/* Now clone breakpoints.  Symbol relinking is done in
	 * clone_single_bp.  */
	struct clone_single_bp_data data = {
		.old_proc = proc,
		.new_proc = retp,
		.error = 0,
	};
	dict_apply_to_all(proc->leader->breakpoints, &clone_single_bp, &data);
	if (data.error < 0)
		goto fail2;

	/* And finally the call stack.  */
	/* XXX clearly the callstack handling should be moved to a
	 * separate module and this whole business extracted to
	 * callstack_clone, or callstack_element_clone.  */
	memcpy(retp->callstack, proc->callstack, sizeof(retp->callstack));
	retp->callstack_depth = proc->callstack_depth;

	size_t i;
	for (i = 0; i < retp->callstack_depth; ++i) {
		struct callstack_element *elem = &retp->callstack[i];
		struct fetch_context *ctx = elem->fetch_context;
		if (ctx != NULL) {
			struct fetch_context *nctx = fetch_arg_clone(retp, ctx);
			if (nctx == NULL) {
				size_t j;
			fail3:
				for (j = 0; j < i; ++j) {
					nctx = elem->fetch_context;
					fetch_arg_done(nctx);
					elem->fetch_context = NULL;
				}
				goto fail2;
			}
			elem->fetch_context = nctx;
		}

		struct value_dict *args = elem->arguments;
		if (args != NULL) {
			struct value_dict *nargs = malloc(sizeof(*nargs));
			if (nargs == NULL
			    || val_dict_clone(nargs, args) < 0) {
				size_t j;
				for (j = 0; j < i; ++j) {
					nargs = elem->arguments;
					val_dict_destroy(nargs);
					free(nargs);
					elem->arguments = NULL;
				}

				/* Pretend that this round went well,
				 * so that fail3 frees I-th
				 * fetch_context.  */
				++i;
				goto fail3;
			}
			elem->arguments = nargs;
		}

		/* If it's not a syscall, we need to find the
		 * corresponding library symbol in the cloned
		 * library.  */
		if (!elem->is_syscall && elem->c_un.libfunc != NULL) {
			struct library_symbol *libfunc = elem->c_un.libfunc;
			int rc = proc_find_symbol(retp, libfunc,
						  NULL, &elem->c_un.libfunc);
			assert(rc == 0);
		}
	}

	/* At this point, retp is fully initialized, except for OS and
	 * arch parts, and we can call private_process_destroy.  */
	if (os_process_clone(retp, proc) < 0) {
		private_process_destroy(retp, 0);
		return -1;
	}
	if (arch_process_clone(retp, proc) < 0) {
		os_process_destroy(retp);
		private_process_destroy(retp, 0);
		return -1;
	}

	return 0;
}

static int
open_one_pid(pid_t pid)
{
	Process *proc;
	char *filename;
	debug(DEBUG_PROCESS, "open_one_pid(pid=%d)", pid);

	/* Get the filename first.  Should the trace_pid fail, we can
	 * easily free it, untracing is more work.  */
	if ((filename = pid2name(pid)) == NULL
	    || trace_pid(pid) < 0) {
	fail:
		free(filename);
		return -1;
	}

	proc = open_program(filename, pid);
	if (proc == NULL)
		goto fail;
	free(filename);
	trace_set_options(proc);

	return 0;
}
Beispiel #7
0
struct libref *elf_read_main_binary(struct task *task, int was_attached)
{
	char fname[PATH_MAX];
	int ret;
	char *filename;
	struct mt_elf mte = { };
	unsigned long entry;
	unsigned long base;
	struct libref *libref;

	filename = pid2name(task->pid);
	if (!filename)
		return NULL;

	libref = libref_new(LIBTYPE_MAIN);
	if (libref == NULL)
		goto fail1;

	ret = readlink(filename, fname, sizeof(fname) - 1);
	if (ret == -1)
		goto fail2;

	fname[ret] = 0;

	free(filename);

	libref_set_filename(libref, fname);

	if (elf_read(&mte, task, fname) == -1)
		goto fail3;

	task->is_64bit = is_64bit(&mte);

	if (process_get_entry(task, &entry, &base) < 0) {
		fprintf(stderr, "Couldn't find process entry of %s\n", filename);
		goto fail3;
	}

	mte.bias = entry - mte.ehdr.e_entry - mte.vstart;
	mte.entry_addr = entry;

	if (elf_lib_init(&mte, task, libref))
		goto fail3;

	close_elf(&mte);

	report_attach(task, was_attached);

	library_add(task, libref);

	if (!mte.interp)
		return libref;

	struct mt_elf mte_ld = { };

	if (copy_str_from_proc(task, ARCH_ADDR_T(mte.bias + mte.interp - mte.vstart), fname, sizeof(fname)) == -1) {
		fprintf(stderr, "fatal error: cannot get loader name for pid=%d\n", task->pid);
		abort();
	}

	if (!elf_read(&mte_ld, task, fname)) {
		struct libref *libref;

		libref = libref_new(LIBTYPE_LOADER);
		if (libref == NULL)
			goto fail4;

		libref_set_filename(libref, fname);

		mte_ld.bias = base;
		mte_ld.entry_addr = base + mte_ld.ehdr.e_entry  - mte.vstart;

		ret = elf_lib_init(&mte_ld, task, libref);
		if (!ret) {
			library_add(task, libref);

			if (linkmap_init(task, ARCH_ADDR_T(mte.bias + mte.dyn - mte.vstart))) {
				arch_addr_t addr = find_solib_break(&mte_ld);
				if (!addr)
					addr = ARCH_ADDR_T(entry);

				struct entry_breakpoint *entry_bp = (void *)breakpoint_new_ext(task, addr, NULL, 0, sizeof(*entry_bp) - sizeof(entry_bp->breakpoint));
				if (!entry_bp)
					fprintf(stderr,
						"Couldn't initialize entry breakpoint for PID %d.\n"
						"Tracing events may be missed.\n",
						task->pid
					);
				else {
					entry_bp->breakpoint.on_hit = entry_breakpoint_on_hit;
					entry_bp->breakpoint.locked = 1;
					entry_bp->dyn_addr = ARCH_ADDR_T(mte.bias + mte.dyn - mte.vstart);

					breakpoint_enable(task, &entry_bp->breakpoint);
				}
			}
		}
		else {
			fprintf(stderr,
				"Couldn't read dynamic loader `%s` for PID %d.\n"
				"Tracing events may be missed.\n",
				fname,
				task->pid
			);
		}
fail4:
		close_elf(&mte_ld);
	}
	else {
		fprintf(stderr,
			"Couldn't open dynamic loader `%s` for PID %d.\n"
			"Tracing events may be missed.\n",
			fname,
			task->pid
		);
	}

	return libref;
fail3:
	close_elf(&mte);
fail2:
	libref_delete(libref);
fail1:
	free(filename);
	return libref;
}