Beispiel #1
0
static int __open_proc (RIOW32Dbg *dbg, bool attach) {
	DEBUG_EVENT de;
	int ret = -1;
	HANDLE h_proc = OpenProcess (PROCESS_ALL_ACCESS, FALSE, dbg->pid);

	if (!h_proc) {
		r_sys_perror ("__open_proc/OpenProcess");
		goto att_exit;
	}
	if (attach) {
		/* Attach to the process */
		if (!DebugActiveProcess(dbg->pid)) {
			r_sys_perror ("__open_proc/DebugActiveProcess");
			goto att_exit;
		}
		/* catch create process event */
		if (!WaitForDebugEvent (&de, 10000)) {
			r_sys_perror ("__open_proc/WaitForDebugEvent");
			goto att_exit;
		}
		if (de.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) {
			eprintf ("exception code 0x%04x\n", (ut32)de.dwDebugEventCode);
			goto att_exit;
		}
		dbg->winbase = (ut64)de.u.CreateProcessInfo.lpBaseOfImage;
	}
	dbg->pi.hProcess = h_proc;
	dbg->tid = __w32_first_thread (dbg->pid);
	ret = dbg->pid;
att_exit:
	if (ret == -1 && h_proc) {
		CloseHandle (h_proc);
	}
	return ret;
}
Beispiel #2
0
static int setup_tokens() {
        HANDLE tok;
        TOKEN_PRIVILEGES tp; 
        DWORD err;

        tok = NULL;
        err = -1; 

        if (!OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, &tok))
                goto err_enable;

        tp.PrivilegeCount = 1;
        if (!LookupPrivilegeValue (NULL,  SE_DEBUG_NAME, &tp.Privileges[0].Luid))
                goto err_enable;

        //tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
        tp.Privileges[0].Attributes = 0; //SE_PRIVILEGE_ENABLED;
        if (!AdjustTokenPrivileges (tok, 0, &tp, sizeof (tp), NULL, NULL)) 
                goto err_enable;
        err = 0;
err_enable:
        if (tok != NULL)
                CloseHandle (tok);
        if (err)
		r_sys_perror ("setup_tokens");
        return err;
}
Beispiel #3
0
R_API bool r_sys_create_child_proc_w32(const char *cmdline, HANDLE out) {
	PROCESS_INFORMATION pi = {0};
	STARTUPINFO si = {0};
	LPTSTR cmdline_;
	bool ret;

	// Set up members of the STARTUPINFO structure.
	// This structure specifies the STDIN and STDOUT handles for redirection.
	si.cb = sizeof (STARTUPINFO);
	si.hStdError = out;
	si.hStdOutput = out;
	si.hStdInput = NULL;
	si.dwFlags |= STARTF_USESTDHANDLES;
	cmdline_ = r_sys_conv_utf8_to_utf16 (cmdline);
	if ((ret = CreateProcess (NULL,
			cmdline_,// command line
			NULL,          // process security attributes
			NULL,          // primary thread security attributes
			TRUE,          // handles are inherited
			0,             // creation flags
			NULL,          // use parent's environment
			NULL,          // use parent's current directory
			&si,  // STARTUPINFO pointer
			&pi))) {  // receives PROCESS_INFORMATION 
		ret = 1;
		CloseHandle (pi.hProcess);
		CloseHandle (pi.hThread);
	} else {
		r_sys_perror ("CreateProcess");
	}
	free (cmdline_);
	return ret;
}
Beispiel #4
0
// UNUSED
static void trace_me () {
#if __APPLE__
	signal (SIGTRAP, SIG_IGN); //NEED BY STEP
#endif
#if __APPLE__ || __BSD__
	/* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */
	signal (SIGABRT, inferior_abort_handler);
	if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) {
		r_sys_perror ("ptrace-traceme");
	}
#else
	if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) {
		r_sys_perror ("ptrace-traceme");
		exit (MAGIC_EXIT);
	}
