Example #1
0
int gdbr_server_read(libgdbr_t *g, char *buf, size_t max_len) {
	bool loop_continue;
	int ret;
	if (!g) {
		return -1;
	}
	memset (buf, 0, max_len);

	do {
		loop_continue = false;
		read_packet (g);
		while (!*g->data) {
			read_packet (g);
		}

		if (r_str_startswith (g->data, "qSupported")) {
			loop_continue = true;
			if ((ret = _server_handle_qSupported (g)) < 0) {
				return ret;
			}
		} else if (r_str_startswith (g->data, "qTStatus")) {
			loop_continue = true;
			if ((ret = _server_handle_qTStatus (g)) < 0) {
				return ret;
			}
		} else if (r_str_startswith (g->data, "qC")) {
			if ((ret = _server_handle_qC (g, buf, max_len)) < 0) {
				return ret;
			}
		}
	} while (loop_continue);
	return ret;
}
Example #2
0
static int lang_lib_file_run (RLang *user, const char *file) {
	char *libpath;
	void *lib;
	if (!(libpath = r_str_new (file))) {
		return -1;
	}
	if (!r_str_startswith (libpath, "/") && !r_str_startswith (libpath, "./")) {
		libpath = r_str_prefix (libpath, "./");
	}
	if (!r_file_exists (libpath)) {
		if (!r_str_endswith (libpath, R_LIB_EXT)) {
			libpath = r_str_appendf (libpath, ".%s", R_LIB_EXT);
		}
	}
	if (!r_file_exists (libpath)) {
		free (libpath);
		return -1;
	}	
	
	lib = r_lib_dl_open (libpath);
	if (lib) {
		void (*fcn)(RCore *);
		fcn = r_lib_dl_sym (lib, "entry");
		if (fcn) {
			fcn (user->user);
		} else {
			eprintf ("Cannot find 'entry' symbol in library\n");
		}
		r_lib_dl_close (lib);
	}
	free (libpath);
	return 0;
}
Example #3
0
static int __io_posix_open(const char *file, int perm, int mode) {
	int fd;
	if (r_str_startswith (file, "file://")) {
		file += strlen ("file://");
	}
	if (r_file_is_directory (file)) {
		return -1;
	}
#if __WINDOWS__
	// probably unnecessary to have this ifdef nowadays windows is posix enough
	if (perm & R_PERM_W) {
		fd = r_sandbox_open (file, O_BINARY | O_RDWR, 0);
		if (fd == -1 && perm & R_PERM_CREAT) {
			r_sandbox_creat (file, 0644);
			fd = r_sandbox_open (file, O_BINARY | O_RDWR | O_CREAT, 0);
		}
	} else {
		fd = r_sandbox_open (file, O_BINARY, 0);
	}
#else
	const int posixFlags = (perm & R_PERM_W) ? (perm & R_PERM_CREAT)
			? (O_RDWR | O_CREAT) : O_RDWR : O_RDONLY;
	fd = r_sandbox_open (file, posixFlags, mode);
#endif
	return fd;
}
Example #4
0
File: xml.c Project: agatti/radare2
static int _resolve_arch(libgdbr_t *g, char *xml_data) {
	char *arch;
	// Find architecture
	g->target.arch = R_SYS_ARCH_NONE;
	if ((arch = strstr (xml_data, "<architecture"))) {
		if (!(arch = strchr (arch, '>'))) {
			return -1;
		}
		arch++;
		if (r_str_startswith (arch, "i386")) {
			g->target.arch = R_SYS_ARCH_X86;
			g->target.bits = 32;
			arch += 4;
			if (r_str_startswith (arch, ":x86-64")) {
				g->target.bits = 64;
			}
		} else if (r_str_startswith (arch, "aarch64")) {
			g->target.arch = R_SYS_ARCH_ARM;
			g->target.bits = 64;
		} else if (r_str_startswith (arch, "arm")) {
			g->target.arch = R_SYS_ARCH_ARM;
			g->target.bits = 32;
		} else if (r_str_startswith (arch, "mips")) {
			g->target.arch = R_SYS_ARCH_MIPS;
			g->target.bits = 32;
		}
		// TODO others
	} else {
		// apple's debugserver on ios9
		if (strstr (xml_data, "com.apple.debugserver.arm64")) {
			g->target.arch = R_SYS_ARCH_ARM;
			g->target.bits = 64;
		} else if (strstr (xml_data, "org.gnu.gdb.mips")) {
			// openocd mips?
			g->target.arch = R_SYS_ARCH_MIPS;
			g->target.bits = 32;
		} else {
			eprintf ("Unknown architecture parsing XML (%s)\n", xml_data);
		}
	}
	return 0;
}
Example #5
0
// default open should permit opening
static RIODesc *__open_default(RIO *io, const char *file, int flags, int mode) {
	if (r_str_startswith (file, "file://")) {
		file += strlen ("file://");
	}
	if (!r_io_def_mmap_check_default (file)) {
		return NULL;
	}
	RIODesc *iod = r_io_def_mmap_open (io, file, flags, mode);
	return iod;
// NTOE: uncomment this line to support loading files in ro as fallback is rw fails
//	return iod? iod: r_io_def_mmap_open (io, file, R_IO_READ, mode);
}
Example #6
0
static bool r_io_def_mmap_check_default (const char *filename) {
	if (filename) {
		if (r_str_startswith (filename, "file://")) {
			filename += strlen ("file://");
		}
		const char * peekaboo = (!strncmp (filename, "nocache://", 10))
			? NULL : strstr (filename, "://");
		if (!peekaboo || (peekaboo-filename) > 10) {
			return true;
		}
	}
	return false;
}
Example #7
0
static int __io_posix_open(const char *file, int flags, int mode) {
	int fd;
	if (r_str_startswith (file, "file://")) {
		file += strlen ("file://");
	}
	if (r_file_is_directory (file)) {
		return -1;
	}
#if __WINDOWS__
	if (flags & R_IO_WRITE) {
		fd = r_sandbox_open (file, O_BINARY | O_RDWR, 0);
		if (fd == -1) {
			r_sandbox_creat (file, 0644);
			fd = r_sandbox_open (file, O_BINARY | O_RDWR, 0);
		}
	} else {
		fd = r_sandbox_open (file, O_BINARY, 0);
	}
#else
	fd = r_sandbox_open (file, (flags & R_IO_WRITE) ? (O_RDWR|O_CREAT) : O_RDONLY, mode);
#endif
	return fd;
}
Example #8
0
File: core.c Project: Xxmmy/radare2
ut64 gdbr_get_baddr(libgdbr_t *g) {
	if (!g || send_msg (g, "qOffsets") < 0 || read_packet (g) < 0
	    || send_ack (g) < 0 || g->data_len == 0) {
		return UINT64_MAX;
	}
	ut64 off, min = UINT64_MAX;
	char *ptr;
	if (r_str_startswith (g->data, "TextSeg=")) {
		ptr = g->data + strlen ("TextSeg=");
		if (!isxdigit (*ptr)) {
			return min;
		}
		off = strtoull (ptr, NULL, 16);
		if (off < min) {
			min = off;
		}
		if (!(ptr = strchr (ptr, ';'))) {
			return min;
		}
		ptr++;
		if (*ptr && r_str_startswith (ptr, "DataSeg=")) {
			ptr += strlen ("DataSeg=");
			if (!isxdigit (*ptr)) {
				return min;
			}
			off = strtoull (ptr, NULL, 16);
			if (off < min) {
				min = off;
			}
		}
		return min;
	}
	if (!r_str_startswith (g->data, "Text=")) {
		return min;
	}
	ptr = g->data + strlen ("Text=");
	if (!isxdigit (*ptr)) {
		return min;
	}
	off = strtoull (ptr, NULL, 16);
	if (off < min) {
		min = off;
	}
	if (!(ptr = strchr (ptr, ';')) || !r_str_startswith (ptr + 1, "Data=")) {
		return UINT64_MAX;
	}
	ptr += strlen (";Data=");
	if (!isxdigit (*ptr)) {
		return UINT64_MAX;
	}
	off = strtoull (ptr, NULL, 16);
	if (off < min) {
		min = off;
	}
	if (!(ptr = strchr (ptr, ';'))) {
		return min;
	}
	ptr++;
	if (r_str_startswith (ptr, "Bss=")) {
		ptr += strlen ("Bss=");
		if (!isxdigit (*ptr)) {
			return min;
		}
		off = strtoull (ptr, NULL, 16);
		if (off < min) {
			min = off;
		}
	}
	return min;
}
Example #9
0
File: xml.c Project: agatti/radare2
static RList* _extract_regs(char *regstr, RList *flags, char *pc_alias) {
	char *regstr_end, *regname, *regtype, *tmp1;
	ut32 flagnum, regname_len, regsize, regnum;
	RList *regs;
	RListIter *iter;
	gdbr_xml_reg_t *tmpreg;
	gdbr_xml_flags_t *tmpflag;
	if (!(regs = r_list_new ())) {
		return NULL;
	}
	while ((regstr = strstr (regstr, "<reg"))) {
		if (!(regstr_end = strchr (regstr, '/'))) {
			goto exit_err;
		}
		*regstr_end = '\0';
		// name
		if (!(regname = strstr (regstr, "name="))) {
			goto exit_err;
		}
		regname += 6;
		if (!(tmp1 = strchr (regname, '"'))) {
			goto exit_err;
		}
		regname_len = tmp1 - regname;
		// size
		if (!(tmp1 = strstr (regstr, "bitsize="))) {
			goto exit_err;
		}
		tmp1 += 9;
		if (!isdigit (*tmp1)) {
			goto exit_err;
		}
		regsize = strtoul (tmp1, NULL, 10);
		// regnum
		regnum = UINT32_MAX;
		if ((tmp1 = strstr (regstr, "regnum="))) {
			tmp1 += 8;
			if (!isdigit (*tmp1)) {
				goto exit_err;
			}
			regnum = strtoul (tmp1, NULL, 10);
		}
		// type
		regtype = "gpr";
		flagnum = r_list_length (flags);
		if ((tmp1 = strstr (regstr, "group="))) {
			tmp1 += 7;
			if (r_str_startswith (tmp1, "float")) {
				regtype = "fpu";
			}
			// We need type information in r2 register profiles
		} else if ((tmp1 = strstr (regstr, "type="))) {
			tmp1 += 6;
			if (r_str_startswith (tmp1, "vec")
			    || r_str_startswith (tmp1, "i387_ext")
			    || r_str_startswith (tmp1, "ieee_single")
			    || r_str_startswith (tmp1, "ieee_double")) {
				regtype = "fpu";
			} else if (r_str_startswith (tmp1, "code_ptr")) {
				strcpy (pc_alias, "=PC	");
				strncpy (pc_alias + 4, regname, regname_len);
				strcpy (pc_alias + 4 + regname_len, "\n");
			} else {
				// Check all flags. If reg is a flag, write flag data
				flagnum = 0;
				r_list_foreach (flags, iter, tmpflag) {
					if (r_str_startswith (tmp1, tmpflag->type)) {
						// Max 64-bit :/
						if (tmpflag->num_bits <= 64) {
							break;
						}
					}
					flagnum++;
				}
			}
			// We need type information in r2 register profiles
		}
		if (!(tmpreg = calloc (1, sizeof (gdbr_xml_reg_t)))) {
			goto exit_err;
		}
		regname[regname_len] = '\0';
		if (regname_len > sizeof (tmpreg->name) - 1) {
			eprintf ("Register name too long: %s\n", regname);
		}
		strncpy (tmpreg->name, regname, sizeof (tmpreg->name) - 1);
		tmpreg->name[sizeof (tmpreg->name) - 1] = '\0';
		regname[regname_len] = '"';
		strncpy (tmpreg->type, regtype, sizeof (tmpreg->type) - 1);
		tmpreg->type[sizeof (tmpreg->type) - 1] = '\0';
		tmpreg->size = regsize / 8;
		tmpreg->flagnum = flagnum;
		if (regnum == UINT32_MAX) {
			r_list_push (regs, tmpreg);
		} else if (regnum >= r_list_length (regs)) {
			int i;
			for (i = regnum - r_list_length (regs); i > 0; i--) {
				// temporary placeholder reg. we trust the xml is correct and this will be replaced.
				r_list_push (regs, tmpreg);
				r_list_tail (regs)->data = NULL;
			}
			r_list_push (regs, tmpreg);
		} else {
			// this is where we replace those placeholder regs
			r_list_set_n (regs, regnum, tmpreg);
		}
		*regstr_end = '/';
		regstr = regstr_end + 2;
	}
Example #10
0
int handle_stop_reason(libgdbr_t *g) {
	send_ack (g);
	if (g->data_len < 3) {
		return -1;
	}
	switch (g->data[0]) {
	case 'O':
		unpack_hex (g->data + 1, g->data_len - 1, g->data + 1);
		//g->data[g->data_len - 1] = '\0';
		eprintf ("%s", g->data + 1);
		if (send_ack (g) < 0) {
			return -1;
		}
		return handle_stop_reason (g); // Wait for next stop message
	case 'W':
		return stop_reason_exit (g);
	case 'X':
		return stop_reason_terminated (g);
	}
	if (g->data[0] != 'T') {
		return -1;
	}
	char *ptr1, *ptr2;
	g->data[g->data_len] = '\0';
	free (g->stop_reason.exec.path);
	memset (&g->stop_reason, 0, sizeof (libgdbr_stop_reason_t));
	g->stop_reason.core = -1;
	if (sscanf (g->data + 1, "%02x", &g->stop_reason.signum) != 1) {
		return -1;
	}
	g->stop_reason.is_valid = true;
	g->stop_reason.reason = R_DEBUG_REASON_SIGNAL;
	for (ptr1 = strtok (g->data + 3, ";"); ptr1; ptr1 = strtok (NULL, ";")) {
		if (r_str_startswith (ptr1, "thread") && !g->stop_reason.thread.present) {
			if (!(ptr2 = strchr (ptr1, ':'))) {
				continue;
			}
			ptr2++;
			if (read_thread_id (ptr2, &g->stop_reason.thread.pid,
					    &g->stop_reason.thread.tid,
					    g->stub_features.multiprocess) < 0) {
				continue;
			}
			g->stop_reason.thread.present = true;
			continue;
		}
		if (r_str_startswith (ptr1, "core")) {
			if (!(ptr2 = strchr (ptr1, ':'))) {
				continue;
			}
			ptr2++;
			if (!isxdigit (*ptr2)) {
				continue;
			}
			g->stop_reason.core = (int) strtol (ptr2, NULL, 16);
			continue;
		}
		if (g->stop_reason.signum == 5) {
			if (r_str_startswith (ptr1, "watch")
			    || r_str_startswith (ptr1, "rwatch")
			    || r_str_startswith (ptr1, "awatch")) {
				if (!(ptr2 = strchr (ptr1, ':'))) {
					continue;
				}
				ptr2++;
				if (!isxdigit (*ptr2)) {
					continue;
				}
				g->stop_reason.watchpoint.addr = strtoll (ptr2, NULL, 16);
				g->stop_reason.watchpoint.present = true;
				continue;
			}
			if (r_str_startswith (ptr1, "exec") && !g->stop_reason.exec.present) {
				if (!(ptr2 = strchr (ptr1, ':'))) {
					continue;
				}
				ptr2++;
				if (!(g->stop_reason.exec.path = calloc (strlen (ptr1) / 2, 1))) {
					continue;
				}
				unpack_hex (ptr2, strlen (ptr2), g->stop_reason.exec.path);
				g->stop_reason.exec.present = true;
				continue;
			}
			if (r_str_startswith (ptr1, "fork") && !g->stop_reason.fork.present) {
				if (!(ptr2 = strchr (ptr1, ':'))) {
					continue;
				}
				ptr2++;
				if (read_thread_id (ptr2, &g->stop_reason.fork.pid,
						    &g->stop_reason.fork.tid,
						    g->stub_features.multiprocess) < 0) {
					continue;
				}
				g->stop_reason.fork.present = true;
				continue;
			}
			if (r_str_startswith (ptr1, "vfork") && !g->stop_reason.vfork.present) {
				if (!(ptr2 = strchr (ptr1, ':'))) {
					continue;
				}
				ptr2++;
				if (read_thread_id (ptr2, &g->stop_reason.vfork.pid,
						    &g->stop_reason.vfork.tid,
						    g->stub_features.multiprocess) < 0) {
					continue;
				}
				g->stop_reason.vfork.present = true;
				continue;
			}
			if (r_str_startswith (ptr1, "vforkdone")) {
				g->stop_reason.vforkdone = true;
				continue;
			}
			if (r_str_startswith (ptr1, "library")) {
				g->stop_reason.library = true;
				continue;
			}
			if (r_str_startswith (ptr1, "swbreak")) {
				g->stop_reason.swbreak = true;
				continue;
			}
			if (r_str_startswith (ptr1, "hwbreak")) {
				g->stop_reason.hwbreak = true;
				continue;
			}
			if (r_str_startswith (ptr1, "create")) {
				g->stop_reason.create = true;
				continue;
			}
		}
	}
	if (g->stop_reason.signum == 5) {
		g->stop_reason.reason = R_DEBUG_REASON_BREAKPOINT;
	}
	return 0;
}
Example #11
0
R_API char *r_type_get_struct_memb(Sdb *TDB, const char *type, int offset) {
	int i, prev_typesize, typesize = 0;
	char *res = NULL;

	if (offset < 0) {
		return NULL;
	}
	char* query = sdb_fmt ("struct.%s", type);
	char *members = sdb_get (TDB, query, 0);
	if (!members) {
		//eprintf ("%s is not a struct\n", type);
		return NULL;
	}
	int nargs = r_str_split (members, ',');
	for (i = 0; i < nargs ; i++) {
		const char *name = r_str_word_get0 (members, i);
		if (!name) {
			break;
		}
		query = sdb_fmt ("struct.%s.%s", type, name);
		char *subtype = sdb_get (TDB, query, 0);
		if (!subtype) {
			break;
		}
		int len = r_str_split (subtype, ',');
		if (len < 3) {
			free (subtype);
			break;
		}
		int val = r_num_math (NULL, r_str_word_get0 (subtype, len - 1));
		int arrsz = val ? val : 1;
		if ((typesize / 8) == offset) {
			res = r_str_newf ("%s.%s", type, name);
			free (subtype);
			break;
		}
		prev_typesize = typesize;
		typesize += r_type_get_bitsize (TDB, subtype) * arrsz;
		// Handle nested structs
		if (offset < (typesize / 8)) {
			char *nested_type = (char *)r_str_word_get0 (subtype, 0);
			if (r_str_startswith (nested_type, "struct ") && !r_str_endswith (nested_type, " *")) {
				len = r_str_split (nested_type, ' ');
				if (len < 2) {
					free (subtype);
					break;
				}
				nested_type = (char *)r_str_word_get0 (nested_type, 1);
				char *nested_res = r_type_get_struct_memb (TDB, nested_type, offset - (prev_typesize / 8));
				if (nested_res) {
					len = r_str_split(nested_res, '.');
					res = r_str_newf ("%s.%s.%s", type, name, r_str_word_get0 (nested_res, len - 1));
					free (nested_res);
					free (subtype);
					break;
				}
			}
		}
		free (subtype);
	}
	free (members);
	return res;
}
Example #12
0
File: core.c Project: P4N74/radare2
int gdbr_server_serve(libgdbr_t *g, gdbr_server_cmd_cb cmd_cb, void *core_ptr) {
	int ret;
	if (!g) {
		return -1;
	}
	while (1) {
		read_packet (g);
		if (g->data_len == 0) {
			continue;
		}
		if (r_str_startswith (g->data, "k")) {
			return _server_handle_k (g, cmd_cb, core_ptr);
		}
		if (r_str_startswith (g->data, "vKill")) {
			return _server_handle_vKill (g, cmd_cb, core_ptr);
		}
		if (r_str_startswith (g->data, "qSupported")) {
			if ((ret = _server_handle_qSupported (g)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "qTStatus")) {
			if ((ret = _server_handle_qTStatus (g)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "qC") && g->data_len == 2) {
			if ((ret = _server_handle_qC (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "qAttached")) {
			if ((ret = _server_handle_qAttached (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "vMustReplyEmpty")) {
			if ((ret = _server_handle_vMustReplyEmpty (g)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "qTfV")) {
			if ((ret = _server_handle_qTfV (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "qfThreadInfo")) {
			if ((ret = _server_handle_qfThreadInfo (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "qsThreadInfo")) {
			if ((ret = _server_handle_qsThreadInfo (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "Hg")) {
			if ((ret = _server_handle_Hg (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "Hc")) {
			if ((ret = _server_handle_Hc (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "?")) {
			if ((ret = _server_handle_ques (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "g") && g->data_len == 1) {
			if ((ret = _server_handle_g (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "vCont")) {
			if ((ret = _server_handle_vCont (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "qOffsets")) {
			if ((ret = _server_handle_qOffsets (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (g->data[0] == 'z' || g->data[0] == 'Z') {
			if ((ret = _server_handle_z (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (g->data[0] == 's') {
			if ((ret = _server_handle_s (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (g->data[0] == 'c') {
			if ((ret = _server_handle_c (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "m")) {
			if ((ret = _server_handle_m (g, cmd_cb, core_ptr)) < 0) {
				return ret;
			}
			continue;
		}
		if (r_str_startswith (g->data, "QStartNoAckMode")) {
			if (send_ack (g) < 0 || send_msg (g, "OK") < 0) {
				return -1;
			}
			g->no_ack = true;
			continue;
		}
		// Unrecognized packet
		if (send_ack (g) < 0 || send_msg (g, "") < 0) {
			g->data[g->data_len] = '\0';
			eprintf ("Unknown packet: %s\n", g->data);
			return -1;
		}
	};
	return ret;
}