#endif
}
Beispiel #5
0
static int iob_pipe_write(void *p, const uint8_t *buf, const uint64_t count, const int timeout) {
	int ret = send ((int) (size_t) p, buf, count, 0);
	if (ret < 1) {
		r_sys_perror ("iob_pipe_write, send");
		if (errno == EPIPE) {
			exit (1);
		}
	}
	return ret;
}
Beispiel #6
0
/* TODO: must return true/false */
static int r_debug_native_continue(RDebug *dbg, int pid, int tid, int sig) {
#if __WINDOWS__ && !__CYGWIN__
	/* Honor the Windows-specific signal that instructs threads to process exceptions */
	DWORD continue_status = (sig == DBG_EXCEPTION_NOT_HANDLED)
		? DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
	if (ContinueDebugEvent (pid, tid, continue_status) == 0) {
		r_sys_perror ("r_debug_native_continue/ContinueDebugEvent");
		eprintf ("debug_contp: error\n");
		return false;
	}
	return tid;
#elif __APPLE__
	bool ret;
	ret = xnu_continue (dbg, pid, tid, sig);
	if (!ret) {
		return -1;
	}
	return tid;
#elif __BSD__
	void *data = (void*)(size_t)((sig != -1) ? sig : dbg->reason.signum);
	ut64 pc = r_debug_reg_get (dbg, "PC");
	return ptrace (PTRACE_CONT, pid, (void*)(size_t)pc, (int)(size_t)data) == 0;
#elif __CYGWIN__
	#warning "r_debug_native_continue not supported on this platform"
	return -1;
#else
	int contsig = dbg->reason.signum;

	if (sig != -1) {
		contsig = sig;
	}
	/* SIGINT handler for attached processes: dbg.consbreak (disabled by default) */
	if (dbg->consbreak) {
		r_cons_break_push ((RConsBreak)r_debug_native_stop, dbg);
	}

	int ret = ptrace (PTRACE_CONT, pid, NULL, contsig);
	if (ret) {
		perror ("PTRACE_CONT");
	}
	if (dbg->continue_all_threads && dbg->n_threads) {
		RList *list = dbg->threads;
		RDebugPid *th;
		RListIter *it;

		if (list) {
			r_list_foreach (list, it, th) {
				if (th->pid && th->pid != pid) {
					ptrace (PTRACE_CONT, tid, NULL, contsig);
				}
			}
		}
	}
Beispiel #7
0
static int r_bin_te_init_hdr(struct r_bin_te_obj_t *bin) {
	if (!bin)
		return false;
	if (!(bin->header = malloc(sizeof(TE_image_file_header)))) {
		r_sys_perror ("malloc (header)");
		return false;
	}
	if (r_buf_read_at (bin->b, 0, (ut8*)bin->header, sizeof(TE_image_file_header)) == -1) {
		eprintf("Error: read (header)\n");
		return false;
	}
	if (!bin->kv) {
		eprintf("Error: sdb instance is empty\n");
		return false;
	}

	sdb_set (bin->kv, "te_machine.cparse", "enum te_machine { TE_IMAGE_FILE_MACHINE_UNKNOWN=0x0, TE_IMAGE_FILE_MACHINE_ALPHA=0x184, "
	"TE_IMAGE_FILE_MACHINE_ALPHA64=0x284, TE_IMAGE_FILE_MACHINE_AM33=0x1d3, TE_IMAGE_FILE_MACHINE_AMD64=0x8664, "
	"TE_IMAGE_FILE_MACHINE_ARM=0x1c0, TE_IMAGE_FILE_MACHINE_AXP64=0x184, TE_IMAGE_FILE_MACHINE_CEE=0xc0ee, "
	"TE_IMAGE_FILE_MACHINE_CEF=0x0cef, TE_IMAGE_FILE_MACHINE_EBC=0x0ebc, TE_IMAGE_FILE_MACHINE_I386=0x014c, "
	"TE_IMAGE_FILE_MACHINE_IA64=0x0200, TE_IMAGE_FILE_MACHINE_M32R=0x9041, TE_IMAGE_FILE_MACHINE_M68K=0x0268, "
	"TE_IMAGE_FILE_MACHINE_MIPS16=0x0266, TE_IMAGE_FILE_MACHINE_MIPSFPU=0x0366, TE_IMAGE_FILE_MACHINE_MIPSFPU16=0x0466, "
	"TE_IMAGE_FILE_MACHINE_POWERPC=0x01f0, TE_IMAGE_FILE_MACHINE_POWERPCFP=0x01f1, TE_IMAGE_FILE_MACHINE_R10000=0x0168, "
	"TE_IMAGE_FILE_MACHINE_R3000=0x0162, TE_IMAGE_FILE_MACHINE_R4000=0x0166, TE_IMAGE_FILE_MACHINE_SH3=0x01a2, "
	"TE_IMAGE_FILE_MACHINE_SH3DSP=0x01a3, TE_IMAGE_FILE_MACHINE_SH3E=0x01a4, TE_IMAGE_FILE_MACHINE_SH4=0x01a6, "
	"TE_IMAGE_FILE_MACHINE_SH5=0x01a8, TE_IMAGE_FILE_MACHINE_THUMB=0x01c2, TE_IMAGE_FILE_MACHINE_TRICORE=0x0520, "
	"TE_IMAGE_FILE_MACHINE_WCEMIPSV2=0x0169};", 0);
	sdb_set (bin->kv, "te_subsystem.cparse", "enum te_subsystem { TE_IMAGE_SUBSYSTEM_UNKNOWN=0, TE_IMAGE_SUBSYSTEM_NATIVE=1, "
	"TE_IMAGE_SUBSYSTEM_WINDOWS_GUI=2, TE_IMAGE_SUBSYSTEM_WINDOWS_CUI=3, "
	"TE_IMAGE_SUBSYSTEM_POSIX_CUI=7, TE_IMAGE_SUBSYSTEM_WINDOWS_CE_GU=9, "
	"TE_IMAGE_SUBSYSTEM_EFI_APPLICATION=10, TE_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER=11, TE_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER=12, "
	"TE_IMAGE_SUBSYSTEM_EFI_ROM=13, TE_IMAGE_SUBSYSTEM_XBOX=14};", 0);
	sdb_num_set (bin->kv, "te_header.offset", 0, 0);
	sdb_set (bin->kv, "te_header.format", "[2]z[2]Eb[1]Ewxxq"
		" Signature (te_machine)Machine NumberOfSections (te_subsystem)Subsystem StrippedSize AddressOfEntryPoint BaseOfCode ImageBase", 0);
	sdb_num_set (bin->kv, "te_directory1_header.offset", 24, 0);
	sdb_set (bin->kv, "te_directory1_header.format", "xx"
		" VirtualAddress Size", 0);
	sdb_num_set (bin->kv, "te_directory2_header.offset", 32, 0);
	sdb_set (bin->kv, "te_directory2_header.format", "xx"
		" VirtualAddress Size", 0);

	if (strncmp ((char*)&bin->header->Signature, "VZ", 2))
			return false;
	return true;
}
Beispiel #8
0
R_API RSocket *r_socket_accept(RSocket *s) {
	RSocket *sock;
	socklen_t salen = sizeof (s->sa);
	if (!s) {
		return NULL;
	}
	sock = R_NEW0 (RSocket);
	if (!sock) {
		return NULL;
	}
	//signal (SIGPIPE, SIG_DFL);
	sock->fd = accept (s->fd, (struct sockaddr *)&s->sa, &salen);
	if (sock->fd == -1) {
		if (errno != EWOULDBLOCK) {
			// not just a timeout
			r_sys_perror ("accept");
		}
		free (sock);
		return NULL;
	}
#if HAVE_LIB_SSL
	sock->is_ssl = s->is_ssl;
	if (sock->is_ssl) {
		sock->sfd = NULL;
		sock->ctx = NULL;
		sock->bio = NULL;
		BIO *sbio = BIO_new_socket (sock->fd, BIO_NOCLOSE);
		sock->sfd = SSL_new (s->ctx);
		SSL_set_bio (sock->sfd, sbio, sbio);
		if (SSL_accept (sock->sfd) <= 0) {
			r_socket_free (sock);
			return NULL;
		}
		sock->bio = BIO_new (BIO_f_buffer ());
		sbio = BIO_new (BIO_f_ssl ());
		BIO_set_ssl (sbio, sock->sfd, BIO_CLOSE);
		BIO_push (sock->bio, sbio);
	}
#else
	sock->is_ssl = 0;
#endif
	return sock;
}
Beispiel #9
0
static int __w32_first_thread(int pid) {
	HANDLE th;
	HANDLE thid;
	THREADENTRY32 te32;
	te32.dwSize = sizeof (THREADENTRY32);

	th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, pid);
	if (th == INVALID_HANDLE_VALUE) {
		return -1;
	}
	if (!Thread32First (th, &te32)) {
		CloseHandle (th);
		return -1;
	}
	do {
		/* get all threads of process */
		if (te32.th32OwnerProcessID == pid) {
#if __MINGW32__
			r2_OpenThread = r_lib_dl_sym (NULL, "OpenThread");
#else
			r2_OpenThread = OpenThread;
#endif
			thid = r2_OpenThread
			? r2_OpenThread (THREAD_ALL_ACCESS, 0, te32.th32ThreadID) : NULL;
			if (!thid) {
				r_sys_perror ("__w32_first_thread/OpenThread");
				goto err_first_th;
			}
			CloseHandle (th);
			return te32.th32ThreadID;
		}
	} while (Thread32Next (th, &te32));
err_first_th:
	eprintf ("Could not find an active thread for pid %d\n", pid);
	CloseHandle (th);
	return pid;
}
Beispiel #10
0
static RList *r_debug_native_pids (int pid) {
	RList *list = r_list_new ();
	if (!list) return NULL;
#if __WINDOWS__ && !__CYGWIN__
	return w32_pids (pid, list);
#elif __APPLE__
	if (pid) {
		RDebugPid *p = xnu_get_pid (pid);
		if (p) r_list_append (list, p);
	} else {
		int i;
		for (i = 1; i < MAXPID; i++) {
			RDebugPid *p = xnu_get_pid (i);
			if (p) r_list_append (list, p);
		}
	}
#elif __linux__
	int i;
	char *ptr, buf[1024];

	list->free = (RListFree)&r_debug_pid_free;
	if (pid) {
		DIR *dh;
		struct dirent *de;

		/* add the requested pid. should we do this? we don't even know if it's valid still.. */
		r_list_append (list, r_debug_pid_new ("(current)", pid, 's', 0));

		/* list parents */
		dh = opendir ("/proc");
		if (!dh) {
			r_sys_perror ("opendir /proc");
			r_list_free (list);
			return NULL;
		}
		while ((de = readdir (dh))) {
			/* for each existing pid file... */
			i = atoi (de->d_name);
			if (i <= 0) {
				continue;
			}

			/* try to read the status */
			buf[0] = 0;
			if (procfs_pid_slurp (i, "status", buf, sizeof (buf)) == -1) {
				continue;
			}
			buf[sizeof (buf) - 1] = 0;

			/* look for the parent process id */
			ptr = strstr (buf, "PPid:");
			if (ptr) {
				int ppid = atoi (ptr + 6);

				/* if this is the requested process... */
				if (i == pid) {
					//eprintf ("PPid: %d\n", ppid);
					/* append it to the list with parent */
					r_list_append (list, r_debug_pid_new (
						"(ppid)", ppid, 's', 0));
				}

				/* ignore it if it is not one of our children */
				if (ppid != pid) {
					continue;
				}

				/* it's a child of the requested pid, read it's command line and add it */
				if (procfs_pid_slurp (ppid, "cmdline", buf, sizeof(buf)) == -1) {
					continue;
				}

				r_list_append (list, r_debug_pid_new (buf, i, 's', 0));
			}
		}
		closedir (dh);
	} else {
		/* try to bruteforce the processes
		 * XXX(jjd): wouldn't listing the processes like before work better?
		 */
		for (i = 2; i < MAXPID; i++) {
			/* try to send signal 0, if it fails it must not be valid */
			if (r_sandbox_kill (i, 0) == -1)
				continue;

			if (procfs_pid_slurp (i, "cmdline", buf, sizeof(buf)) == -1)
				continue;

			r_list_append (list, r_debug_pid_new (buf, i, 's', 0));
		}
	}
#else /* rest is BSD */
#ifdef __NetBSD__
# define KVM_OPEN_FLAG KVM_NO_FILES
# define KVM_GETPROCS(kd, opt, arg, cntptr) \
	kvm_getproc2 (kd, opt, arg, sizeof(struct kinfo_proc2), cntptr)
# define KP_COMM(x) (x)->p_comm
# define KP_PID(x) (x)->p_pid
# define KP_PPID(x) (x)->p_ppid
# define KINFO_PROC kinfo_proc2
#elif defined(__OpenBSD__)
# define KVM_OPEN_FLAG KVM_NO_FILES
# define KVM_GETPROCS(kd, opt, arg, cntptr) \
	kvm_getprocs (kd, opt, arg, sizeof(struct kinfo_proc), cntptr)
# define KP_COMM(x) (x)->p_comm
# define KP_PID(x) (x)->p_pid
# define KP_PPID(x) (x)->p_ppid
# define KINFO_PROC kinfo_proc
#else
# define KVM_OPEN_FLAG O_RDONLY
# define KVM_GETPROCS(kd, opt, arg, cntptr) \
	kvm_getprocs (kd, opt, arg, cntptr)
# define KP_COMM(x) (x)->ki_comm
# define KP_PID(x) (x)->ki_pid
# define KP_PPID(x) (x)->ki_ppid
# define KINFO_PROC kinfo_proc
#endif
	char errbuf[_POSIX2_LINE_MAX];
	struct KINFO_PROC* kp;
	int cnt = 0;
	kvm_t* kd = kvm_openfiles (NULL, NULL, NULL, KVM_OPEN_FLAG, errbuf);
	if (!kd) {
		eprintf ("kvm_openfiles says %s\n", errbuf);
		return NULL;
	}

	if (pid) {
		kp = KVM_GETPROCS (kd, KERN_PROC_PID, pid, &cnt);
		if (cnt == 1) {
			RDebugPid *p = r_debug_pid_new (KP_COMM(kp), pid, 's', 0);
			if (p) r_list_append (list, p);
			/* we got our process, now fetch the parent process */
			kp = KVM_GETPROCS (kd, KERN_PROC_PID, KP_PPID(kp), &cnt);
                        if (cnt == 1) {
				RDebugPid *p = r_debug_pid_new (KP_COMM(kp), KP_PID(kp), 's', 0);
				if (p) r_list_append (list, p);
			}
		}
	} else {
		kp = KVM_GETPROCS (kd, KERN_PROC_UID, geteuid(), &cnt);
		int i;
		for (i = 0; i < cnt; i++) {
			RDebugPid *p = r_debug_pid_new (KP_COMM(kp + i), KP_PID(kp + i), 's', 0);
			if (p) r_list_append (list, p);
		}
	}
	kvm_close(kd);
#endif
	return list;
}
Beispiel #11
0
/*
 * wait for an event and start trying to figure out what to do with it.
 *
 * Returns R_DEBUG_REASON_*
 */
static RDebugReasonType r_debug_native_wait (RDebug *dbg, int pid) {
	int status = -1;
	RDebugReasonType reason = R_DEBUG_REASON_UNKNOWN;

#if __WINDOWS__ && !__CYGWIN__
	int mode = 0;
	reason = w32_dbg_wait (dbg, pid);
	if (reason == R_DEBUG_REASON_NEW_LIB) {
		mode = 'l';
	} else if (reason == R_DEBUG_REASON_EXIT_LIB) {
		mode = 'u';
	} else {
		mode = 0;
	}
	if (mode) {
		RDebugInfo *r = r_debug_native_info (dbg, "");
		if (r && r->lib) {
			if (tracelib (dbg, mode=='l'? "load":"unload", r->lib))
				reason = R_DEBUG_REASON_TRAP;
		} else {
			eprintf ("%soading unknown library.\n", mode?"L":"Unl");
		}
		r_debug_info_free (r);
	}
#else
	if (pid == -1) {
		eprintf ("r_debug_native_wait called with -1 pid!\n");
		return R_DEBUG_REASON_ERROR;
	}

#if __APPLE__
	// eprintf ("No waitpid here :D\n");
	reason = xnu_wait (dbg, pid);
	status = reason? 1: 0;
#else
	// XXX: this is blocking, ^C will be ignored
#ifdef WAIT_ON_ALL_CHILDREN
	//eprintf ("waiting on all children ...\n");
	int ret = waitpid (-1, &status, WAITPID_FLAGS);
#else
	//eprintf ("waiting on pid %d ...\n", pid);
	int ret = waitpid (pid, &status, WAITPID_FLAGS);
#endif // WAIT_ON_ALL_CHILDREN
	if (ret == -1) {
		r_sys_perror ("waitpid");
		return R_DEBUG_REASON_ERROR;
	}

	//eprintf ("r_debug_native_wait: status=%d (0x%x) (return=%d)\n", status, status, ret);

#ifdef WAIT_ON_ALL_CHILDREN
	if (ret != pid) {
		reason = R_DEBUG_REASON_NEW_PID;
		eprintf ("switching to pid %d\n", ret);
		r_debug_select(dbg, ret, ret);
	}
#endif // WAIT_ON_ALL_CHILDREN

	// TODO: switch status and handle reasons here
#if __linux__ && defined(PT_GETEVENTMSG)
	reason = linux_ptrace_event (dbg, pid, status);
#endif // __linux__

	/* propagate errors */
	if (reason == R_DEBUG_REASON_ERROR) {
		return reason;
	}

	/* we don't know what to do yet, let's try harder to figure it out. */
	if (reason == R_DEBUG_REASON_UNKNOWN) {
		if (WIFEXITED (status)) {
			eprintf ("child exited with status %d\n", WEXITSTATUS (status));
			reason = R_DEBUG_REASON_DEAD;
		} else if (WIFSIGNALED (status)) {
			eprintf ("child received signal %d\n", WTERMSIG (status));
			reason = R_DEBUG_REASON_SIGNAL;
		} else if (WIFSTOPPED (status)) {
			if (WSTOPSIG (status) != SIGTRAP) {
				eprintf ("child stopped with signal %d\n", WSTOPSIG (status));
			}

			/* this one might be good enough... */
			dbg->reason.signum = WSTOPSIG (status);

			/* the ptrace documentation says GETSIGINFO is only necessary for
			 * differentiating the various stops.
			 *
			 * this might modify dbg->reason.signum
			 */
			if (!r_debug_handle_signals (dbg))
				return R_DEBUG_REASON_ERROR;
			reason = dbg->reason.type;
		} else if (WIFCONTINUED (status)) {
			eprintf ("child continued...\n");
			reason = R_DEBUG_REASON_NONE;
		} else if (status == 1) {
			/* XXX(jjd): does this actually happen? */
			eprintf ("EEK DEAD DEBUGEE!\n");
			reason = R_DEBUG_REASON_DEAD;
		} else if (status == 0) {
			/* XXX(jjd): does this actually happen? */
			eprintf ("STATUS=0?!?!?!?\n");
			reason = R_DEBUG_REASON_DEAD;
		} else {
			if (ret != pid) {
				reason = R_DEBUG_REASON_NEW_PID;
			} else {
				/* ugh. still don't know :-/ */
				eprintf ("CRAP. returning from wait without knowing why...\n");
			}
		}
	}

	/* if we still don't know what to do, we have a problem... */
	if (reason == R_DEBUG_REASON_UNKNOWN) {
		eprintf ("%s: no idea what happened... wtf?!?!\n", __func__);
		reason = R_DEBUG_REASON_ERROR;
	}
#endif // __APPLE__
#endif // __WINDOWS__ && !__CYGWIN__

	dbg->reason.tid = pid;
	dbg->reason.type = reason;
	return reason;
}
R_API int r_socket_listen (RSocket *s, const char *port, const char *certfile) {
#if __UNIX__ || defined(__CYGWIN__)
	int optval = 1;
	int ret;
	struct linger linger = { 0 };
#endif
	if (r_sandbox_enable (0))
		return false;
#if __WINDOWS__ && !defined(__CYGWIN__) && !defined(__MINGW64__)
	WSADATA wsadata;
	if (WSAStartup (MAKEWORD (1, 1), &wsadata) == SOCKET_ERROR) {
		eprintf ("Error creating socket.");
		return false;
	}
#endif
	if ((s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP))<0)
		return false;
#if __UNIX__ || defined(__CYGWIN__)
	linger.l_onoff = 1;
	linger.l_linger = 1;
	ret = setsockopt (s->fd, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof (linger));
	if (ret < 0)
		return false;
	{ // fix close after write bug //
	int x = 1500; // FORCE MTU
	ret = setsockopt (s->fd, SOL_SOCKET, SO_SNDBUF, (void*)&x, sizeof (int));
	if (ret < 0)
		return false;
	}
	ret = setsockopt (s->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof optval);
	if (ret < 0)
		return false;
#endif
	memset (&s->sa, 0, sizeof (s->sa));
	s->sa.sin_family = AF_INET;
	s->sa.sin_addr.s_addr = htonl (s->local? INADDR_LOOPBACK: INADDR_ANY);
	s->port = r_socket_port_by_name (port);
	if (s->port <1)
		return false;
	s->sa.sin_port = htons (s->port); // TODO honor etc/services

	if (bind (s->fd, (struct sockaddr *)&s->sa, sizeof(s->sa)) < 0) {
		r_sys_perror ("bind");
		close (s->fd);
		return false;
	}
#if __UNIX__ || defined(__CYGWIN__)
	signal (SIGPIPE, SIG_IGN);
#endif
	if (listen (s->fd, 32) < 0) {
		close (s->fd);
		return false;
	}
#if HAVE_LIB_SSL
	if (s->is_ssl) {
		s->ctx = SSL_CTX_new (SSLv23_method ());
		if (s->ctx == NULL) {
			r_socket_free (s);
			return false;
		}
		if (!SSL_CTX_use_certificate_chain_file (s->ctx, certfile)) {
			r_socket_free (s);
			return false;
		}
		if (!SSL_CTX_use_PrivateKey_file (s->ctx, certfile, SSL_FILETYPE_PEM)) {
			r_socket_free (s);
			return false;
		}
		SSL_CTX_set_verify_depth (s->ctx, 1);
	}
#endif
	return true;
}
Beispiel #13
0
static int r_bin_mz_init_hdr(struct r_bin_mz_obj_t* bin) {
	int relocations_size, dos_file_size;
	if (!(bin->dos_header = R_NEW0 (MZ_image_dos_header))) {
		r_sys_perror ("malloc (MZ_image_dos_header)");
		return false;
	}
	// TODO: read field by field to avoid endian and alignment issues
	if (r_buf_read_at (bin->b, 0, (ut8*)bin->dos_header,
			sizeof (*bin->dos_header)) == -1) {
		eprintf ("Error: read (MZ_image_dos_header)\n");
		return false;
	}

	if (bin->dos_header->blocks_in_file < 1) {
		return false;
	}
	dos_file_size = ((bin->dos_header->blocks_in_file - 1) << 9) + \
			bin->dos_header->bytes_in_last_block;

	bin->dos_file_size = dos_file_size;
	if (dos_file_size > bin->size) {
		return false;
	}
	relocations_size = bin->dos_header->num_relocs * sizeof (MZ_image_relocation_entry);
	if ((bin->dos_header->reloc_table_offset + relocations_size) > bin->size) {
		return false;
	}

	sdb_num_set (bin->kv, "mz.initial.cs", bin->dos_header->cs, 0);
	sdb_num_set (bin->kv, "mz.initial.ip", bin->dos_header->ip, 0);
	sdb_num_set (bin->kv, "mz.initial.ss", bin->dos_header->ss, 0);
	sdb_num_set (bin->kv, "mz.initial.sp", bin->dos_header->sp, 0);
	sdb_num_set (bin->kv, "mz.overlay_number", bin->dos_header->overlay_number, 0);
	sdb_num_set (bin->kv, "mz.dos_header.offset", 0, 0);
	sdb_set (bin->kv, "mz.dos_header.format", "[2]zwwwwwwwwwwwww"
			" signature bytes_in_last_block blocks_in_file num_relocs "
			" header_paragraphs min_extra_paragraphs max_extra_paragraphs "
			" ss sp checksum ip cs reloc_table_offset overlay_number ", 0);

	bin->dos_extended_header_size = bin->dos_header->reloc_table_offset - \
		sizeof (MZ_image_dos_header);

	if (bin->dos_extended_header_size > 0) {
		if (!(bin->dos_extended_header =
			      malloc (bin->dos_extended_header_size))) {
			r_sys_perror ("malloc (dos extended header)");
			return false;
		}
		if (r_buf_read_at (bin->b, sizeof (MZ_image_dos_header),
				(ut8*)bin->dos_extended_header,
				bin->dos_extended_header_size) == -1) {
			eprintf ("Error: read (dos extended header)\n");
			return false;
		}
	}

	if (relocations_size > 0) {
		if (!(bin->relocation_entries = malloc (relocations_size))) {
			r_sys_perror ("malloc (dos relocation entries)");
			return false;
		}
		if (r_buf_read_at (bin->b, bin->dos_header->reloc_table_offset,
				(ut8*)bin->relocation_entries, relocations_size) == -1) {
			eprintf ("Error: read (dos relocation entries)\n");
			R_FREE (bin->relocation_entries);
			return false;
		}
	}
	return true;
}
Beispiel #14
0
// __UNIX__ (not windows)
static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) {
	char **argv;
	int ret, status, pid = fork ();
	switch (pid) {
	case -1:
		perror ("fork_and_ptraceme");
		break;
	case 0:
#if __APPLE__
		signal (SIGTRAP, SIG_IGN); //NEED BY STEP 
#endif
#if __APPLE__ || __BSD__
/* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */
		signal (SIGABRT, inferior_abort_handler);
		if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) {
#else
		if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) {
#endif
			r_sys_perror ("ptrace-traceme");
			exit (MAGIC_EXIT);
		}
		{
			char *expr = NULL;
			int i;
			RRunProfile *rp = r_run_new (NULL);
			argv = r_str_argv (cmd, NULL);
			for (i=0; argv[i]; i++) {
				rp->_args[i] = argv[i];
			}
			rp->_args[i] = NULL;
			rp->_program = argv[0];
			if (io->runprofile && *io->runprofile) {
				if (!r_run_parsefile (rp, io->runprofile)) {
					eprintf ("Can't find profile '%s'\n", io->runprofile);
					exit (MAGIC_EXIT);
				}
			}
			if (bits==64)
				r_run_parseline (rp, expr=strdup ("bits=64"));
			else if (bits==32)
				r_run_parseline (rp, expr=strdup ("bits=32"));
			free (expr);
			r_run_start (rp);
			r_run_free (rp);
			// double free wtf
		//	r_str_argv_free (argv);
			exit (1);
		}
		perror ("fork_and_attach: execv");
		//printf(stderr, "[%d] %s execv failed.\n", getpid(), ps.filename);
		exit (MAGIC_EXIT); /* error */
		return 0; // invalid pid // if exit is overriden.. :)
	default:
		/* XXX: clean this dirty code */
                ret = wait (&status);
		if (ret != pid)
			eprintf ("Wait event received by different pid %d\n", ret);
                if (WIFSTOPPED (status))
                        eprintf ("Process with PID %d started...\n", (int)pid);
		if (WEXITSTATUS (status) == MAGIC_EXIT)
			pid = -1;
		// XXX kill (pid, SIGSTOP);
		break;
	}
	eprintf ("PID = %d\n", pid);
	return pid;
}
#endif

static int __plugin_open(RIO *io, const char *file, ut8 many) {
	if (!strncmp (file, "dbg://", 6) && file[6])
		return R_TRUE;
	return R_FALSE;
}

static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
	char uri[128];
	if (__plugin_open (io, file,  0)) {
		int pid = atoi (file+6);
		if (pid == 0) {
			pid = fork_and_ptraceme (io, io->bits, file+6);
			if (pid==-1)
				return NULL;
#if __WINDOWS__
			sprintf (uri, "w32dbg://%d", pid);
#elif __APPLE__
			sprintf (uri, "mach://%d", pid);
#else
			// TODO: use io_procpid here? faster or what?
			sprintf (uri, "ptrace://%d", pid);
#endif
			my_io_redirect (io, uri);
		} else {
			sprintf (uri, "attach://%d", pid);
			my_io_redirect (io, uri);
		}
		return NULL;
	}
	my_io_redirect (io, NULL);
	return NULL;
}
Beispiel #15
0
static void trace_me () {
#if __APPLE__
	signal (SIGTRAP, SIG_IGN); //NEED BY STEP
#endif
#if __APPLE__ || __BSD__
/* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */
	signal (SIGABRT, inferior_abort_handler);
	if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) {
#else
	if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) {
#endif
		r_sys_perror ("ptrace-traceme");
		exit (MAGIC_EXIT);
	}
}

// __UNIX__ (not windows)
static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) {
	bool runprofile = io->runprofile && *(io->runprofile);
	char **argv;
#if __APPLE__ && !__POWERPC__
	if (!runprofile) {
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
		posix_spawn_file_actions_t fileActions;
		ut32 ps_flags = POSIX_SPAWN_SETSIGDEF |
				POSIX_SPAWN_SETSIGMASK;
   		sigset_t no_signals;
    		sigset_t all_signals;
    		sigemptyset (&no_signals);
    		sigfillset (&all_signals);
		posix_spawnattr_t attr = {0};
		size_t copied = 1;
		cpu_type_t cpu;
		pid_t p = -1;
		int ret, useASLR = io->aslr;
		char *_cmd = io->args ?
				r_str_concatf (strdup (cmd), " %s", io->args) :
				strdup (cmd);
		argv = r_str_argv (_cmd, NULL);
		if (!argv) {
			free (_cmd);
			return -1;
		}
		if (!*argv) {
			r_str_argv_free (argv);
			free (_cmd);
			eprintf ("Invalid execvp\n");
			return -1;
		}
		posix_spawnattr_init (&attr);
		if (useASLR != -1) {
			if (!useASLR) ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
		}

		posix_spawn_file_actions_init (&fileActions);
		posix_spawn_file_actions_addinherit_np (&fileActions, STDIN_FILENO);
		posix_spawn_file_actions_addinherit_np (&fileActions, STDOUT_FILENO);
		posix_spawn_file_actions_addinherit_np (&fileActions, STDERR_FILENO);
		ps_flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
		ps_flags |= POSIX_SPAWN_START_SUSPENDED;

   		posix_spawnattr_setsigmask(&attr, &no_signals);
    		posix_spawnattr_setsigdefault(&attr, &all_signals);

		(void)posix_spawnattr_setflags (&attr, ps_flags);
#if __i386__ || __x86_64__
		cpu = CPU_TYPE_I386;
		if (bits == 64) cpu |= CPU_ARCH_ABI64;
#else
		cpu = CPU_TYPE_ANY;
#endif
		posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &copied);
		{
			char *dst = r_file_readlink (argv[0]);
			if (dst) {
				argv[0] = dst;
			}
		}
		ret = posix_spawnp (&p, argv[0], &fileActions, &attr, argv, NULL);
		switch (ret) {
		case 0:
			// eprintf ("Success\n");
			break;
		case 22:
			eprintf ("posix_spawnp: Invalid argument\n");
			break;
		case 86:
			eprintf ("Unsupported architecture\n");
			break;
		default:
			eprintf ("posix_spawnp: unknown error %d\n", ret);
			perror ("posix_spawnp");
			break;
		}
		posix_spawn_file_actions_destroy (&fileActions);
		r_str_argv_free (argv);
		free (_cmd);
		return p;
	}
#endif
	int ret, status, child_pid;

	child_pid = r_sys_fork ();
	switch (child_pid) {
	case -1:
		perror ("fork_and_ptraceme");
		break;
	case 0:
		if (runprofile) {
			char *expr = NULL;
			int i;
			RRunProfile *rp = r_run_new (NULL);
			argv = r_str_argv (cmd, NULL);
			for (i = 0; argv[i]; i++) {
				rp->_args[i] = argv[i];
			}
			rp->_args[i] = NULL;
			rp->_program = argv[0];
			rp->_dodebug = true;
			if (io->runprofile && *io->runprofile) {
				if (!r_run_parsefile (rp, io->runprofile)) {
					eprintf ("Can't find profile '%s'\n",
						io->runprofile);
					exit (MAGIC_EXIT);
				}
			}
			if (bits == 64)
				r_run_parseline (rp, expr=strdup ("bits=64"));
			else if (bits == 32)
				r_run_parseline (rp, expr=strdup ("bits=32"));
			free (expr);
			if (r_run_config_env (rp)) {
				eprintf ("Can't config the environment.\n");
				exit (1);
			}
			trace_me ();
			r_run_start (rp);
			r_run_free (rp);
			r_str_argv_free (argv);
			exit (1);
		} else {
			char *_cmd = io->args ?
				r_str_concatf (strdup (cmd), " %s", io->args) :
				strdup (cmd);

			trace_me ();
			argv = r_str_argv (_cmd, NULL);
			if (!argv) {
				free (_cmd);
				return -1;
			}
			if (argv && *argv) {
				int i;
				for (i = 3; i < 1024; i++)
					(void)close (i);
				execvp (argv[0], argv);
			} else {
				eprintf ("Invalid execvp\n");
			}
			r_str_argv_free (argv);
			free (_cmd);
		}
		perror ("fork_and_attach: execv");
		//printf(stderr, "[%d] %s execv failed.\n", getpid(), ps.filename);
		exit (MAGIC_EXIT); /* error */
		return 0; // invalid pid // if exit is overriden.. :)
	default:
		/* XXX: clean this dirty code */
		do {
			ret = wait (&status);
			if (ret == -1) return -1;
			if (ret != child_pid) {
				eprintf ("Wait event received by "
					"different pid %d\n", ret);
			}
		} while (ret != child_pid);
		if (WIFSTOPPED (status))
			eprintf ("Process with PID %d started...\n", (int)child_pid);
		if (WEXITSTATUS (status) == MAGIC_EXIT)
			child_pid = -1;
		// XXX kill (pid, SIGSTOP);
		break;
	}
	return child_pid;
}
Beispiel #16
0
static int cmd_meta_comment(RCore *core, const char *input) {
	ut64 addr = core->offset;
	switch (input[1]) {
	case '?': {
		const char* help_msg[] = {
			"Usage:", "CC[-+!*au] [base64:..|str] @ addr", "",
			"CC", "", "list all comments in human friendly form",
			"CC*", "", "list all comments in r2 commands",
			"CC.", "", "show comment at current offset",
			"CC,", " [file]", "show or set comment file",
			"CC", " or maybe not", "append comment at current address",
			"CC+", " same as above", "append comment at current address",
			"CC!", "", "edit comment using cfg.editor (vim, ..)",
			"CC-", " @ cmt_addr", "remove comment at given address",
			"CCu", " good boy @ addr", "add good boy comment at given address",
			"CCu", " base64:AA== @ addr", "add comment in base64",
			NULL};
		r_core_cmd_help (core, help_msg);
		} break;
	case ',': // "CC,"
		if (input[2]=='?') {
			eprintf ("Usage: CC, [file]\n");
		} else if (input[2]==' ') {
			const char *fn = input+2;
			char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
			while (*fn== ' ')fn++;
			if (comment && *comment) {
				// append filename in current comment
				char *nc = r_str_newf ("%s ,(%s)", comment, fn);
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc);
				free (nc);
			} else {
				char *comment = r_str_newf (",(%s)", fn);
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, comment);
				free (comment);
			}
		} else {
			char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
			if (comment && *comment) {
				char *cmtfile = r_str_between (comment, ",(", ")");
				if (cmtfile && *cmtfile) {
					char *getcommapath(RCore *core);
					char *cwd = getcommapath (core);
					r_cons_printf ("%s"R_SYS_DIR"%s\n", cwd, cmtfile);
					free (cwd);
				}
				free (cmtfile);
			}
			free (comment);
		}
		break;
	case '.':
		  {
			  char *comment = r_meta_get_string (
					  core->anal, R_META_TYPE_COMMENT, addr);
			  if (comment) {
				  r_cons_println (comment);
				  free (comment);
			  }
		  }
		break;
	case 0:
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 0);
		break;
	case 'j':
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 'j');
		break;
	case '!':
		{
			char *out, *comment = r_meta_get_string (
					core->anal, R_META_TYPE_COMMENT, addr);
			out = r_core_editor (core, NULL, comment);
			if (out) {
				//r_meta_add (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
				r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr);
				//r_meta_del (core->anal->meta, input[0], addr, addr+1, NULL);
				r_meta_set_string (core->anal,
						R_META_TYPE_COMMENT, addr, out);
				free (out);
			}
			free (comment);
		}
		break;
	case '+':
	case ' ':
		{
		const char* newcomment = r_str_chop_ro (input + 2);
		char *text, *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
		char *nc = strdup (newcomment);
		r_str_unescape (nc);
		if (comment) {
			text = malloc (strlen (comment)+strlen (newcomment)+2);
			if (text) {
				strcpy (text, comment);
				strcat (text, "\n");
				strcat (text, nc);
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, text);
				free (text);
			} else {
				r_sys_perror ("malloc");
			}
		} else {
			r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc);
		}
		free (nc);
		}
		break;
	case '*':
		r_meta_list (core->anal, R_META_TYPE_COMMENT, 1);
		break;
	case '-': // "CC-"
		r_meta_del (core->anal, R_META_TYPE_COMMENT, core->offset, 1, NULL);
		break;
	case 'u':
		//
		{
		char *newcomment;
		const char *arg = input + 2;
		while (*arg && *arg == ' ') arg++;
		if (!strncmp (arg, "base64:", 7)) {
			char *s = (char *)sdb_decode (arg+7, NULL);
			if (s) {
				newcomment = s;
			} else {
				newcomment = NULL;
			}
		} else {
			newcomment = strdup (arg);
		}
		if (newcomment) {
			char *comment = r_meta_get_string (
					core->anal, R_META_TYPE_COMMENT, addr);
			if (!comment || (comment && !strstr (comment, newcomment))) {
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT,
						addr, newcomment);
			}
			free (comment);
			free (newcomment);
		}
		}
		break;
	case 'a':
		{
		char *s, *p;
		s = strchr (input, ' ');
		if (s) {
			s = strdup (s+1);
		} else {
			eprintf ("Usage\n");
			return false;
		}
		p = strchr (s, ' ');
		if (p) *p++ = 0;
		ut64 addr;
		if (input[2]=='-') {
			if (input[3]) {
				addr = r_num_math (core->num, input+3);
				r_meta_del (core->anal,
						R_META_TYPE_COMMENT,
						addr, 1, NULL);
			} else eprintf ("Usage: CCa-[address]\n");
			free (s);
			return true;
		}
		addr = r_num_math (core->num, s);
		// Comment at
		if (p) {
			if (input[2]=='+') {
				char *comment = r_meta_get_string (
						core->anal, R_META_TYPE_COMMENT,
						addr);
				if (comment) {
					char* text = r_str_newf ("%s\n%s", comment, p);
					r_meta_add (core->anal,
							R_META_TYPE_COMMENT,
							addr, addr+1, text);
					free (text);
				} else {
					r_meta_add (core->anal,
							R_META_TYPE_COMMENT,
							addr, addr+1, p);
				}
			} else {
				r_meta_add (core->anal,
						R_META_TYPE_COMMENT,
						addr, addr+1, p);
			}
		} else eprintf ("Usage: CCa [address] [comment]\n");
		free (s);
		return true;
		}
	}

	return true;
}
Beispiel #17
0
static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) {
	PROCESS_INFORMATION pi;
        STARTUPINFO si = { sizeof (si) };
        DEBUG_EVENT de;
	int pid, tid;
	HANDLE th = INVALID_HANDLE_VALUE;
	if (!*cmd)
		return -1;
	setup_tokens ();

	char **argv = r_str_argv (cmd, NULL);
	// We need to build a command line with quoted argument and escaped quotes
	int cmd_len = 0;
	int i = 0;
	while (argv[i]) {
		char *current = argv[i];
		int quote_count = 0;
		while ((current = strchr (current, '"')))
			quote_count ++;
		cmd_len += strlen (argv[i]);
		cmd_len += quote_count; // The quotes will add one backslash each
		cmd_len += 2; // Add two enclosing quotes;
		i++;
	}
	cmd_len += i-1; // Add argc-1 spaces

	char *cmdline = malloc ((cmd_len + 1) * sizeof (char));
	int cmd_i = 0; // Next character to write in cmdline
	i = 0;
	while (argv[i]) {
		if (i != 0)
			cmdline[cmd_i++] = ' ';

		cmdline[cmd_i++] = '"';
		
		int arg_i = 0; // Index of current character in orginal argument
		while (argv[i][arg_i]) {
			char c = argv[i][arg_i];
			if (c == '"') {
				cmdline[cmd_i++] = '\\';
			}
			cmdline[cmd_i++] = c;
			arg_i++;
		}

		cmdline[cmd_i++] = '"';
		i++;
	}
	cmdline[cmd_i] = '\0';

        if (!CreateProcess (argv[0], cmdline,
                        NULL, NULL, FALSE,
                        CREATE_NEW_CONSOLE | DEBUG_ONLY_THIS_PROCESS,
                        NULL, NULL, &si, &pi)) {
                r_sys_perror ("CreateProcess");
                return -1;
        }
	free (cmdline);
	r_str_argv_free (argv);

        /* get process id and thread id */
        pid = pi.dwProcessId;
        tid = pi.dwThreadId;

#if 0
        /* load thread list */
	{
		HANDLE h;
		THREADENTRY32 te32;
		HANDLE WINAPI (*win32_openthread)(DWORD, BOOL, DWORD) = NULL;
		win32_openthread = (HANDLE WINAPI (*)(DWORD, BOOL, DWORD))
			GetProcAddress (GetModuleHandle ("kernel32"), "OpenThread");

		th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, pid);
		if (th == INVALID_HANDLE_VALUE || !Thread32First(th, &te32))
			r_sys_perror ("CreateToolhelp32Snapshot");

		do {
			if (te32.th32OwnerProcessID == pid) {
				h = win32_openthread (THREAD_ALL_ACCESS, 0, te32.th32ThreadID);
				if (h == NULL) r_sys_perror ("OpenThread");
				else eprintf ("HANDLE=%p\n", h);
			}
		} while (Thread32Next (th, &te32));
	}
#endif

#if 0
	// Access denied here :?
	if (ContinueDebugEvent (pid, tid, DBG_CONTINUE) == 0) {
		r_sys_perror ("ContinueDebugEvent");
		goto err_fork;
	}
#endif

        /* catch create process event */
        if (!WaitForDebugEvent (&de, 10000))
                goto err_fork;

        /* check if is a create process debug event */
        if (de.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) {
                eprintf ("exception code 0x%04x\n", (ut32)de.dwDebugEventCode);
                goto err_fork;
        }

	if (th != INVALID_HANDLE_VALUE)
		CloseHandle (th);

	eprintf ("PID=%d\n", pid);
	eprintf ("TID=%d\n", tid);
        return pid;

err_fork:
	eprintf ("ERRFORK\n");
        TerminateProcess (pi.hProcess, 1);
	if (th != INVALID_HANDLE_VALUE)
		CloseHandle (th);
        return -1;
}
Beispiel #18
0
// __UNIX__ (not windows)
static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) {
	char **argv;
	int ret, status, pid = r_sys_fork ();
	switch (pid) {
	case -1:
		perror ("fork_and_ptraceme");
		break;
	case 0:
#if __APPLE__
		signal (SIGTRAP, SIG_IGN); //NEED BY STEP 
#endif
#if __APPLE__ || __BSD__
/* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */
		signal (SIGABRT, inferior_abort_handler);
		if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) {
#else
		if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) {
#endif
			r_sys_perror ("ptrace-traceme");
			exit (MAGIC_EXIT);
		}
		if (io->runprofile && *(io->runprofile)) {
			char *expr = NULL;
			int i;
			RRunProfile *rp = r_run_new (NULL);
			argv = r_str_argv (cmd, NULL);
			for (i=0; argv[i]; i++) {
				rp->_args[i] = argv[i];
			}
			rp->_args[i] = NULL;
			rp->_program = argv[0];
			if (io->runprofile && *io->runprofile) {
				if (!r_run_parsefile (rp, io->runprofile)) {
					eprintf ("Can't find profile '%s'\n", io->runprofile);
					exit (MAGIC_EXIT);
				}
			}
			if (bits==64)
				r_run_parseline (rp, expr=strdup ("bits=64"));
			else if (bits==32)
				r_run_parseline (rp, expr=strdup ("bits=32"));
			free (expr);
			r_run_start (rp);
			r_run_free (rp);
			// double free wtf
			//	r_str_argv_free (argv);
			exit (1);
		} else {
			// TODO: Add support to redirect filedescriptors
			// TODO: Configure process environment
			char *_cmd = strdup (cmd);
			argv = r_str_argv (_cmd, NULL);
			if (!argv) {
				free (_cmd);
				return -1;
			}
#if __APPLE__
			 {
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
				ut32 ps_flags = POSIX_SPAWN_SETEXEC;
				posix_spawnattr_t attr = {0};
				size_t copied = 1;
				cpu_type_t cpu;
				pid_t p = -1;
				int ret;

				int useASLR = 1;
				posix_spawnattr_init (&attr);
				if (useASLR != -1) {
					if (useASLR) {
						// enable aslr if not enabled? really?
					} else {
						ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
					}
				}
				(void)posix_spawnattr_setflags (&attr, ps_flags);
#if __i386__ || __x86_64__
				cpu = CPU_TYPE_I386;
				if (bits == 64)
					cpu |= CPU_ARCH_ABI64;
#else
				cpu = CPU_TYPE_ANY;
#endif
				posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &copied);
				ret = posix_spawnp (&p, argv[0], NULL, &attr, argv, NULL);
				switch (ret) {
				case 0:
					eprintf ("Success\n");
					break;
				case 22:
					eprintf ("posix_spawnp: Invalid argument\n");
					break;
				case 86:
					eprintf ("Unsupported architecture\n");
					break;
				default:
					eprintf ("posix_spawnp: unknown error %d\n", ret);
					perror ("posix_spawnp");
					break;
				}
				/* only required if no SETEXEC called
				   if (p != -1)
				   wait (p);
				 */
				exit (MAGIC_EXIT); /* error */
			 }
#else
			 if (argv && *argv) {
				 execvp (argv[0], argv);
			 } else {
				 eprintf ("Invalid execvp\n");
			 }
#endif
			free (_cmd);
		}
		perror ("fork_and_attach: execv");
		//printf(stderr, "[%d] %s execv failed.\n", getpid(), ps.filename);
		exit (MAGIC_EXIT); /* error */
		return 0; // invalid pid // if exit is overriden.. :)
	default:
		/* XXX: clean this dirty code */
		do {
                	ret = wait (&status);
			if (ret == -1)
				return -1;
			if (ret != pid)
				eprintf ("Wait event received by different pid %d\n", ret);
		} while (ret!=pid);
		if (WIFSTOPPED (status))
			eprintf ("Process with PID %d started...\n", (int)pid);
		if (WEXITSTATUS (status) == MAGIC_EXIT)
			pid = -1;
		// XXX kill (pid, SIGSTOP);
		break;
	}
	eprintf ("PID = %d\n", pid);
	return pid;
}
#endif

static int __plugin_open(RIO *io, const char *file, ut8 many) {
	if (!strncmp (file, "dbg://", 6) && file[6])
		return R_TRUE;
	return R_FALSE;
}

static RIODesc *__open(RIO *io, const char *file, int rw, int mode) {
	char uri[128];
	if (__plugin_open (io, file,  0)) {
		const char *pidfile = file + 6;
		char *endptr;
		int pid = (int)strtol (pidfile, &endptr, 10);
		if (endptr == pidfile || pid < 0) pid = -1;

		if (pid == -1) {
			pid = fork_and_ptraceme (io, io->bits, file+6);
			if (pid == -1)
				return NULL;
#if __WINDOWS__
			sprintf (uri, "w32dbg://%d", pid);
#elif __APPLE__
			sprintf (uri, "mach://%d", pid);
#else
			// TODO: use io_procpid here? faster or what?
			sprintf (uri, "ptrace://%d", pid);
#endif
			my_io_redirect (io, file, uri);
		} else {
			sprintf (uri, "attach://%d", pid);
			my_io_redirect (io, file, uri);
		}
		return NULL;
	}
	my_io_redirect (io, file, NULL);
	return NULL;
}
Beispiel #19
0
static RList *r_debug_native_pids (int pid) {
	RList *list = r_list_new ();
	if (!list) return NULL;
#if __WINDOWS__ && !__CYGWIN__
	return w32_pids (pid, list);
#elif __APPLE__
	if (pid) {
		RDebugPid *p = xnu_get_pid (pid);
		if (p) r_list_append (list, p);
	} else {
		int i;
		for (i = 1; i < MAXPID; i++) {
			RDebugPid *p = xnu_get_pid (i);
			if (p) r_list_append (list, p);
		}
	}
#else
	int i;
	char *ptr, buf[1024];

	list->free = (RListFree)&r_debug_pid_free;
	if (pid) {
		DIR *dh;
		struct dirent *de;

		/* add the requested pid. should we do this? we don't even know if it's valid still.. */
		r_list_append (list, r_debug_pid_new ("(current)", pid, 's', 0));

		/* list parents */
		dh = opendir ("/proc");
		if (dh == NULL) {
			r_sys_perror ("opendir /proc");
			r_list_free (list);
			return NULL;
		}
		while ((de = readdir (dh))) {
			/* for each existing pid file... */
			i = atoi (de->d_name);
			if (i <= 0) {
				continue;
			}

			/* try to read the status */
			buf[0] = 0;
			if (procfs_pid_slurp (i, "status", buf, sizeof (buf)) == -1) {
				continue;
			}
			buf[sizeof (buf) - 1] = 0;

			/* look for the parent process id */
			ptr = strstr (buf, "PPid:");
			if (ptr) {
				int ppid = atoi (ptr + 6);

				/* if this is the requested process... */
				if (i == pid) {
					//eprintf ("PPid: %d\n", ppid);
					/* append it to the list with parent */
					r_list_append (list, r_debug_pid_new (
						"(ppid)", ppid, 's', 0));
				}

				/* ignore it if it is not one of our children */
				if (ppid != pid) {
					continue;
				}

				/* it's a child of the requested pid, read it's command line and add it */
				if (procfs_pid_slurp (ppid, "cmdline", buf, sizeof(buf)) == -1) {
					continue;
				}

				r_list_append (list, r_debug_pid_new (buf, i, 's', 0));
			}
		}
		closedir (dh);
	} else {
		/* try to bruteforce the processes
		 * XXX(jjd): wouldn't listing the processes like before work better?
		 */
		for (i = 2; i < MAXPID; i++) {
			/* try to send signal 0, if it fails it must not be valid */
			if (r_sandbox_kill (i, 0) == -1)
				continue;

			if (procfs_pid_slurp (i, "cmdline", buf, sizeof(buf)) == -1)
				continue;

			r_list_append (list, r_debug_pid_new (buf, i, 's', 0));
		}
	}
#endif
	return list;
}
Beispiel #20
0
static int r_debug_native_wait (RDebug *dbg, int pid) {
	int status = -1;
#if __WINDOWS__ && !__CYGWIN__
	int mode = 0;
	status = w32_dbg_wait (dbg, pid);
	if (status == R_DEBUG_REASON_NEW_LIB) {
		mode = 'l';
	} else if (status == R_DEBUG_REASON_EXIT_LIB) {
		mode = 'u';
	} else {
		mode = 0;
	}
	if (mode) {
		RDebugInfo *r = r_debug_native_info (dbg, "");
		if (r && r->lib) {
			if (tracelib (dbg, mode=='l'? "load":"unload", r->lib))
				status=R_DEBUG_REASON_TRAP;
		} else {
			eprintf ("%soading unknown library.\n", mode?"L":"Unl");
		}
		r_debug_info_free (r);
	}
#else
	if (pid == -1) {
		status = R_DEBUG_REASON_UNKNOWN;
	} else {
#if __APPLE__
		// eprintf ("No waitpid here :D\n");
		status = xnu_wait (dbg, pid);
#else
		// XXX: this is blocking, ^C will be ignored
		int ret = waitpid (pid, &status, 0);
		if (ret == -1) {
			r_sys_perror ("waitpid");
			status = R_DEBUG_REASON_ERROR;
		} else {
			//printf ("r_debug_native_wait: status=%d (return=%d)\n", status, ret);

			// TODO: switch status and handle reasons here
#if __linux__ && defined(PT_GETEVENTMSG)
			// Handle PTRACE_EVENT_*
			if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP) {
				ut32 pt_evt = status >> 16;
				ut32 data;

				switch (pt_evt) {
				case 0:
					// Normal trap?
					break;

				case PTRACE_EVENT_FORK:
					if (dbg->trace_forks) {
						if (ptrace (PTRACE_GETEVENTMSG, pid, 0, &data) == -1) {
							r_sys_perror ("ptrace GETEVENTMSG");
						} else {
							eprintf ("PTRACE_EVENT_FORK new_pid=%d\n", data);
							dbg->forked_pid = data;
							// TODO: more handling here?
						}
					}
					break;
				case PTRACE_EVENT_EXIT:
					if (ptrace (PTRACE_GETEVENTMSG, pid, 0, &data) == -1) {
						r_sys_perror ("ptrace GETEVENTMSG");
					} else {
						eprintf ("PTRACE_EVENT_EXIT pid=%d, status=%d\n", pid, data);
					}
					break;
				default:
					eprintf ("Unknown PTRACE_EVENT encountered: %d\n", pt_evt);
					break;
				}
			}
#endif

			r_debug_handle_signals (dbg);

			if (WIFSTOPPED (status)) {
				dbg->reason.signum = WSTOPSIG (status);
				status = R_DEBUG_REASON_SIGNAL;
			} else if (status == 0 || ret == -1) {
				status = R_DEBUG_REASON_DEAD;
			} else {
				if (ret != pid)
					status = R_DEBUG_REASON_NEW_PID;
				else status = R_DEBUG_REASON_UNKNOWN;
			}
		}
#endif
	}
Beispiel #21
0
static void trace_me () {
#if __APPLE__
	signal (SIGTRAP, SIG_IGN); //NEED BY STEP
#endif
#if __APPLE__ || __BSD__
/* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */
	signal (SIGABRT, inferior_abort_handler);
	if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) {
#else
	if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) {
#endif
		r_sys_perror ("ptrace-traceme");
		exit (MAGIC_EXIT);
	}
}

void handle_posix_error(int err) {
	switch (err) {
	case 0:
		// eprintf ("Success\n");
		break;
	case 22:
		eprintf ("posix_spawnp: Invalid argument\n");
		break;
	case 86:
		eprintf ("Unsupported architecture. Please specify -b 32\n");
		break;
	default:
		eprintf ("posix_spawnp: unknown error %d\n", err);
		perror ("posix_spawnp");
		break;
	}
}

static RRunProfile* _get_run_profile(RIO *io, int bits, char **argv) {
	char *expr = NULL;
	int i;
	RRunProfile *rp = r_run_new (NULL);
	if (!rp) {
		return NULL;
	}
	for (i = 0; argv[i]; i++) {
		rp->_args[i] = argv[i];
	}
	rp->_args[i] = NULL;
	rp->_program = strdup (argv[0]);
	rp->_dodebug = true;
	if (io->runprofile && *io->runprofile) {
		if (!r_run_parsefile (rp, io->runprofile)) {
			eprintf ("Can't find profile '%s'\n", io->runprofile);
			r_run_free (rp);
			return NULL;
		}
		if (strstr (io->runprofile, R_SYS_DIR ".rarun2.")) {
			(void)r_file_rm (io->runprofile);
		}
	}
	if (bits == 64) {
		r_run_parseline (rp, expr=strdup ("bits=64"));
	} else if (bits == 32) {
		r_run_parseline (rp, expr=strdup ("bits=32"));
	}
	free (expr);
	if (r_run_config_env (rp)) {
		eprintf ("Can't config the environment.\n");
		r_run_free (rp);
		return NULL;
	}
	return rp;
}
Beispiel #22
0
R_API int r_run_config_env(RRunProfile *p) {
	int ret;

	if (!p->_program && !p->_system) {
		printf ("No program or system rule defined\n");
		return 1;
	}
	// when IO is redirected to a process, handle them together
	if (handle_redirection (p->_stdio, true, true, false) != 0) {
		return 1;
	}
	if (handle_redirection (p->_stdin, true, false, false) != 0) {
		return 1;
	}
	if (handle_redirection (p->_stdout, false, true, false) != 0) {
		return 1;
	}
	if (handle_redirection (p->_stderr, false, false, true) != 0) {
		return 1;
	}
	if (p->_aslr != -1)
		setASLR (p->_aslr);
#if __UNIX__
	set_limit (p->_docore, RLIMIT_CORE, RLIM_INFINITY);
	if (p->_maxfd)
		set_limit (p->_maxfd, RLIMIT_NOFILE, p->_maxfd);
#ifdef RLIMIT_NPROC
	if (p->_maxproc)
		set_limit (p->_maxproc, RLIMIT_NPROC, p->_maxproc);
#endif
	if (p->_maxstack)
		set_limit (p->_maxstack, RLIMIT_STACK, p->_maxstack);
#else
	if (p->_docore || p->_maxfd || p->_maxproc || p->_maxstack)
		eprintf ("Warning: setrlimits not supported for this platform\n");
#endif
	if (p->_connect) {
		char *q = strchr (p->_connect, ':');
		if (q) {
			RSocket *fd = r_socket_new (0);
			*q = 0;
			if (!r_socket_connect_tcp (fd, p->_connect, q+1, 30)) {
				eprintf ("Cannot connect\n");
				return 1;
			}
			eprintf ("connected\n");
			close (0);
			close (1);
			close (2);
			dup2 (fd->fd, 0);
			dup2 (fd->fd, 1);
			dup2 (fd->fd, 2);
		} else {
			eprintf ("Invalid format for connect. missing ':'\n");
			return 1;
		}
	}
	if (p->_listen) {
		RSocket *child, *fd = r_socket_new (0);
		bool is_child = false;
		if (!r_socket_listen (fd, p->_listen, NULL)) {
			eprintf ("rarun2: cannot listen\n");
			r_socket_free (fd);
			return 1;
		}
		while (true) {
			child = r_socket_accept (fd);
			if (child) {
				is_child = true;

				if (p->_dofork && !p->_dodebug) {
					pid_t child_pid = r_sys_fork ();
					if (child_pid == -1) {
						eprintf("rarun2: cannot fork\n");
						r_socket_free (child);
						r_socket_free (fd);
						return 1;
					} else if (child_pid != 0){
						// parent code
						is_child = false;
					}
				}

				if (is_child) {
					r_socket_close_fd (fd);
					eprintf ("connected\n");
					close (0);
					close (1);
					close (2);
					dup2 (child->fd, 0);
					dup2 (child->fd, 1);
					dup2 (child->fd, 2);
					break;
				} else {
					r_socket_close_fd (child);
				}
			}
		}
		if(!is_child) r_socket_free (child);
		r_socket_free (fd);
	}
	if (p->_r2sleep != 0) {
		r_sys_sleep (p->_r2sleep);
	}
#if __UNIX__
	if (p->_chroot) {
		if (chdir (p->_chroot) == -1) {
			eprintf ("Cannot chdir to chroot in %s\n", p->_chroot);
			return 1;
		} else {
			if (chroot (".") == -1) {
				eprintf ("Cannot chroot to %s\n", p->_chroot);
				return 1;
			} else {
				if (p->_chgdir) {
					if (chdir (p->_chgdir) == -1) {
						eprintf ("Cannot chdir after chroot to %s\n", p->_chgdir);
						return 1;
					}
				}
			}
		}
	} else if (p->_chgdir) {
		if (chdir (p->_chgdir) == -1) {
			eprintf ("Cannot chdir after chroot to %s\n", p->_chgdir);
			return 1;
		}
	}
#endif
	if (p->_chgdir) {
		ret = chdir (p->_chgdir);
		if (ret < 0) {
			return 1;
		}
	}
	if (p->_chroot) {
		ret = chdir (p->_chroot);
		if (ret < 0) {
			return 1;
		}
	}
#if __UNIX__
	if (p->_chroot) {
		if (chroot (p->_chroot) == 0) {
			chdir ("/");
		} else {
			eprintf ("rarun2: cannot chroot\n");
			r_sys_perror ("chroot");
			return 1;
		}
	}
	if (p->_setuid) {
		ret = setgroups (0, NULL);
		if (ret < 0)
			return 1;
		ret = setuid (atoi (p->_setuid));
		if (ret < 0)
			return 1;
	}
	if (p->_seteuid) {
		ret = seteuid (atoi (p->_seteuid));
		if (ret < 0)
			return 1;
	}
	if (p->_setgid) {
		ret = setgid (atoi (p->_setgid));
		if (ret < 0)
			return 1;
	}
	if (p->_input) {
		char *inp;
		int f2[2];
		pipe (f2);
		close (0);
		dup2 (f2[0], 0);
		inp = getstr (p->_input);
		if (inp) {
			write (f2[1], inp, strlen (inp));
			close (f2[1]);
			free (inp);
		} else {
			eprintf ("Invalid input\n");
		}
	}
#endif
	if (p->_r2preload) {
		if (p->_preload) {
			eprintf ("WARNING: Only one library can be opened at a time\n");
		}
		p->_preload = R2_LIBDIR"/libr2."R_LIB_EXT;
	}
	if (p->_libpath) {
#if __WINDOWS__
		eprintf ("rarun2: libpath unsupported for this platform\n");
#elif __HAIKU__
		r_sys_setenv ("LIBRARY_PATH", p->_libpath);
#elif __APPLE__
		r_sys_setenv ("DYLD_LIBRARY_PATH", p->_libpath);
#else
		r_sys_setenv ("LD_LIBRARY_PATH", p->_libpath);
#endif
	}
	if (p->_preload) {
#if __APPLE__
		// 10.6
		r_sys_setenv ("DYLD_PRELOAD", p->_preload);
		r_sys_setenv ("DYLD_INSERT_LIBRARIES", p->_preload);
		// 10.8
		r_sys_setenv ("DYLD_FORCE_FLAT_NAMESPACE", "1");
#else
		r_sys_setenv ("LD_PRELOAD", p->_preload);
#endif
	}
	if (p->_timeout) {
#if __UNIX__
		int mypid = getpid ();
		if (!r_sys_fork ()) {
			int use_signal = p->_timeout_sig;
			if (use_signal < 1) {
				use_signal = SIGKILL;
			}
			sleep (p->_timeout);
			if (!kill (mypid, 0)) {
				eprintf ("\nrarun2: Interrupted by timeout\n");
			}
			kill (mypid, use_signal);
			exit (0);
		}
#else
		eprintf ("timeout not supported for this platform\n");
#endif
	}
	return 0;
}
Beispiel #23
0
static int fork_and_ptraceme(RIO *io, int bits, const char *cmd) {
	PROCESS_INFORMATION pi;
	STARTUPINFO si = { 0 } ;
	DEBUG_EVENT de;
	int pid, tid;
	HANDLE th = INVALID_HANDLE_VALUE;
	if (!*cmd) {
		return -1;
	}
	setup_tokens ();
	char *_cmd = io->args ? r_str_appendf (strdup (cmd), " %s", io->args) :
		strdup (cmd);
	char **argv = r_str_argv (_cmd, NULL);
	// We need to build a command line with quoted argument and escaped quotes
	int cmd_len = 0;
	int i = 0;

	si.cb = sizeof (si);
	while (argv[i]) {
		char *current = argv[i];
		int quote_count = 0;
		while ((current = strchr (current, '"'))) {
			quote_count ++;
		}
		cmd_len += strlen (argv[i]);
		cmd_len += quote_count; // The quotes will add one backslash each
		cmd_len += 2; // Add two enclosing quotes;
		i++;
	}
	cmd_len += i-1; // Add argc-1 spaces

	char *cmdline = malloc ((cmd_len + 1) * sizeof (char));
	int cmd_i = 0; // Next character to write in cmdline
	i = 0;
	while (argv[i]) {
		if (i != 0) {
			cmdline[cmd_i++] = ' ';
		}
		cmdline[cmd_i++] = '"';

		int arg_i = 0; // Index of current character in orginal argument
		while (argv[i][arg_i]) {
			char c = argv[i][arg_i];
			if (c == '"') {
				cmdline[cmd_i++] = '\\';
			}
			cmdline[cmd_i++] = c;
			arg_i++;
		}

		cmdline[cmd_i++] = '"';
		i++;
	}
	cmdline[cmd_i] = '\0';

	LPTSTR appname_ = r_sys_conv_utf8_to_utf16 (argv[0]);
	LPTSTR cmdline_ = r_sys_conv_utf8_to_utf16 (cmdline);
	if (!CreateProcess (appname_, cmdline_, NULL, NULL, FALSE,
						 CREATE_NEW_CONSOLE | DEBUG_ONLY_THIS_PROCESS,
						 NULL, NULL, &si, &pi)) {
		r_sys_perror ("fork_and_ptraceme/CreateProcess");
		free (appname_);
		free (cmdline_);
		return -1;
	}
	free (appname_);
	free (cmdline_);
	free (cmdline);
	r_str_argv_free (argv);
	/* get process id and thread id */
	pid = pi.dwProcessId;
	tid = pi.dwThreadId;

	/* catch create process event */
	if (!WaitForDebugEvent (&de, 10000)) goto err_fork;

	/* check if is a create process debug event */
	if (de.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) {
		eprintf ("exception code 0x%04x\n", (ut32)de.dwDebugEventCode);
		goto err_fork;
	}

	if (th != INVALID_HANDLE_VALUE) {
		CloseHandle (th);
	}
	eprintf ("Spawned new process with pid %d, tid = %d\n", pid, tid);
	winbase = (ut64)de.u.CreateProcessInfo.lpBaseOfImage;
	wintid = tid;
	return pid;

err_fork:
	eprintf ("ERRFORK\n");
	TerminateProcess (pi.hProcess, 1);
	if (th != INVALID_HANDLE_VALUE) CloseHandle (th);
	return -1;
}
Beispiel #24
0
static int fork_and_ptraceme(const char *cmd) {
	PROCESS_INFORMATION pi;
        STARTUPINFO si = { sizeof (si) };
        DEBUG_EVENT de;
	int pid, tid;
	HANDLE th = INVALID_HANDLE_VALUE;
	if (!*cmd)
		return -1;
	setup_tokens ();
        /* TODO: with args */
        if (!CreateProcess (cmd, NULL,
                        NULL, NULL, FALSE,
                        CREATE_NEW_CONSOLE | DEBUG_ONLY_THIS_PROCESS,
                        NULL, NULL, &si, &pi)) {
                r_sys_perror ("CreateProcess");
                return -1;
        }

        /* get process id and thread id */
        pid = pi.dwProcessId;
        tid = pi.dwThreadId;

#if 0
        /* load thread list */
	{
		HANDLE h;
		THREADENTRY32 te32;
		HANDLE WINAPI (*win32_openthread)(DWORD, BOOL, DWORD) = NULL;
		win32_openthread = (HANDLE WINAPI (*)(DWORD, BOOL, DWORD))
			GetProcAddress (GetModuleHandle ("kernel32"), "OpenThread");

		th = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, pid);
		if (th == INVALID_HANDLE_VALUE || !Thread32First(th, &te32))
			r_sys_perror ("CreateToolhelp32Snapshot");

		do {
			if (te32.th32OwnerProcessID == pid) {
				h = win32_openthread (THREAD_ALL_ACCESS, 0, te32.th32ThreadID);
				if (h == NULL) r_sys_perror ("OpenThread");
				else eprintf ("HANDLE=%p\n", h);
			}
		} while (Thread32Next (th, &te32));
	}
#endif

#if 0
	// Access denied here :?
	if (ContinueDebugEvent (pid, tid, DBG_CONTINUE) == 0) {
		r_sys_perror ("ContinueDebugEvent");
		goto err_fork;
	}
#endif

        /* catch create process event */
        if (!WaitForDebugEvent (&de, 10000))
                goto err_fork;

        /* check if is a create process debug event */
        if (de.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) {
                eprintf ("exception code 0x%04x\n", (ut32)de.dwDebugEventCode);
                goto err_fork;
        }

	if (th != INVALID_HANDLE_VALUE)
		CloseHandle (th);

	eprintf ("PID=%d\n", pid);
	eprintf ("TID=%d\n", tid);
        return pid;

err_fork:
	eprintf ("ERRFORK\n");
        TerminateProcess (pi.hProcess, 1);
	if (th != INVALID_HANDLE_VALUE)
		CloseHandle (th);
        return -1;
}
Beispiel #25
0
Datei: mz.c Projekt: 0x2F/radare2
static int r_bin_mz_init_hdr(struct r_bin_mz_obj_t* bin) {
	int relocations_size, dos_file_size;

	if (!(bin->dos_header = malloc (sizeof(MZ_image_dos_header)))) {
		r_sys_perror ("malloc (MZ_image_dos_header)");
		return R_FALSE;
	}
	if (r_buf_read_at (bin->b, 0, (ut8*)bin->dos_header,
			sizeof(*bin->dos_header)) == -1) {
		eprintf ("Error: read (MZ_image_dos_header)\n");
		return R_FALSE;
	}

	if (bin->dos_header->blocks_in_file < 1)
		return R_FALSE;

	dos_file_size = ((bin->dos_header->blocks_in_file - 1) << 9) + \
			bin->dos_header->bytes_in_last_block;

	bin->dos_file_size = dos_file_size;

	if (dos_file_size > bin->size)
		return R_FALSE;

	relocations_size = bin->dos_header->num_relocs * \
		sizeof(MZ_image_relocation_entry);

	/* Check if relocation table doesn't exceed dos binary size */
	if ((bin->dos_header->reloc_table_offset + relocations_size) > \
			dos_file_size)
		return R_FALSE;

	sdb_num_set (bin->kv, "mz.initial.cs", bin->dos_header->cs, 0);
	sdb_num_set (bin->kv, "mz.initial.ip", bin->dos_header->ip, 0);
	sdb_num_set (bin->kv, "mz.initial.ss", bin->dos_header->ss, 0);
	sdb_num_set (bin->kv, "mz.initial.sp", bin->dos_header->sp, 0);
	sdb_num_set (bin->kv, "mz.overlay_number",
		bin->dos_header->overlay_number, 0);
	sdb_num_set (bin->kv, "mz.dos_header.offset", 0, 0);
	sdb_set (bin->kv, "mz.dos_header.format", "[2]zwwwwwwwwwwwww"
			" signature bytes_in_last_block blocks_in_file num_relocs "
			" header_paragraphs min_extra_paragraphs max_extra_paragraphs "
			" ss sp checksum ip cs reloc_table_offset overlay_number ", 0);

	bin->dos_extended_header_size = bin->dos_header->reloc_table_offset - \
		sizeof(MZ_image_dos_header);

	if (bin->dos_extended_header_size > 0)
	{
		if (!(bin->dos_extended_header = \
				malloc (bin->dos_extended_header_size))) {
			r_sys_perror ("malloc (dos extended header)");
			return R_FALSE;
		}
		if (r_buf_read_at (bin->b, sizeof(MZ_image_dos_header),
				(ut8*)bin->dos_extended_header,
				bin->dos_extended_header_size) == -1) {
			eprintf ("Error: read (dos extended header)\n");
			return R_FALSE;
		}
	}

	if (relocations_size > 0)
	{
		if (!(bin->relocation_entries = malloc (relocations_size))) {
			r_sys_perror ("malloc (dos relocation entries)");
			return R_FALSE;
		}
		if (r_buf_read_at (bin->b, bin->dos_header->reloc_table_offset,
				(ut8*)bin->relocation_entries, relocations_size) == -1) {
			eprintf ("Error: read (dos relocation entries)\n");
			return R_FALSE;
		}
	}

	return R_TRUE;
}