Esempio n. 1
0
static int rabin_extract(int all) {
	char outfile[512], outpath[512], *path, *ptr;
	int i = 0;

	if (all) {
		for (i=0; i<bin->narch; i++) {
			const char *arch;
			int bits;

			r_bin_select_idx (bin, i);
			if (bin->cur.o->info == NULL) {
				arch = "unknown";
				bits = 0;
			//	eprintf ("No extract info found.\n");
			//	continue;
			} else {
				arch = bin->cur.o->info->arch;
				bits = bin->cur.o->info->bits;
			}
			path = strdup (bin->cur.file);
			// XXX: Wrong for w32 (/)
			if ((ptr = strrchr (path, '/'))) {
				*ptr = '\0';
				ptr++;
			} else ptr = bin->cur.file;
/*
			if (output)
				snprintf (outpath, sizeof (outpath), "%s/%s", output, path);
			else snprintf (outpath, sizeof (outpath), "./%s", path);
*/
			snprintf (outpath, sizeof (outpath), "%s.fat", ptr);
			if (!r_sys_rmkdir (outpath)) {
				eprintf ("Error creating dir structure\n");
				return R_FALSE;
			}
			snprintf (outfile, sizeof (outfile), "%s/%s.%s_%i.%d",
					outpath, ptr, arch, bits, i);
			if (!r_file_dump (outfile, bin->cur.buf->buf, bin->cur.size)) {
				eprintf ("Error extracting %s\n", outfile);
				return R_FALSE;
			} else printf ("%s created (%i)\n", outfile, bin->cur.size);
		}
	} else { /* XXX: Use 'output' for filename? */
		if (bin->cur.o->info == NULL) {
			eprintf ("No extract info found.\n");
		} else {
			if ((ptr = strrchr (bin->cur.file, '/')))
				ptr++;
			else ptr = bin->cur.file;
			snprintf (outfile, sizeof (outfile), "%s.%s_%i", ptr,
					bin->cur.o->info->arch, bin->cur.o->info->bits);
			if (!r_file_dump (outfile, bin->cur.buf->buf, bin->cur.size)) {
				eprintf ("Error extracting %s\n", outfile);
				return R_FALSE;
			} else printf ("%s created (%i)\n", outfile, bin->cur.size);
		}
	}
	return R_TRUE;
}
Esempio n. 2
0
File: diff.c Progetto: P4N74/radare2
// XXX: temporary files are
R_API int r_diff_buffers_unified(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
	if (r_mem_is_printable (a, R_MIN (5, la))) {
		r_file_dump (".a", a, la, 0);
		r_file_dump (".b", b, lb, 0);
	} else {
		r_file_hexdump (".a", a, la, 0);
		r_file_hexdump (".b", b, lb, 0);
	}
	r_sys_cmd ("diff -ru .a .b");
	r_file_rm (".a");
	r_file_rm (".b");
	return 0;
}
Esempio n. 3
0
static bool r_egg_Cfile_parseCompiled(const char *file) {
	char *fileExt = r_str_newf ("%s.tmp", file);
	char *buffer = r_file_slurp (fileExt, NULL);

	buffer = r_str_replace (buffer, "rdata", "text", false);
	buffer = r_str_replace (buffer, "rodata", "text", false);
	buffer = r_str_replace (buffer, "get_pc_thunk.bx", "__getesp__", true);

	const char *words[] = {".cstring", "size", "___main", "section", "__alloca", "zero", "cfi"};
	size_t i;
	for (i = 0; i < 7; i++) {
		r_str_stripLine (buffer, words[i]);
	}

	free (fileExt);
	fileExt = r_str_newf ("%s.s", file);
	if (!r_file_dump (fileExt, (const ut8*) buffer, strlen (buffer), true)) {
		eprintf ("Error while opening %s.s\n", file);
		goto fail;
	}

	free (buffer);
	free (fileExt);
	return true;

fail:
	free (buffer);
	free (fileExt);
	return false;
}
Esempio n. 4
0
static int rabin_dump_sections(char *scnname) {
	RList *sections;
	RListIter *iter;
	RBinSection *section;
	ut8 *buf;
	char *ret;

	if ((sections = r_bin_get_sections (bin)) == NULL)
		return R_FALSE;

	r_list_foreach (sections, iter, section) {
		if (!strcmp (scnname, section->name)) {
			if (!(buf = malloc (section->size)))
				return R_FALSE;
			if (!(ret = malloc (section->size*2+1))) {
				free (buf);
				return R_FALSE;
			}
			r_buf_read_at (bin->cur->buf, section->paddr, buf, section->size);
			if (output) {
				r_file_dump (output, buf, section->size);
			} else {
				r_hex_bin2str (buf, section->size, ret);
				printf ("%s\n", ret);
			}
			free (buf);
			free (ret);
			break;
		}
	}

	return R_TRUE;
}
Esempio n. 5
0
R_API int r_bin_wr_output(RBin *bin, const char *filename) {
	RBinFile *binfile = r_bin_cur (bin);

	if (!binfile || !binfile->buf) return R_FALSE;
	return r_file_dump (filename, binfile->buf->buf,
			binfile->buf->length);
}
Esempio n. 6
0
static void filesave () {
	char buf[128];
	int i;
	if (!path) {
		eprintf ("File: ");
		buf[0] = 0;
		fgets (buf, sizeof(buf), stdin);
		i = strlen (buf);
		if (i>0) {
			buf[i-1] = 0;
			free (path);
			path = strdup (buf);
		}
	}
	if (lines) {
		for (i=0; i<bytes; i++) {
			if (lines[i]=='\0')
				lines[i]='\n';
		}
	}
	r_file_dump (path, (const ut8*)lines, bytes);
	eprintf ("File '%s' saved (%d bytes)\n", path, bytes);
	// restore back zeroes
	nlines = r_str_split (lines, '\n');
}
Esempio n. 7
0
// XXX: temporary files are
R_API char *r_diff_buffers_unified(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
		r_file_dump (".a", a, la, 0);
		r_file_dump (".b", b, lb, 0);
#if 0
	if (r_mem_is_printable (a, R_MIN (5, la))) {
		r_file_dump (".a", a, la, 0);
		r_file_dump (".b", b, lb, 0);
	} else {
		r_file_hexdump (".a", a, la, 0);
		r_file_hexdump (".b", b, lb, 0);
	}
#endif
	char* err = NULL;
	char* out = NULL;
	int out_len;
	(void)r_sys_cmd_str_full ("/usr/bin/diff -u .a .b", NULL, &out, &out_len, &err);
	r_file_rm (".a");
	r_file_rm (".b");
	free (err);
	return out;
}
Esempio n. 8
0
int main () {
#define _BUFFER_SIZE 64
	unsigned char code[64] = {
		0x31, 0xc0, 0x40, 0x68, 0x2a, 0x00, 0x00, 0x00, 0x81, 0xec, 0x04, 
		0x00, 0x00, 0x00, 0xcd, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	RBuffer *b;
	RBin *bin = r_bin_new ();
	if (!r_bin_use_arch (bin, "x86", 32, "mach0")) {
		eprintf ("Cannot set arch\n");
		return 1;
	}
	b = r_bin_create (bin, code, _BUFFER_SIZE, NULL, 0);
	if (b) {
		if (r_file_dump ("a.out", b->buf, b->length))
			eprintf ("dumped %d bytes in a.out\n", b->length);
		else eprintf ("error dumping into a.out\n");
	} else eprintf ("So f*****g oops\n");
	r_bin_free (bin);
	r_buf_free (b);
	return 0;
}
Esempio n. 9
0
R_API int r_run_start(RRunProfile *p) {
#if __APPLE__
	posix_spawnattr_t attr = {0};
	pid_t pid = -1;
#endif
	int ret;
	if (!p->_program && !p->_system) {
		printf ("No program or system rule defined\n");
		return 1;
	}
	if (p->_stdin) {
		int f = open (p->_stdin, O_RDONLY);
		if (f < 0)
			return 1;
		close (0);
		dup2 (f, 0);
	}
	if (p->_stdout) {
		int f = open (p->_stdout, O_WRONLY);
		if (f < 0)
			return 1;
		close (1);
		dup2 (f, 1);
	}
	if (p->_stderr) {
		int f = open (p->_stderr, O_WRONLY);
		if (f < 0)
			return 1;
		close (2);
		dup2 (f, 2);
	}
	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);
		if (!r_socket_listen (fd, p->_listen, NULL)) {
			eprintf ("rarun2: cannot listen\n");
			r_socket_free (fd);
			return 1;
		}
		child = r_socket_accept (fd);
		if (child) {
			eprintf ("connected\n");
			close (0);
			close (1);
			close (2);
			dup2 (child->fd, 0);
			dup2 (child->fd, 1);
			dup2 (child->fd, 2);
		}
	}
	if (p->_r2sleep != 0) {
		r_sys_sleep (p->_r2sleep);
	}
	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)) {
			eprintf ("rarun2: cannot chroot\n");
			return 1;
		}
		chdir("/");
	}
	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) {
		int f2[2];
		pipe (f2);
		close (0);
		dup2 (f2[0], 0);
		parseinput (p->_input);
		write (f2[1], p->_input, strlen (p->_input));
	}
#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 (!fork ()) {
			sleep (p->_timeout);
			if (!kill (mypid, 0))
				eprintf ("\nrarun2: Interrupted by timeout\n");
			kill (mypid, SIGKILL);
			exit (0);
		}
#else
		eprintf ("timeout not supported for this platform\n");
#endif
	}
#if __APPLE__
	posix_spawnattr_init (&attr);
	if (p->_args[0]) {
		char **envp = r_sys_get_environ();
		ut32 spflags = 0; //POSIX_SPAWN_START_SUSPENDED;
		spflags |= POSIX_SPAWN_SETEXEC;
		if (p->_aslr == 0) {
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
			spflags |= _POSIX_SPAWN_DISABLE_ASLR;
		}
		(void)posix_spawnattr_setflags (&attr, spflags);
		if (p->_bits) {
			size_t copied = 1;
			cpu_type_t cpu;
#if __i386__ || __x86_64__
			cpu = CPU_TYPE_I386;
			if (p->_bits == 64)
				cpu |= CPU_ARCH_ABI64;
#else
			cpu = CPU_TYPE_ANY;
#endif
			posix_spawnattr_setbinpref_np (
					&attr, 1, &cpu, &copied);
		}
		ret = posix_spawnp (&pid, p->_args[0],
			NULL, &attr, p->_args, envp);
		switch (ret) {
		case 0:
			break;
		case 22:
			eprintf ("posix_spawnp: Invalid argument\n");
			break;
		case 86:
			eprintf ("posix_spawnp: Unsupported architecture\n");
			break;
		default:
			eprintf ("posix_spawnp: unknown error %d\n", ret);
			perror ("posix_spawnp");
			break;
		}
		exit (ret);
	}
#endif
	if (p->_system) {
		if (p->_pid) {
			eprintf ("PID: Cannot determine pid with 'system' directive. Use 'program'.\n");
		}
		exit (r_sys_cmd (p->_system));
	}
	if (p->_program) {
		if (!r_file_exists (p->_program)) {
			char *progpath = r_file_path (p->_program);
			if (progpath && *progpath) {
				free (p->_program);
				p->_program = progpath;
			} else {
				free (progpath);
				eprintf ("rarun2: %s: file not found\n", p->_program);
				return 1;
			}
		}
#if __UNIX__
		// XXX HACK close all non-tty fds
		{ int i; for (i=3; i<10; i++) close (i); }
		// TODO: use posix_spawn
		if (p->_setgid) {
			ret = setgid (atoi (p->_setgid));
			if (ret < 0)
				return 1;
		}
		if (p->_pid) {
			eprintf ("PID: %d\n", getpid ());
		}
		if (p->_pidfile) {
			char pidstr[32];
			snprintf (pidstr, sizeof (pidstr), "%d\n", getpid ());
			r_file_dump (p->_pidfile,
				(const ut8*)pidstr,
				strlen (pidstr), 0);
		}
#endif

	if (p->_nice) {
#if __UNIX__
        errno = 0;
        ret = nice(p->_nice);
        if (ret == -1) {
            if (errno != 0) {
                return 1;
            }
        }
#else
	eprintf ("nice not supported for this platform\n");
#endif
    }
		exit (execv (p->_program, (char* const*)p->_args));
	}
	return 0;
}
Esempio n. 10
0
R_API int r_diff_buffers_static(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
	int i, len;
	int hit = 0;
	la = R_ABS(la);
	lb = R_ABS(lb);
	if (la != lb) {
	 	len = R_MIN(la, lb);
		fprintf(stderr,
			"Buffer truncated to %d bytes (%d not compared)\n",
			len, R_ABS(lb-la));
	} else len = la;
	for(i = 0; i<len; i++) {
		if (a[i]!=b[i]) {
			hit++;
		} else {
			if (hit>0) {
				struct r_diff_op_t o = {
					.a_off = d->off_a+i-hit, .a_buf = a+i-hit, .a_len = hit,
					.b_off = d->off_b+i-hit, .b_buf = b+i-hit, .b_len = hit
				};
				d->callback (d, d->user, &o);
				hit = 0;
			}
		}
	}
	if (hit>0) {
		struct r_diff_op_t o = {
			.a_off = d->off_a+i-hit, .a_buf = a+i-hit, .a_len = hit,
			.b_off = d->off_b+i-hit, .b_buf = b+i-hit, .b_len = hit
		};
		d->callback (d, d->user, &o);
		hit = 0;
	}
	return 0;
}

// XXX: temporary files are
R_API int r_diff_buffers_radiff(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
	char *ptr, *str, buf[64], oop = 0;
	int ret, atl, btl, hit;
	ut8 at[128], bt[128];
	ut64 ooa, oob;
	FILE *fd;

	hit = atl = btl = 0;
	ooa = oob = 0LL;
	oop = -1;

	r_file_dump (".a", a, la, 0);
	r_file_dump (".b", b, lb, 0);
	r_sys_cmd ("radiff -d .a .b | rsc uncolor > .d");
	fd = fopen (".d", "r");
	if (!fd) return 0;

	while (!feof (fd)) {
		ut64 oa, ob; // offset
		int ba, bb = 0; // byte
		char op; // operation

		oa = ob = 0LL;
		if (!fgets (buf, 63, fd))
			break;
		if (feof (fd))
			break;
		str = buf;

		ptr = strchr (buf, ' ');
		if (!ptr) continue;
		*ptr='\0';
		sscanf (str, "0x%08"PFMT64x"", &oa);

		str = r_str_ichr (ptr+1, ' ');
		if (*str!='|'&&*str!='>'&&*str!='<') {
			ptr = strchr (str, ' ');
			if (!ptr) continue;
			*ptr='\0';
			sscanf (str, "%02x", &ba);
		} else ba = 0;

		str = r_str_ichr (ptr+1, ' ');
		ptr = strchr (str, ' ');
		if (!ptr) continue;
		*ptr='\0';
		sscanf (str, "%c", &op);

		str = r_str_ichr (ptr+1, ' ');
		if (str[0]!='0' || str[1]!='x') {
			ptr = strchr(str, ' ');
			if (!ptr) continue;
			*ptr = '\0';
			sscanf (str, "%02x", &bb);
		}

		str = ptr+1;
		ptr = strchr (str, '\n');
		if (!ptr) continue;
		*ptr='\0';
		sscanf (str, "0x%08"PFMT64x"", &ob);

		if (oop == op || oop==-1) {
			if (hit == 0) {
				ooa = oa;
				oob = ob;
			}
			at[atl] = ba;
			bt[btl] = bb;
			switch (op) {
			case '|':
				atl++;
				btl++;
				break;
			case '>':
				btl++;
				break;
			case '<':
				atl++;
				break;
			}
			hit++;
		} else {
			if (hit>0) {
				struct r_diff_op_t o = {
					.a_off = ooa, .a_buf = at, .a_len = atl,
					.b_off = oob, .b_buf = bt, .b_len = btl
				};
				ret = d->callback(d, d->user, &o);
				if (!ret)
					break;
				atl = btl = 0;
				hit = 0;
			}
		}
		oop = op;
	}
	if (hit > 0) {
		struct r_diff_op_t o = {
			.a_off = ooa, .a_buf = at, .a_len = atl,
			.b_off = oob, .b_buf = bt, .b_len = btl
		};
		if (!d->callback (d, d->user, &o)) {
			fclose (fd);
			return 0;
		}
		atl = btl = 0;
		hit = 0;
	}
	fclose (fd);
	unlink (".a");
	unlink (".b");
	unlink (".d");
	return 0;
}

R_API int r_diff_buffers(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb) {
	if (d->delta) {
		return r_diff_buffers_delta (d, a, la, b, lb);
	}
	return r_diff_buffers_static (d, a, la, b, lb);
}

/* TODO: Move into r_util maybe? */
R_API bool r_diff_buffers_distance(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb, ut32 *distance, double *similarity) {
	const bool verbose = d? d->verbose: false;
	/*
	More memory efficient version on Levenshtein Distance from:
	https://en.wikipedia.org/wiki/Levenshtein_distance
	http://www.codeproject.com/Articles/13525/Fast-memory-efficient-Levenshtein-algorithm
	ObM..

	8/July/2016 - More time efficient Levenshtein Distance. Now runs in about O(N*sum(MDistance)) instead of O(NM)
	In real world testing the speedups for similar files are immense. Processing of
	radiff2 -sV routerA/firmware_extract/bin/httpd routerB/firmware_extract/bin/httpd
	reduced from 28 hours to about 13 minutes.
	*/
	int i, j;
	const ut8 *aBufPtr;
	const ut8 *bBufPtr;
	ut32 aLen;
	ut32 bLen;

	// temp pointer will be used to switch v0 and v1 after processing the inner loop.
	int *temp;
	int *v0, *v1;

	// We need these variables outside the context of the loops as we need to
	// survive multiple loop iterations.
	// start and stop are used in our inner loop
	// colMin tells us the current 'best' edit distance.
	// extendStop & extendStart are used when we get 'double up' edge conditions
	// that require us to keep some more data.
	int start = 0;
	int stop = 0;
	int smallest;
	int colMin = 0;
	int extendStop = 0;
	int extendStart = 0;

	//we could move cost into the 'i' loop.
	int cost = 0;

	// loops can get very big, this can be removed, but it's currently in there for debugging
	// and optimisation testing.
	ut64 loops = 0;

	// We need the longest file to be 'A' because our optimisation tries to stop and start
	// around the diagonal.
	//  AAAAAAA
	// B*
	// B *
	// B  *____
	// if we have them the other way around and we terminate on the diagonal, we won't have
	// inspected all the bytes of file B..
	//  AAAA
	// B*
	// B *
	// B  *
	// B   *
	// B   ?

	if (la < lb) {
		aBufPtr = b;
		bBufPtr = a;
		aLen = lb;
		bLen = la;
	} else {
		aBufPtr = a;
		bBufPtr = b;
		aLen = la;
		bLen = lb;
	}
	stop = bLen;
	// Preliminary tests

	//Do we have both files a & b, and are they at least one byte?
	if (!aBufPtr || !bBufPtr || aLen < 1 || bLen < 1) {
		return false;
	}

	//IF the files are the same size and are identical, then we have matching files
	if (aLen == bLen && !memcmp (aBufPtr, bBufPtr, aLen)) {
		if (distance) {
			*distance = 0;
		}
		if (similarity) {
			*similarity = 1.0;
		}
		return true;
	}
	// Only calloc if we have to do some processing

	// calloc v0 & v1 and check they initialised
	v0 = (int*) calloc ((bLen + 3), sizeof (int));
	if (!v0) {
		eprintf ("Error: cannot allocate %i bytes.", bLen + 3);
		return false;
	}

	v1 = (int*) calloc ((bLen + 3), sizeof (int));
	if (!v1) {
		eprintf ("Error: cannot allocate %i bytes", 2 * (bLen + 3));
		free (v0);
		return false;
	}

	// initialise v0 and v1.
	// With optimisiation we only strictly we only need to initialise v0[0..2]=0..2 & v1[0] = 1;
	for (i = 0; i < bLen + 1 ; i++) {
		v0[i] = i;
		v1[i] = i + 1;
	}

	// Outer loop = the length of the longest input file.
	for (i = 0; i < aLen; i++) {

		// We're going to stop the inner loop at:
		// bLen (so we don't run off the end of our array)
		// or 'two below the diagonal' PLUS any extension we need for 'double up' edge values
		// (see extendStop for logic)
		stop = R_MIN ((i + extendStop + 2), bLen);

		// We need a value in the result column (v1[start]).
		// If you look at the loop below, we need it because we look at v1[j] as one of the
		// potential shortest edit distances.
		// In all cases where the edit distance can't 'reach',
		// the value of v1[start] simply increments.
		if (start > bLen) {
			break;
		} 
		v1[start] = v0[start] + 1;

		// need to have a bigger number in colMin than we'll ever encounter in the inner loop
		colMin = aLen;

		// Inner loop does all the work:
		for (j = start; j <= stop; j++) {
			loops++;

			// The main levenshtein comparison:
			cost = (aBufPtr[i] == bBufPtr[j]) ? 0 : 1;
			smallest = R_MIN ((v1[j] + 1), (v0[j + 1] + 1));
			smallest = R_MIN (smallest, (v0[j] + cost));

			// populate the next two entries in v1.
			// only really required if this is the last loop.
			if (j + 2 > bLen + 3) {
				break;
			}
			v1[j + 1] = smallest;
			v1[j + 2] = smallest + 1;

			// If we have seen a smaller number, it's the new column Minimum
			colMin = R_MIN ((colMin), (smallest));

		}

		// We're going to start at i+1 next iteration
		// The column minimum is the current edit distance
		// This distance is the minimum 'search width' from the optimal 'i' diagonal
		// The extendStart picks up an edge case where we have a match on the first iteration
		// We update extendStart after we've set start for the next iteration.
		start = i + 1 - colMin - extendStart;

		// If the last processed entry is a match, AND
		// the current byte in 'a' and the previous processed entry in 'b' aren't a match
		// then we need to extend our search below the optimal 'i' diagonal. because we'll
		// have a vertical double up condition in our last two values of the results column.
		// j-2 is used because j++ increments prior to loop exit in the processing loop above.
		if (!cost && aBufPtr[i] != bBufPtr[j - 2]) {
			extendStop ++;
		}

		// If new start would be a match then we have a horizontal 'double up'
		// which means we need to keep an extra row of data
		// so don't increment the start counter this time, BUT keep
		// extendStart up our sleeves for next iteration.
		if (i + 1 < aLen && start < bLen && aBufPtr[i + 1] == bBufPtr[start]) {
			start --;
			extendStart ++;
		}
		//Switch v0 and v1 pointers via temp pointer
		temp = v0;
		v0 = v1;
		v1 = temp;

		//Print a processing update every 10K of outer loop
		if (verbose && i % 10000==0) {
			eprintf ("\rProcessing %d of %d\r", i, aLen);
		}
	}
	//Clean up output on loop exit (purely aesthetic)
	if (verbose) {
		eprintf ("\rProcessing %d of %d (loops=%llu)\n", i, aLen,loops);
	}
	if (distance) {
		// the final distance is the last byte we processed in the inner loop.
		// v0 is used instead of v1 because we switched the pointers before exiting the outer loop
		*distance = v0[stop];
		if (similarity) {
			double diff = (double) (*distance) / (double) (R_MAX (aLen, bLen));
			*similarity = (double)1 - diff;
		}
	}
	free (v0);
	free (v1);
	return true;
}
Esempio n. 11
0
R_API int r_run_start(RRunProfile *p) {
#if LIBC_HAVE_FORK
	if (p->_execve) {
		exit (execv (p->_program, (char* const*)p->_args));
	}
#endif
#if __APPLE__ && !__POWERPC__ && LIBC_HAVE_FORK
	posix_spawnattr_t attr = {0};
	pid_t pid = -1;
	int ret;
	posix_spawnattr_init (&attr);
	if (p->_args[0]) {
		char **envp = r_sys_get_environ();
		ut32 spflags = 0; //POSIX_SPAWN_START_SUSPENDED;
		spflags |= POSIX_SPAWN_SETEXEC;
		if (p->_aslr == 0) {
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
			spflags |= _POSIX_SPAWN_DISABLE_ASLR;
		}
		(void)posix_spawnattr_setflags (&attr, spflags);
		if (p->_bits) {
			size_t copied = 1;
			cpu_type_t cpu;
#if __i386__ || __x86_64__
			cpu = CPU_TYPE_I386;
			if (p->_bits == 64)
				cpu |= CPU_ARCH_ABI64;
#else
			cpu = CPU_TYPE_ANY;
#endif
			posix_spawnattr_setbinpref_np (
					&attr, 1, &cpu, &copied);
		}
		ret = posix_spawnp (&pid, p->_args[0],
			NULL, &attr, p->_args, envp);
		switch (ret) {
		case 0:
			break;
		case 22:
			eprintf ("posix_spawnp: Invalid argument\n");
			break;
		case 86:
			eprintf ("posix_spawnp: Unsupported architecture\n");
			break;
		default:
			eprintf ("posix_spawnp: unknown error %d\n", ret);
			perror ("posix_spawnp");
			break;
		}
		exit (ret);
	}
#endif
	if (p->_system) {
		if (p->_pid) {
			eprintf ("PID: Cannot determine pid with 'system' directive. Use 'program'.\n");
		}
		exit (r_sys_cmd (p->_system));
	}
	if (p->_program) {
		if (!r_file_exists (p->_program)) {
			char *progpath = r_file_path (p->_program);
			if (progpath && *progpath) {
				free (p->_program);
				p->_program = progpath;
			} else {
				free (progpath);
				eprintf ("rarun2: %s: file not found\n", p->_program);
				return 1;
			}
		}
#if __UNIX__
		// XXX HACK close all non-tty fds
		{ int i; for (i=3; i<10; i++) close (i); }
		// TODO: use posix_spawn
		if (p->_setgid) {
			int ret = setgid (atoi (p->_setgid));
			if (ret < 0)
				return 1;
		}
		if (p->_pid) {
			eprintf ("PID: %d\n", getpid ());
		}
		if (p->_pidfile) {
			char pidstr[32];
			snprintf (pidstr, sizeof (pidstr), "%d\n", getpid ());
			r_file_dump (p->_pidfile,
				(const ut8*)pidstr,
				strlen (pidstr), 0);
		}
#endif

		if (p->_nice) {
#if __UNIX__ && !defined(__HAIKU__)
			if (nice (p->_nice) == -1) {
				return 1;
			}
#else
			eprintf ("nice not supported for this platform\n");
#endif
		}
// TODO: must be HAVE_EXECVE
#if LIBC_HAVE_FORK
		exit (execv (p->_program, (char* const*)p->_args));
#endif
	}
	return 0;
}
Esempio n. 12
0
/* TODO: simplify using r_write */
static int cmd_write(void *data, const char *input) {
    ut64 off;
    ut8 *buf;
    const char *arg;
    int wseek, i, size, len = strlen (input);
    char *tmp, *str, *ostr;
    RCore *core = (RCore *)data;
#define WSEEK(x,y) if(wseek)r_core_seek_delta(x,y)
    wseek = r_config_get_i (core->config, "cfg.wseek");
    str = ostr = strdup (input+1);

    switch (*input) {
    case 'p':
        if (input[1]==' ' && input[2]) {
            r_core_patch (core, input+2);
        } else {
            eprintf ("Usage: wp [rapatch-file]\n"
                     "TODO: rapatch format documentation here\n");
        }
        break;
    case 'r':
        off = r_num_math (core->num, input+1);
        len = (int)off;
        if (len>0) {
            buf = malloc (len);
            if (buf != NULL) {
                r_num_irand ();
                for (i=0; i<len; i++)
                    buf[i] = r_num_rand (256);
                r_core_write_at (core, core->offset, buf, len);
                WSEEK (core, len);
                free (buf);
            } else eprintf ("Cannot allocate %d bytes\n", len);
        }
        break;
    case 'A':
        switch (input[1]) {
        case ' ':
            if (input[2] && input[3]==' ') {
                r_asm_set_pc (core->assembler, core->offset);
                eprintf ("modify (%c)=%s\n", input[2], input+4);
                len = r_asm_modify (core->assembler, core->block, input[2],
                                    r_num_math (core->num, input+4));
                eprintf ("len=%d\n", len);
                if (len>0) {
                    r_core_write_at (core, core->offset, core->block, len);
                    WSEEK (core, len);
                } else eprintf ("r_asm_modify = %d\n", len);
            } else eprintf ("Usage: wA [type] [value]\n");
            break;
        case '?':
        default:
            r_cons_printf ("Usage: wA [type] [value]\n"
                           "Types:\n"
                           " r   raw write value\n"
                           " v   set value (taking care of current address)\n"
                           " d   destination register\n"
                           " 0   1st src register\n"
                           " 1   2nd src register\n"
                           "Example: wA r 0 # e800000000\n");
            break;
        }
        break;
    case 'c':
        switch (input[1]) {
        case 'i':
            r_io_cache_commit (core->io);
            r_core_block_read (core, 0);
            break;
        case 'r':
            r_io_cache_reset (core->io, R_TRUE);
            /* Before loading the core block we have to make sure that if
             * the cache wrote past the original EOF these changes are no
             * longer displayed. */
            memset (core->block, 0xff, core->blocksize);
            r_core_block_read (core, 0);
            break;
        case '-':
            if (input[2]=='*') {
                r_io_cache_reset (core->io, R_TRUE);
            } else if (input[2]==' ') {
                char *p = strchr (input+3, ' ');
                ut64 to, from = core->offset;
                if (p) {
                    *p = 0;
                    from = r_num_math (core->num, input+3);
                    to = r_num_math (core->num, input+3);
                    if (to<from) {
                        eprintf ("Invalid range (from>to)\n");
                        return 0;
                    }
                } else {
                    from = r_num_math (core->num, input+3);
                    to = from + core->blocksize;
                }
                r_io_cache_invalidate (core->io, from, to);
            } else {
                eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
                r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize);
            }
            /* See 'r' above. */
            memset (core->block, 0xff, core->blocksize);
            r_core_block_read (core, 0);
            break;
        case '?':
            r_cons_printf (
                "Usage: wc[ir*?]\n"
                " wc           list all write changes\n"
                " wc- [a] [b]  remove write op at curseek or given addr\n"
                " wc*          \"\" in radare commands\n"
                " wcr          reset all write changes in cache\n"
                " wci          commit write cache\n"
                "NOTE: Requires 'e io.cache=true'\n");
            break;
        case '*':
            r_io_cache_list (core->io, R_TRUE);
            break;
        case '\0':
            r_io_cache_list (core->io, R_FALSE);
            break;
        }
        break;
    case ' ':
        /* write string */
        len = r_str_escape (str);
        r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
        r_io_set_fd (core->io, core->file->fd);
        r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
        WSEEK (core, len);
        r_core_block_read (core, 0);
        break;
    case 't':
        if (*str != ' ') {
            eprintf ("Usage: wt file [size]\n");
        } else {
            tmp = strchr (str+1, ' ');
            if (tmp) {
                st64 sz = (st64) r_num_math (core->num, tmp+1);
                *tmp = 0;
                if (sz<1) eprintf ("Invalid length\n");
                else r_core_dump (core, str+1, core->offset, (ut64)sz);
            } else r_file_dump (str+1, core->block, core->blocksize);
        }
        break;
    case 'T':
        eprintf ("TODO: wT // why?\n");
        break;
    case 'f':
        arg = (const char *)(input+((input[1]==' ')?2:1));
        if ((buf = (ut8*) r_file_slurp (arg, &size))) {
            r_io_set_fd (core->io, core->file->fd);
            r_io_write_at (core->io, core->offset, buf, size);
            WSEEK (core, size);
            free(buf);
            r_core_block_read (core, 0);
        } else eprintf ("Cannot open file '%s'\n", arg);
        break;
    case 'F':
        arg = (const char *)(input+((input[1]==' ')?2:1));
        if ((buf = r_file_slurp_hexpairs (arg, &size))) {
            r_io_set_fd (core->io, core->file->fd);
            r_io_write_at (core->io, core->offset, buf, size);
            WSEEK (core, size);
            free (buf);
            r_core_block_read (core, 0);
        } else eprintf ("Cannot open file '%s'\n", arg);
        break;
    case 'w':
        str++;
        len = (len-1)<<1;
        if (len>0) tmp = malloc (len+1);
        else tmp = NULL;
        if (tmp) {
            for (i=0; i<len; i++) {
                if (i%2) tmp[i] = 0;
                else tmp[i] = str[i>>1];
            }
            str = tmp;
            r_io_set_fd (core->io, core->file->fd);
            r_io_write_at (core->io, core->offset, (const ut8*)str, len);
            WSEEK (core, len);
            r_core_block_read (core, 0);
            free (tmp);
        } else eprintf ("Cannot malloc %d\n", len);
        break;
    case 'x':
    {
        int b, len = strlen (input);
        ut8 *buf = malloc (len+1);
        len = r_hex_str2bin (input+1, buf);
        if (len != 0) {
            if (len<0) len = -len+1;
            b = core->block[len]&0xf;
            b |= (buf[len]&0xf0);
            buf[len] = b;
            r_core_write_at (core, core->offset, buf, len);
            WSEEK (core, len);
            r_core_block_read (core, 0);
        } else eprintf ("Error: invalid hexpair string\n");
        free (buf);
    }
    break;
    case 'a':
        switch (input[1]) {
        case 'o':
            if (input[2] == ' ')
                r_core_hack (core, input+3);
            else r_core_hack_help (core);
            break;
        case ' ':
        case '*':
        {   const char *file = input[1]=='*'? input+2: input+1;
            RAsmCode *acode;
            r_asm_set_pc (core->assembler, core->offset);
            acode = r_asm_massemble (core->assembler, file);
            if (acode) {
                if (input[1]=='*') {
                    r_cons_printf ("wx %s\n", acode->buf_hex);
                } else {
                    if (r_config_get_i (core->config, "scr.prompt"))
                        eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
                    r_core_write_at (core, core->offset, acode->buf, acode->len);
                    WSEEK (core, acode->len);
                    r_core_block_read (core, 0);
                }
                r_asm_code_free (acode);
            }
        }
        break;
        case 'f':
            if ((input[2]==' '||input[2]=='*')) {
                const char *file = input[2]=='*'? input+4: input+3;
                RAsmCode *acode;
                r_asm_set_pc (core->assembler, core->offset);
                acode = r_asm_assemble_file (core->assembler, file);
                if (acode) {
                    if (input[2]=='*') {
                        r_cons_printf ("wx %s\n", acode->buf_hex);
                    } else {
                        if (r_config_get_i (core->config, "scr.prompt"))
                            eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
                        r_core_write_at (core, core->offset, acode->buf, acode->len);
                        WSEEK (core, acode->len);
                        r_core_block_read (core, 0);
                    }
                    r_asm_code_free (acode);
                } else eprintf ("Cannot assemble file\n");
            } else eprintf ("Wrong argument\n");
            break;
        default:
            eprintf ("Usage: wa[of*] [arg]\n"
                     " wa nop           : write nopcode using asm.arch and asm.bits\n"
                     " wa* mov eax, 33  : show 'wx' op with hexpair bytes of sassembled opcode\n"
                     " \"wa nop;nop\"     : assemble more than one instruction (note the quotes)\n"
                     " waf foo.asm      : assemble file and write bytes\n"
                     " wao nop          : convert current opcode into nops\n"
                     " wao?             : show help for assembler operation on current opcode (hack)\n");
            break;
        }
        break;
    case 'b':
    {
        int len = strlen (input);
        ut8 *buf = malloc (len+1);
        if (buf) {
            len = r_hex_str2bin (input+1, buf);
            if (len > 0) {
                r_mem_copyloop (core->block, buf, core->blocksize, len);
                r_core_write_at (core, core->offset, core->block, core->blocksize);
                WSEEK (core, core->blocksize);
                r_core_block_read (core, 0);
            } else eprintf ("Wrong argument\n");
        } else eprintf ("Cannot malloc %d\n", len+1);
    }
    break;
    case 'm':
        size = r_hex_str2bin (input+1, (ut8*)str);
        switch (input[1]) {
        case '\0':
            eprintf ("Current write mask: TODO\n");
            // TODO
            break;
        case '?':
            break;
        case '-':
            r_io_set_write_mask(core->io, 0, 0);
            eprintf ("Write mask disabled\n");
            break;
        case ' ':
            if (size>0) {
                r_io_set_fd (core->io, core->file->fd);
                r_io_set_write_mask (core->io, (const ut8*)str, size);
                WSEEK (core, size);
                eprintf ("Write mask set to '");
                for (i=0; i<size; i++)
                    eprintf ("%02x", str[i]);
                eprintf ("'\n");
            } else eprintf ("Invalid string\n");
            break;
        }
        break;
    case 'v':
    {
        int type = 0;
        ut8 addr1;
        ut16 addr2;
        ut32 addr4, addr4_;
        ut64 addr8;

        switch (input[1]) {
        case '?':
            r_cons_printf ("Usage: wv[size] [value]    # write value of given size\n"
                           "  wv1 234      # write one byte with this value\n"
                           "  wv 0x834002  # write dword with this value\n"
                           "Supported sizes are: 1, 2, 4, 8\n");
            return 0;
        case '1':
            type = 1;
            break;
        case '2':
            type = 2;
            break;
        case '4':
            type = 4;
            break;
        case '8':
            type = 8;
            break;
        }
        off = r_num_math (core->num, input+2);
        r_io_set_fd (core->io, core->file->fd);
        r_io_seek (core->io, core->offset, R_IO_SEEK_SET);
        if (type == 0)
            type = (off&UT64_32U)? 8: 4;
        switch (type) {
        case 1:
            addr1 = (ut8)off;
            r_io_write (core->io, (const ut8 *)&addr1, 1);
            WSEEK (core, 1);
            break;
        case 2:
            addr2 = (ut16)off;
            r_io_write (core->io, (const ut8 *)&addr2, 2);
            WSEEK (core, 2);
            break;
        case 4:
            addr4_ = (ut32)off;
            //drop_endian((ut8*)&addr4_, (ut8*)&addr4, 4); /* addr4_ = addr4 */
            //endian_memcpy((ut8*)&addr4, (ut8*)&addr4_, 4); /* addr4 = addr4_ */
            memcpy ((ut8*)&addr4, (ut8*)&addr4_, 4); // XXX needs endian here too
            r_io_write (core->io, (const ut8 *)&addr4, 4);
            WSEEK (core, 4);
            break;
        case 8:
            /* 8 byte addr */
            memcpy ((ut8*)&addr8, (ut8*)&off, 8); // XXX needs endian here
            //	endian_memcpy((ut8*)&addr8, (ut8*)&off, 8);
            r_io_write (core->io, (const ut8 *)&addr8, 8);
            WSEEK (core, 8);
            break;
        }
        r_core_block_read (core, 0);
    }
    break;
    case 'o':
        switch (input[1]) {
        case 'a':
        case 's':
        case 'A':
        case 'x':
        case 'r':
        case 'l':
        case 'm':
        case 'd':
        case 'o':
        case 'w':
            if (input[2]!=' ') {
                r_cons_printf ("Usage: 'wo%c 00 11 22'\n", input[1]);
                return 0;
            }
        case '2':
        case '4':
            r_core_write_op (core, input+3, input[1]);
            r_core_block_read (core, 0);
            break;
        case 'n':
            r_core_write_op (core, "ff", 'x');
            r_core_block_read (core, 0);
            break;
        case '\0':
        case '?':
        default:
            r_cons_printf (
                "Usage: wo[asmdxoArl24] [hexpairs] @ addr[:bsize]\n"
                "Example:\n"
                "  wox 0x90   ; xor cur block with 0x90\n"
                "  wox 90     ; xor cur block with 0x90\n"
                "  wox 0x0203 ; xor cur block with 0203\n"
                "  woa 02 03  ; add [0203][0203][...] to curblk\n"
                "Supported operations:\n"
                "  wow  ==  write looped value (alias for 'wb')\n"
                "  woa  +=  addition\n"
                "  wos  -=  substraction\n"
                "  wom  *=  multiply\n"
                "  wod  /=  divide\n"
                "  wox  ^=  xor\n"
                "  woo  |=  or\n"
                "  woA  &=  and\n"
                "  wor  >>= shift right\n"
                "  wol  <<= shift left\n"
                "  wo2  2=  2 byte endian swap\n"
                "  wo4  4=  4 byte endian swap\n"
            );
            break;
        }
        break;
    default:
    case '?':
        if (core->oobi) {
            eprintf ("Writing oobi buffer!\n");
            r_io_set_fd (core->io, core->file->fd);
            r_io_write (core->io, core->oobi, core->oobi_len);
            WSEEK (core, core->oobi_len);
            r_core_block_read (core, 0);
        } else r_cons_printf (
                "Usage: w[x] [str] [<file] [<<EOF] [@addr]\n"
                " w foobar     write string 'foobar'\n"
                " wr 10        write 10 random bytes\n"
                " ww foobar    write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'\n"
                " wa push ebp  write opcode, separated by ';' (use '\"' around the command)\n"
                " waf file     assemble file and write bytes\n"
                " wA r 0       alter/modify opcode at current seek (see wA?)\n"
                " wb 010203    fill current block with cyclic hexpairs\n"
                " wc[ir*?]     write cache commit/reset/list\n"
                " wx 9090      write two intel nops\n"
                " wv eip+34    write 32-64 bit value\n"
                " wo? hex      write in block with operation. 'wo?' fmi\n"
                " wm f0ff      set binary mask hexpair to be used as cyclic write mask\n"
                " wf file      write contents of file at current offset\n"
                " wF file      write contents of hexpairs file here\n"
                " wt file [sz] write to file (from current seek, blocksize or sz bytes)\n"
                " wp file      apply radare patch file. See wp? fmi\n");
        //TODO: add support for offset+seek
        // " wf file o s ; write contents of file from optional offset 'o' and size 's'.\n"
        break;
    }
Esempio n. 13
0
File: buf.c Progetto: P4N74/radare2
R_API bool r_buf_dump(RBuffer *b, const char *file) {
	if (!b || !file) {
		return false;
	}
	return r_file_dump (file, r_buf_get_at (b, 0, NULL), r_buf_size (b), 0);
}
Esempio n. 14
0
/* TODO: simplify using r_write */
static int cmd_write(void *data, const char *input) {
	int wseek, i, size, len = strlen (input);
	RCore *core = (RCore *)data;
	char *tmp, *str, *ostr;
	const char *arg, *filename;
	char _fn[32];
	ut64 off;
	ut8 *buf;
	st64 num = 0;
	const char* help_msg[] = {
		"Usage:","w[x] [str] [<file] [<<EOF] [@addr]","",
		"w","[1248][+-][n]","increment/decrement byte,word..",
		"w"," foobar","write string 'foobar'",
		"w0"," [len]","write 'len' bytes with value 0x00",
		"w6","[de] base64/hex","write base64 [d]ecoded or [e]ncoded string",
		"wa"," push ebp","write opcode, separated by ';' (use '\"' around the command)",
		"waf"," file","assemble file and write bytes",
		"wA"," r 0","alter/modify opcode at current seek (see wA?)",
		"wb"," 010203","fill current block with cyclic hexpairs",
		"wB","[-]0xVALUE","set or unset bits with given value",
		"wc","","list all write changes",
		"wc","[ir*?]","write cache undo/commit/reset/list (io.cache)",
		"wd"," [off] [n]","duplicate N bytes from offset at current seek (memcpy) (see y?)",
		"we","[nNsxX] [arg]","extend write operations (insert instead of replace)",
		"wf"," -|file","write contents of file at current offset",
		"wF"," -|file","write contents of hexpairs file here",
		"wh"," r2","whereis/which shell command",
		"wm"," f0ff","set binary mask hexpair to be used as cyclic write mask",
		"wo?"," hex","write in block with operation. 'wo?' fmi",
		"wp"," -|file","apply radare patch file. See wp? fmi",
		"wr"," 10","write 10 random bytes",
		"ws"," pstring","write 1 byte for length and then the string",
		"wt"," file [sz]","write to file (from current seek, blocksize or sz bytes)",
		"ww"," foobar","write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'",
		"wx"," 9090","write two intel nops",
		"wv"," eip+34","write 32-64 bit value",
		NULL
	};

	if (!input)
		return 0;

	#define WSEEK(x,y) if (wseek)r_core_seek_delta (x,y)
	wseek = r_config_get_i (core->config, "cfg.wseek");
	str = ostr = strdup ((input&&*input)?input+1:"");
	_fn[0] = 0;

	switch (*input) {
	case 'B':
		switch (input[1]) {
		case ' ':
			cmd_write_bits (core, 1, r_num_math (core->num, input+2));
			break;
		case '-':
			cmd_write_bits (core, 0, r_num_math (core->num, input+2));
			break;
		default:
			eprintf ("Usage: wB 0x2000  # or wB-0x2000\n");
			break;
		}
		break;
	case '0':
		{
			ut64 len = r_num_math (core->num, input+1);
			if (len>0) {
				ut8 *buf = calloc (1, len);
				if (buf) {
					r_io_write (core->io, buf, len);
					free (buf);
				} else eprintf ("Cannot allocate %d bytes\n", (int)len);
			}
		}
		break;
	case '1':
	case '2':
	case '4':
	case '8':
		if (input[1] && input[2]) {
			if (input[1]==input[2]) {
				num = 1;
			} else num = r_num_math (core->num, input+2);
		}
		switch (input[2] ? input[1] : 0) {
		case '+':
			cmd_write_inc (core, *input-'0', num);
			break;
		case '-':
			cmd_write_inc (core, *input-'0', -num);
			break;
		default:
			eprintf ("Usage: w[1248][+-][num]   # inc/dec byte/word/..\n");
		}
		break;
	case '6':
		{
		int fail = 0;
		if(input[1] && input[2] != ' ') {
			fail = 1;
		}
		ut8 *buf;
		int len, str_len;
		const char *str;

		if (input[1] && input[2] && input[3])
			str = input + 3;
		else str = "";
		str_len = strlen (str) + 1;
		if (!fail) {
			switch (input[1]) {
			case 'd':
				buf = malloc (str_len);
				len = r_base64_decode (buf, str, 0);
				if(len == 0) {
					free(buf);
					fail = 1;
				}
				break;
			case 'e':
				{
				ut8 *bin_buf = malloc(str_len);
				int bin_len = r_hex_str2bin(str, bin_buf);
				if(bin_len == 0) {
					fail = 1;
				} else {
					buf = malloc(str_len * 4 + 1);
					len = r_base64_encode((char *)buf, bin_buf, bin_len);
					if(len == 0) {
						free(buf);
						fail = 1;
					}
				}
				free (bin_buf);
				break;
				}
			default:
				fail = 1;
				break;
			}
		}
		if(!fail) {
			r_core_write_at (core, core->offset, buf, len);
			WSEEK (core, len);
			r_core_block_read (core, 0);
			free(buf);
		} else {
			eprintf ("Usage: w6[de] base64/hex\n");
		}
		break;
		}
	case 'h':
		{
		char *p = strchr (input, ' ');
		if (p) {
			while (*p==' ') p++;
			p = r_file_path (p);
			if (p) {
				r_cons_printf ("%s\n", p);
				free (p);
			}
		}
		}
		break;
	case 'e':
		{
		ut64 addr = 0, len = 0, b_size = 0;
		st64 dist = 0;
		ut8* bytes = NULL;
		int cmd_suc = R_FALSE;
		char *input_shadow = NULL, *p = NULL;

		switch (input[1]) {
			case 'n':
				if (input[2] == ' ') {
					len = *input ? r_num_math (
						core->num, input+3) : 0;
					if (len > 0){
						ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, core->offset, len);
						core->offset = cur_off;
						r_core_block_read (core, 0);
					}
				}
				break;
			case 'N':
				if (input[2] == ' ') {
					input += 3;
					while (*input && *input == ' ') input++;
					addr = r_num_math (core->num, input);
					while (*input && *input != ' ') input++;
					input++;
					len = *input ? r_num_math (core->num, input) : 0;
					if (len > 0){
						ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, addr, len);
						cmd_suc = r_core_seek (core, cur_off, 1);
						core->offset = addr;
						r_core_block_read (core, 0);
					}
				}
				break;
			case 'x':
				if (input[2] == ' ') {
					input+=2;
					len = *input ? strlen (input) : 0;
					bytes = len > 1? malloc (len+1) : NULL;
					len = bytes ? r_hex_str2bin (input, bytes) : 0;
					if (len > 0) {
						ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, cur_off, len);
						if (cmd_suc) {
							r_core_write_at (core, cur_off, bytes, len);
						}
						core->offset = cur_off;
						r_core_block_read (core, 0);
					}
					free (bytes);
				}
				break;
			case 'X':
				if (input[2] == ' ') {
					addr = r_num_math (core->num, input+3);
					input += 3;
					while (*input && *input != ' ') input++;
					input++;
					len = *input ? strlen (input) : 0;
					bytes = len > 1? malloc (len+1) : NULL;
					len = bytes ? r_hex_str2bin (input, bytes) : 0;
					if (len > 0) {
						//ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, addr, len);
						if (cmd_suc) {
							r_core_write_at (core, addr, bytes, len);
						}
						core->offset = addr;
						r_core_block_read (core, 0);
					}
					free (bytes);
				}
				break;
			case 's':
				input +=  3;
				while (*input && *input == ' ') input++;
				len = strlen (input);
				input_shadow = len > 0? malloc (len+1): 0;

				// since the distance can be negative,
				// the r_num_math will perform an unwanted operation
				// the solution is to tokenize the string :/
				if (input_shadow) {
					strncpy (input_shadow, input, len+1);
					p = strtok (input_shadow, " ");
					addr = p && *p ? r_num_math (core->num, p) : 0;

					p = strtok (NULL, " ");
					dist = p && *p ? r_num_math (core->num, p) : 0;

					p = strtok (NULL, " ");
					b_size = p && *p ? r_num_math (core->num, p) : 0;
					if (dist != 0){
						r_core_shift_block (core, addr, b_size, dist);
						r_core_seek (core, addr, 1);
						cmd_suc = R_TRUE;
					}
				}
				free (input_shadow);
				break;
			case '?':
			default:
				cmd_suc = R_FALSE;
		}


		if (cmd_suc == R_FALSE) {
			r_cons_printf ("|Usage: write extend\n"
			"wen <num>               insert num null bytes at current offset\n"
			"wex <hex_bytes>         insert bytes at current offset\n"
			"weN <addr> <len>        insert bytes at address\n"
			"weX <addr> <hex_bytes>  insert bytes at address\n"
			"wes <addr>  <dist> <block_size>   shift a blocksize left or write in the editor\n"
			);
		}
		}
		break;
	case 'p':
		if (input[1]=='-' || (input[1]==' ' && input[2]=='-')) {
			char *out = r_core_editor (core, NULL, NULL);
			if (out) {
				r_core_patch (core, out);
				free (out);
			}
		} else {
			if (input[1]==' ' && input[2]) {
				char *data = r_file_slurp (input+2, NULL);
				if (data) {
					r_core_patch (core, data);
					free (data);
				}
			} else {
				eprintf ("Usage: wp [-|r2patch-file]\n"
			         "TODO: rapatch format documentation here\n");
			}
		}
		break;
	case 'u':
		// TODO: implement it in an API RCore.write_unified_hexpatch() is ETOOLONG
		if (input[1]==' ') {
			char *data = r_file_slurp (input+2, NULL);
			if (data) {
				char sign = ' ';
				int line = 0, offs = 0, hexa = 0;
				int newline = 1;
				for (i=0; data[i]; i++) {
					switch (data[i]) {
					case '+':
						if (newline)
							sign = 1;
						break;
					case '-':
						if (newline) {
							sign = 0;
							offs = i + ((data[i+1]==' ')?2:1);
						}
						break;
					case ' ':
						data[i] = 0;
						if (sign) {
							if (!line) line = i+1;
							else
							if (!hexa) hexa = i+1;
						}
						break;
					case '\r':
						break;
					case '\n':
						newline = 1;
						if (sign == -1) {
							offs = 0;
							line = 0;
							hexa = 0;
						} else if (sign) {
							if (offs && hexa) {
								r_cons_printf ("wx %s @ %s\n", data+hexa, data+offs);
							} else eprintf ("food\n");
							offs = 0;
							line = 0;
						} else hexa = 0;
						sign = -1;
						continue;
					}
					newline = 0;
				}
				free (data);
			}
		} else {
			eprintf ("|Usage: wu [unified-diff-patch]    # see 'cu'\n");
		}
		break;
	case 'r':
		off = r_num_math (core->num, input+1);
		len = (int)off;
		if (len>0) {
			buf = malloc (len);
			if (buf != NULL) {
				r_num_irand ();
				for (i=0; i<len; i++)
					buf[i] = r_num_rand (256);
				r_core_write_at (core, core->offset, buf, len);
				WSEEK (core, len);
				free (buf);
			} else eprintf ("Cannot allocate %d bytes\n", len);
		}
		break;
	case 'A':
		switch (input[1]) {
		case ' ':
			if (input[2] && input[3]==' ') {
				r_asm_set_pc (core->assembler, core->offset);
				eprintf ("modify (%c)=%s\n", input[2], input+4);
				len = r_asm_modify (core->assembler, core->block, input[2],
					r_num_math (core->num, input+4));
				eprintf ("len=%d\n", len);
				if (len>0) {
					r_core_write_at (core, core->offset, core->block, len);
					WSEEK (core, len);
				} else eprintf ("r_asm_modify = %d\n", len);
			} else eprintf ("Usage: wA [type] [value]\n");
			break;
		case '?':
		default:
			r_cons_printf ("|Usage: wA [type] [value]\n"
			"|Types:\n"
			"| r   raw write value\n"
			"| v   set value (taking care of current address)\n"
			"| d   destination register\n"
			"| 0   1st src register\n"
			"| 1   2nd src register\n"
			"|Example: wA r 0 # e800000000\n");
			break;
		}
		break;
	case 'c':
		switch (input[1]) {
		case 'i':
			r_io_cache_commit (core->io, 0, UT64_MAX);
			r_core_block_read (core, 0);
			break;
		case 'r':
			r_io_cache_reset (core->io, R_TRUE);
			/* Before loading the core block we have to make sure that if
			 * the cache wrote past the original EOF these changes are no
			 * longer displayed. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core, 0);
			break;
		case '+':
			if (input[2]=='*') {
				//r_io_cache_reset (core->io, R_TRUE);
				eprintf ("TODO\n");
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from = core->offset;
				if (p) {
					*p = 0;
					from = r_num_math (core->num, input+3);
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					from = r_num_math (core->num, input+3);
					to = from + core->blocksize;
				}
				r_io_cache_commit (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_commit (core->io, core->offset, core->offset+1);
			}
			break;
		case '-':
			if (input[2]=='*') {
				r_io_cache_reset (core->io, R_TRUE);
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from = core->offset;
				if (p) {
					*p = 0;
					from = r_num_math (core->num, input+3);
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					from = r_num_math (core->num, input+3);
					to = from + core->blocksize;
				}
				r_io_cache_invalidate (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize);
			}
			/* See 'r' above. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core, 0);
			break;
		case '?':
	{
                const char* help_msg[] = {
			"Usage:", "wc[ir+-*?]","  # NOTE: Uses io.cache=true",
			"wc","","list all write changes",
			"wc-"," [from] [to]","remove write op at curseek or given addr",
			"wc+"," [addr]","commit change from cache to io",
			"wc*","","\"\" in radare commands",
			"wcr","","reset all write changes in cache",
			"wci","","commit write cache",
                        NULL
                        };
                        r_core_cmd_help(core, help_msg);
        }
			break;
		case '*':
			r_io_cache_list (core->io, R_TRUE);
			break;
		case '\0':
			//if (!r_config_get_i (core->config, "io.cache"))
			//	eprintf ("[warning] e io.cache must be true\n");
			r_io_cache_list (core->io, R_FALSE);
			break;
		}
		break;
	case ' ':
		/* write string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
		r_io_use_desc (core->io, core->file->desc);
		r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
		WSEEK (core, len);
		r_core_block_read (core, 0);
		break;
	case 't': // "wt"
		if (*str == '?' || *str == '\0') {
			eprintf ("Usage: wt[a] file [size]   write 'size' bytes in current block to file\n");
			free (ostr);
			return 0;
		} else {
			int append = 0;
			st64 sz = core->blocksize;
			if (*str=='a') { // "wta"
				append = 1;
				str++;
				if (str[0]==' ') {
					filename = str+1;
				} else {
					const char* prefix = r_config_get (core->config, "cfg.prefixdump");
					snprintf (_fn, sizeof (_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
					filename = _fn;
				}
			} else if (*str != ' ') {
				const char* prefix = r_config_get (core->config, "cfg.prefixdump");
				snprintf(_fn, sizeof(_fn), "%s.0x%08"PFMT64x, prefix, core->offset);
				filename = _fn;
			} else filename = str+1;
			tmp = strchr (str+1, ' ');
			if (tmp) {
				sz = (st64) r_num_math (core->num, tmp+1);
				if (!sz) {
					sz = core->blocksize;
				}
				*tmp = 0;
				if (sz<1) eprintf ("Invalid length\n");
				else r_core_dump (core, filename, core->offset, (ut64)sz, append);
			} else {
				if (!r_file_dump (filename, core->block, core->blocksize, append)) {
					sz = 0;
				} else sz = core->blocksize;
			}
			eprintf ("Dumped %"PFMT64d" bytes from 0x%08"PFMT64x" into %s\n",
				sz, core->offset, filename);
		}
		break;
	case 'f':
		arg = (const char *)(input+((input[1]==' ')?2:1));
		if (!strcmp (arg, "-")) {
			char *out = r_core_editor (core, NULL, NULL);
			if (out) {
				r_io_write_at (core->io, core->offset,
					(ut8*)out, strlen (out));
				free (out);
			}
		} else
		if ((buf = (ut8*) r_file_slurp (arg, &size))) {
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, buf, size);
			WSEEK (core, size);
			free (buf);
			r_core_block_read (core, 0);
		} else eprintf ("Cannot open file '%s'\n", arg);
		break;
	case 'F':
		arg = (const char *)(input+((input[1]==' ')?2:1));
		if (!strcmp (arg, "-")) {
			int len;
			ut8 *out;
			char *in = r_core_editor (core, NULL, NULL);
			if (in) {
				out = (ut8 *)strdup (in);
				if (out) {
					len = r_hex_str2bin (in, out);
					if (len>0)
						r_io_write_at (core->io, core->offset, out, len);
					free (out);
				}
				free (in);
			}
		} else
		if ((buf = r_file_slurp_hexpairs (arg, &size))) {
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, buf, size);
			WSEEK (core, size);
			free (buf);
			r_core_block_read (core, 0);
		} else eprintf ("Cannot open file '%s'\n", arg);
		break;
	case 'w':
		str++;
		len = (len-1)<<1;
		if (len>0) tmp = malloc (len+1);
		else tmp = NULL;
		if (tmp) {
			for (i=0; i<len; i++) {
				if (i%2) tmp[i] = 0;
				else tmp[i] = str[i>>1];
			}
			str = tmp;
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, (const ut8*)str, len);
			WSEEK (core, len);
			r_core_block_read (core, 0);
			free (tmp);
		} else eprintf ("Cannot malloc %d\n", len);
		break;
	case 'x':
		{
		int b, len = strlen (input);
		ut8 *buf = malloc (len+1);
		len = r_hex_str2bin (input+1, buf);
		if (len != 0) {
			if (len<0) len = -len+1;
			if (len<core->blocksize) {
				b = core->block[len]&0xf;
				b |= (buf[len]&0xf0);
			} else b = buf[len];
			buf[len] = b;
			r_core_write_at (core, core->offset, buf, len);
			WSEEK (core, len);
			r_core_block_read (core, 0);
		} else eprintf ("Error: invalid hexpair string\n");
		free (buf);
		}
		break;
	case 'a':
		switch (input[1]) {
		case 'o':
			if (input[2] == ' ')
				r_core_hack (core, input+3);
			else r_core_hack_help (core);
			break;
		case ' ':
		case '*':
			{ const char *file = input[1]=='*'? input+2: input+1;
			RAsmCode *acode;
			r_asm_set_pc (core->assembler, core->offset);
			acode = r_asm_massemble (core->assembler, file);
			if (acode) {
				if (input[1]=='*') {
					r_cons_printf ("wx %s\n", acode->buf_hex);
				} else {
					if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s) = wx %s\n", acode->len, input+2, acode->buf_hex);
					r_core_write_at (core, core->offset, acode->buf, acode->len);
					WSEEK (core, acode->len);
					r_core_block_read (core, 0);
				}
				r_asm_code_free (acode);
			}
			} break;
		case 'f':
			if ((input[2]==' '||input[2]=='*')) {
				const char *file = input[2]=='*'? input+4: input+3;
				RAsmCode *acode;
				r_asm_set_pc (core->assembler, core->offset);
				acode = r_asm_assemble_file (core->assembler, file);
				if (acode) {
					if (input[2]=='*') {
						r_cons_printf ("wx %s\n", acode->buf_hex);
					} else {
						if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
						r_core_write_at (core, core->offset, acode->buf, acode->len);
						WSEEK (core, acode->len);
						r_core_block_read (core, 0);
					}
					r_asm_code_free (acode);
				} else eprintf ("Cannot assemble file\n");
			} else eprintf ("Wrong argument\n");
			break;
		default:
			r_cons_printf ("|Usage: wa[of*] [arg]\n"
				"| wa nop           : write nopcode using asm.arch and asm.bits\n"
				"| wa* mov eax, 33  : show 'wx' op with hexpair bytes of assembled opcode\n"
				"| \"wa nop;nop\"     : assemble more than one instruction (note the quotes)\n"
				"| waf foo.asm      : assemble file and write bytes\n"
				"| wao nop          : convert current opcode into nops\n"
				"| wao?             : show help for assembler operation on current opcode (hack)\n");
			break;
		}
		break;
	case 'b':
		{
		int len = strlen (input);
		ut8 *buf = malloc (len+1);
		if (buf) {
			len = r_hex_str2bin (input+1, buf);
			if (len > 0) {
				r_mem_copyloop (core->block, buf, core->blocksize, len);
				r_core_write_at (core, core->offset, core->block, core->blocksize);
				WSEEK (core, core->blocksize);
				r_core_block_read (core, 0);
			} else eprintf ("Wrong argument\n");
			free (buf);
		} else eprintf ("Cannot malloc %d\n", len+1);
		}
		break;
	case 'm':
		size = r_hex_str2bin (input+1, (ut8*)str);
		switch (input[1]) {
		case '\0':
			eprintf ("Current write mask: TODO\n");
			// TODO
			break;
		case '?':
			break;
		case '-':
			r_io_set_write_mask (core->io, 0, 0);
			eprintf ("Write mask disabled\n");
			break;
		case ' ':
			if (size>0) {
				r_io_use_desc (core->io, core->file->desc);
				r_io_set_write_mask (core->io, (const ut8*)str, size);
				WSEEK (core, size);
				eprintf ("Write mask set to '");
				for (i=0; i<size; i++)
					eprintf ("%02x", str[i]);
				eprintf ("'\n");
			} else eprintf ("Invalid string\n");
			break;
		}
		break;
	case 'v':
		cmd_write_value (core, input);
		break;
	case 'o':
		cmd_write_op (core, input);
		break;
	case 'd':
		if (input[1] && input[1]==' ') {
			char *arg, *inp = strdup (input+2);
			arg = strchr (inp, ' ');
			if (arg) {
				*arg = 0;
				ut64 addr = r_num_math (core->num, input+2);
				ut64 len = r_num_math (core->num, arg+1);
				ut8 *data = malloc (len);
				r_io_read_at (core->io, addr, data, len);
				r_io_write_at (core->io, core->offset, data, len);
				free (data);
			} else eprintf ("See wd?\n");
			free (inp);
		} else eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n");
		break;
	case 's':
		if (str && *str && str[1]) {
			len = r_str_unescape (str+1);
			if (len>255) {
				eprintf ("Too large\n");
			} else {
				ut8 ulen = (ut8)len;
				r_core_write_at (core, core->offset, &ulen, 1);
				r_core_write_at (core, core->offset+1, (const ut8*)str+1, len);
				WSEEK (core, len);
				r_core_block_read (core, 0);
			}
		} else eprintf ("Too short.\n");
		break;
	default:
	case '?':
		if (core->oobi) {
			eprintf ("Writing oobi buffer!\n");
			r_io_use_desc (core->io, core->file->desc);
			r_io_write (core->io, core->oobi, core->oobi_len);
			WSEEK (core, core->oobi_len);
			r_core_block_read (core, 0);
		} else {
			r_core_cmd_help (core, help_msg);
		}
		break;
	}
Esempio n. 15
0
static int cmd_project(void *data, const char *input) {
	RCore *core = (RCore *)data;
	const char *file, *arg = input+1;
	const char *fileproject = r_config_get (core->config, "file.project");
	char *str = strdup (fileproject);
	if (*arg==' ') arg++;
	file = input[1]?arg:str;
	switch (input[0]) {
	case 'c':
		if (!input[1]) {
			eprintf ("TODO: Show project saving script to console\n");
		} else if (input[1]==' ') {
			r_core_project_cat (core, input+2);
		} else eprintf ("Usage: Pc [prjname]\n");
		break;
	case 'o':
	//	if (r_file_is_regular (file))
		if (input[1]) {
			r_core_project_open (core, file);
		} else {
			if (file && *file)
				r_cons_printf ("%s\n", file);
		}
		break;
	case 'l':
		r_core_project_list (core, input[1]);
		break;
	case 'd':
		r_core_project_delete (core, file);
		break;
	case 's':
		if (r_core_project_save (core, file)) {
			r_config_set (core->config, "file.project", file);
			r_cons_printf ("%s\n", file);
		}
		break;
	case 'n':
		if (!fileproject || !*fileproject) {
			eprintf ("No project\n");
		} else
		switch (input[1]) {
		case '-':
			/* remove lines containing specific words */
			{
			char *str = r_core_project_notes_file (core, fileproject);
			char *data = r_file_slurp (str, NULL);
			FILE *fd = r_sandbox_fopen (str, "w");
			if (!fd) {
				eprintf ("Cannot open %s\n", str);
			} else {
				int del = 0;
				if (data) {
					char *ptr, *nl;
					for (ptr = data; ptr; ptr = nl)  {
						nl = strchr (ptr, '\n');
						if (nl) {
							*nl++ = 0;
							if (strstr (ptr, input+2)) {
								del ++;
							} else {
								fprintf (fd, "%s\n", ptr);
							}
						}
					}
					free (data);
				}
				fclose (fd);
				free (str);
				if (del>0) {
					eprintf ("Deleted %d lines\n", del);
				}
			}
			}
			break;
		case ' ':
			if (input[2]=='-') {
				char *str = r_core_project_notes_file (core, fileproject);
				// edit with cfg.editor
				const char *editor = r_config_get (core->config, "cfg.editor");
				if (str && *str && editor && *editor)
					r_sys_cmdf ("%s %s", editor, str);
				else eprintf ("No cfg.editor configured\n");
				free (str);
			} else {
				//char *str = r_core_project_notes_file (core, fileproject);
				// append line to project notes
				char *str = r_core_project_notes_file (core, fileproject);
				char *data = r_file_slurp (str, NULL);
				FILE *fd = r_sandbox_fopen (str, "a");
				if (fd) {
					fprintf (fd, "%s\n", input+2);
					fclose (fd);
				}
				free (str);
				free (data);
			}
			break;
		case 'j':
			if (!input[2]) {
				int len = 0;
				/* get base64 string */
				char *str = r_core_project_notes_file (core, fileproject);
				if (str) {
					char *data = r_file_slurp (str, &len);
					char *res = r_base64_encode_dyn (data, len);
					if (res) {
						r_cons_printf ("%s\n", res);
						free (res);
					}
					free (data);
					free (str);
				}
			} else if (input[2] == ' ') {
				/* set base64 string */
				ut8 *data = r_base64_decode_dyn (input+3, 0);
				if (data) {
					char *str = r_core_project_notes_file (core, fileproject);
					if (str) {
						r_file_dump (str, data, strlen ((const char*)data));
						free (str);
					}
					free (data);
				}
			} else {
				eprintf ("Usage: `Pnj` or `Pnj ...`\n");
			}
			break;
		case 0:
			{
			char *str = r_core_project_notes_file (core, fileproject);
			char *data = r_file_slurp (str, NULL);
			if (data) {
				r_cons_printf ("%s\n", data);
				free (data);
			}
			free (str);
			}
			break;
		case '?':
			{
				const char* help_msg[] = {
					"Usage:", "Pn[j-?] [...]", "Project Notes",
					"Pn", "", "show project notes",
					"Pn", " -", "edit notes with cfg.editor",
					"Pn-", "", "delete notes",
					"Pn-", "str", "delete lines matching /str/ in notes",
					"Pnj", "", "show notes in base64",
					"Pnj", " [base64]", "set notes in base64",
					NULL};
				r_core_cmd_help (core, help_msg);
			}
			break;
		}
		break;
	case 'i':
//		if (r_file_is_regular (file))
		free (r_core_project_info (core, file));
		break;
	default: {
		const char* help_msg[] = {
		"Usage:", "P[?osi] [file]", "Project management",
		"Pc", "", "show what will be saved in the project script",
		"Pc", " [file]", "show project script to console",
		"Pd", " [file]", "delete project",
		"Pi", " [file]", "show project information",
		"Pl", "", "list all projects",
		"Pn", "[j]", "show project notes (Pnj for json)",
		"Pn", " [base64]", "set notes text",
		"Pn", " -", "edit notes with cfg.editor",
		"Po", " [file]", "open project",
		"Ps", " [file]", "save project",
		"NOTE:", "", "See 'e file.project'",
		"NOTE:", "", "project files are stored in ~/.config/radare2/projects",
		NULL};
		r_core_cmd_help (core, help_msg);
		}
		break;
	}
	free (str);
	return R_TRUE;
}
Esempio n. 16
0
static int cmd_cmp(void *data, const char *input) {
	RCore *core = data;
	FILE *fd;
	ut8 *buf;
	int ret;
	ut32 v32;
	ut64 v64;

	switch (*input) {
	case ' ':
		radare_compare (core, core->block, (ut8*)input+1, strlen (input+1)+1);
		break;
	case 'x':
		if (input[1]!=' ') {
			eprintf ("Usage: cx 001122'\n");
			return 0;
		}
		buf = (ut8*)malloc (strlen (input+2));
		ret = r_hex_str2bin (input+2, buf);
		if (ret<1) eprintf ("Cannot parse hexpair\n");
		else radare_compare (core, core->block, buf, ret);
		free (buf);
		break;
	case 'X':
		buf = malloc (core->blocksize);
		ret = r_io_read_at (core->io, r_num_math (core->num, input+1), buf, core->blocksize);
		radare_compare (core, core->block, buf, ret);
		free (buf);
		break;
	case 'f':
		if (input[1]!=' ') {
			eprintf ("Please. use 'cf [file]'\n");
			return 0;
		}
		fd = fopen (input+2, "rb");
		if (fd == NULL) {
			eprintf ("Cannot open file '%s'\n", input+2);
			return 0;
		}
		buf = (ut8 *)malloc (core->blocksize);
		fread (buf, 1, core->blocksize, fd);
		fclose (fd);
		radare_compare (core, core->block, buf, core->blocksize);
		free (buf);
		break;
	case 'q':
		v64 = (ut64) r_num_math (core->num, input+1);
		radare_compare (core, core->block, (ut8*)&v64, sizeof (v64));
		break;
	case 'd':
		v32 = (ut32) r_num_math (core->num, input+1);
		radare_compare (core, core->block, (ut8*)&v32, sizeof (v32));
		break;
#if 0
	case 'c':
		radare_compare_code (
			r_num_math (core->num, input+1),
			core->block, core->blocksize);
		break;
	case 'D':
		{ // XXX ugly hack
		char cmd[1024];
		sprintf (cmd, "radiff -b %s %s", ".curblock", input+2);
		r_file_dump (".curblock", config.block, config.block_size);
		radare_system(cmd);
		unlink(".curblock");
		}
		break;
#endif
	case 'g':
		{ // XXX: this is broken
			int diffops = 0;
		RCore *core2;
		char *file2 = NULL;
		if (input[1]=='o') {
			file2 = (char*)r_str_chop_ro (input+2);
			r_anal_diff_setup (core->anal, R_TRUE, -1, -1);
		} else
		if (input[1]==' ') {
			file2 = (char*)r_str_chop_ro (input+2);
			r_anal_diff_setup (core->anal, R_FALSE, -1, -1);
		} else {
			eprintf ("Usage: cg[o] [file]\n");
			eprintf (" cg  - byte-per-byte code graph diff\n");
			eprintf (" cgo - opcode-bytes code graph diff\n");
			return R_FALSE;
		}

		if (!(core2 = r_core_new ())) {
			eprintf ("Cannot init diff core\n");
			return R_FALSE;
		}
		core2->io->va = core->io->va;
		core2->anal->split = core->anal->split;
		if (!r_core_file_open (core2, file2, 0, 0LL)) {
			eprintf ("Cannot open diff file '%s'\n", file2);
			r_core_free (core2);
			return R_FALSE;
		}
		// TODO: must replicate on core1 too
		r_config_set_i (core2->config, "io.va", R_TRUE);
		r_config_set_i (core2->config, "anal.split", R_TRUE);
                r_anal_diff_setup (core->anal, diffops, -1, -1);
                r_anal_diff_setup (core2->anal, diffops, -1, -1);

		r_core_bin_load (core2, file2);
		r_core_gdiff (core, core2);
		r_core_diff_show (core, core2);
		r_core_free (core2);
		}
		break;
	case '?':
		r_cons_strcat (
		"Usage: c[?cdfx] [argument]\n"
		" c  [string]   Compares a plain with escaped chars string\n"
		//" cc [offset]   Code bindiff current block against offset\n"
		" cd [value]    Compare a doubleword from a math expression\n"
		//" cD [file]     Like above, but using radiff -b\n");
		" cq [value]    Compare a quadword from a math expression\n"
		" cx [hexpair]  Compare hexpair string\n"
		" cX [addr]     Like 'cc' but using hexdiff output\n"
		" cf [file]     Compare contents of file at current seek\n"
		" cg[o] [file]  Graphdiff current file and [file]\n");
		break;
	default:
		eprintf ("Usage: c[?Ddxf] [argument]\n");
	}

	return 0;
}
Esempio n. 17
0
R_API int r_diff_buffers_static(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
	int i, len;
	int hit = 0;
	la = R_ABS(la);
	lb = R_ABS(lb);
	if (la != lb) {
	 	len = R_MIN(la, lb);
		fprintf(stderr,
			"Buffer truncated to %d bytes (%d not compared)\n",
			len, R_ABS(lb-la));
	} else len = la;
	for(i = 0; i<len; i++) {
		if (a[i]!=b[i]) {
			hit++;
		} else {
			if (hit>0) {
				struct r_diff_op_t o = {
					.a_off = d->off_a+i-hit, .a_buf = a+i-hit, .a_len = hit,
					.b_off = d->off_b+i-hit, .b_buf = b+i-hit, .b_len = hit
				};
				d->callback (d, d->user, &o);
				hit = 0;
			}
		}
	}
	if (hit>0) {
		struct r_diff_op_t o = {
			.a_off = d->off_a+i-hit, .a_buf = a+i-hit, .a_len = hit,
			.b_off = d->off_b+i-hit, .b_buf = b+i-hit, .b_len = hit
		};
		d->callback (d, d->user, &o);
		hit = 0;
	}
	return 0;
}

// XXX: temporary files are
R_API int r_diff_buffers_radiff(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
	char *ptr, *str, buf[64], oop = 0;
	int ret, atl, btl, hit;
	ut8 at[128], bt[128];
	ut64 ooa, oob;
	FILE *fd;

	hit = atl = btl = 0;
	ooa = oob = 0LL;
	oop = -1;

	r_file_dump (".a", a, la, 0);
	r_file_dump (".b", b, lb, 0);
	r_sys_cmd ("radiff -d .a .b | rsc uncolor > .d");
	fd = fopen (".d", "r");
	if (!fd) return 0;

	while (!feof (fd)) {
		ut64 oa, ob; // offset
		int ba, bb = 0; // byte
		char op; // operation

		oa = ob = 0LL;
		if (!fgets (buf, 63, fd))
			break;
		if (feof (fd))
			break;
		str = buf;

		ptr = strchr (buf, ' ');
		if (!ptr) continue;
		*ptr='\0';
		sscanf (str, "0x%08"PFMT64x"", &oa);

		str = r_str_ichr (ptr+1, ' ');
		if (*str!='|'&&*str!='>'&&*str!='<') {
			ptr = strchr (str, ' ');
			if (!ptr) continue;
			*ptr='\0';
			sscanf (str, "%02x", &ba);
		} else ba = 0;

		str = r_str_ichr (ptr+1, ' ');
		ptr = strchr (str, ' ');
		if (!ptr) continue;
		*ptr='\0';
		sscanf (str, "%c", &op);

		str = r_str_ichr (ptr+1, ' ');
		if (str[0]!='0' || str[1]!='x') {
			ptr = strchr(str, ' ');
			if (!ptr) continue;
			*ptr = '\0';
			sscanf (str, "%02x", &bb);
		}

		str = ptr+1;
		ptr = strchr (str, '\n');
		if (!ptr) continue;
		*ptr='\0';
		sscanf (str, "0x%08"PFMT64x"", &ob);

		if (oop == op || oop==-1) {
			if (hit == 0) {
				ooa = oa;
				oob = ob;
			}
			at[atl] = ba;
			bt[btl] = bb;
			switch (op) {
			case '|':
				atl++;
				btl++;
				break;
			case '>':
				btl++;
				break;
			case '<':
				atl++;
				break;
			}
			hit++;
		} else {
			if (hit>0) {
				struct r_diff_op_t o = {
					.a_off = ooa, .a_buf = at, .a_len = atl,
					.b_off = oob, .b_buf = bt, .b_len = btl
				};
				ret = d->callback(d, d->user, &o);
				if (!ret)
					break;
				atl = btl = 0;
				hit = 0;
			}
		}
		oop = op;
	}
	if (hit > 0) {
		struct r_diff_op_t o = {
			.a_off = ooa, .a_buf = at, .a_len = atl,
			.b_off = oob, .b_buf = bt, .b_len = btl
		};
		if (!d->callback (d, d->user, &o)) {
			fclose (fd);
			return 0;
		}
		atl = btl = 0;
		hit = 0;
	}
	fclose (fd);
	unlink (".a");
	unlink (".b");
	unlink (".d");
	return 0;
}

R_API int r_diff_buffers(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb) {
	if (d->delta) {
		return r_diff_buffers_delta (d, a, la, b, lb);
	}
	return r_diff_buffers_static (d, a, la, b, lb);
}

/* TODO: Move into r_util maybe? */
R_API bool r_diff_buffers_distance(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb, ut32 *distance, double *similarity) {
	const bool verbose = d? d->verbose: false;
	/* 
	More memory efficient version on Levenshtein Distance from:
	https://en.wikipedia.org/wiki/Levenshtein_distance
	http://www.codeproject.com/Articles/13525/Fast-memory-efficient-Levenshtein-algorithm
	ObM..
	*/
	int i, j;
	/* TODO: ensure those pointers are allocated */
	int *v0 = (int*) calloc ((lb + 1), sizeof (int));
	int *v1 = (int*) calloc ((lb + 1), sizeof (int));	
	
	if (!a || !b || la < 1 || lb < 1) {
		free (v0);
		free (v1);
		return false;
	}

	if (la == lb && !memcmp (a, b, la)) {
		if (distance) {
			*distance = 0;
		}
		if (similarity) {
			*similarity = 1.0;
		}
		free (v0);
		free (v1);
		return true;
	}

	for (i = 0; i < lb + 1 ; i++) {
		v0[i] = i;
	}

	for (i = 0; i < la; i++) {
		v1[0] = i + 1;

		for (j = 0; j < lb; j++) {
			int cost = (a[i] == b[j]) ? 0 : 1;
			int smallest = R_MIN ((v1[j] + 1), (v0[j + 1] + 1));
			smallest = R_MIN (smallest, (v0[j] + cost));
			v1[j + 1] = smallest;
		}

		for (j = 0; j < lb + 1; j++) {
			v0[j] = v1[j];
		}
		if (verbose && (i % 10000 == 0))
			eprintf ("Processing %d of %d\r", i, la - 1);
	}
	if (verbose) {
		eprintf ("\rProcessing %d of %d\n", i, la - 1);
	}
	
	if (distance) {
		*distance = v1[lb];
		if (similarity) {
			double diff = (double) (*distance) / (double) (R_MAX (la, lb));
			*similarity = (double)1 - diff;
		}
	}
	free (v0);
	free (v1);
	return true;
}
Esempio n. 18
0
R_API int r_core_rtr_http(RCore *core, int launch, const char *path) {
	char buf[32];
	RSocketHTTPRequest *rs;
	int iport, oldsandbox = -1;
	int timeout = r_config_get_i (core->config, "http.timeout");
	int x = r_config_get_i (core->config, "scr.html");
	int y = r_config_get_i (core->config, "scr.color");
	int z = r_config_get_i (core->config, "asm.bytes");
	int u = r_config_get_i (core->config, "scr.interactive");
	int v = r_config_get_i (core->config, "asm.cmtright");
	const char *port = r_config_get (core->config, "http.port");
	char *allow = (char *)r_config_get (core->config, "http.allow");
	if (core->http_up) {
		eprintf ("http server is already running\n");
		return 1;
	}
	if (r_sandbox_enable (0)) {
		eprintf ("sandbox: connect disabled\n");
		return 1;
	}
	if (path && atoi (path)) {
		port = path;
		path = NULL;
	}
	if (!strcmp (port, "0")) {
		r_num_irand ();
		iport = 1024+r_num_rand (45256);
		snprintf (buf, sizeof (buf), "%d", iport);
		port = buf;
	}
	s = r_socket_new (R_FALSE);
	s->local = !r_config_get_i (core->config, "http.public");
	if (!r_socket_listen (s, port, NULL)) {
		eprintf ("Cannot listen on http.port\n");
		return 1;
	}
	if (launch) {
		char cmd[128];
		const char *browser = r_config_get (core->config, "http.browser");
		snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s &",
			browser, atoi (port), path?path:"");
		r_sys_cmd (cmd);
	}
	r_config_set (core->config, "asm.cmtright", "false");
	r_config_set (core->config, "scr.html", "true");
	r_config_set (core->config, "scr.color", "false");
	r_config_set (core->config, "asm.bytes", "false");
	r_config_set (core->config, "scr.interactive", "false");
	if (r_config_get_i (core->config, "http.sandbox")) {
		oldsandbox = r_config_get_i (core->config, "cfg.sandbox");
		r_config_set (core->config, "cfg.sandbox", "true");
	}
	eprintf ("Starting http server...\n");
	eprintf ("http://localhost:%d/\n", atoi (port));
	core->http_up = R_TRUE;
	while (!r_cons_singleton ()->breaked) {
		r_cons_break ((RConsBreak)http_break, core);
		rs = r_socket_http_accept (s, timeout);
		if (!rs) {
			if (!s) break;
			r_sys_usleep (100);
			continue;
		}
		if (allow && *allow) {
			int accepted = R_FALSE;
			const char *host;
			char *p, *peer = r_socket_to_string (rs->s);
			char *allows = strdup (allow);
			//eprintf ("Firewall (%s)\n", allows);
			int i, count = r_str_split (allows, ',');
			p = strchr (peer, ':');
			if (p) *p = 0;
			for (i=0; i<count; i++) {
				host = r_str_word_get0 (allows, i);
				//eprintf ("--- (%s) (%s)\n", host, peer);
				if (!strcmp (host, peer)) {
					accepted = R_TRUE;
					break;
				}
			}
			free (peer);
			free (allows);
			if (!accepted) {
				r_socket_http_close (rs);
				continue;
			}
		}
		if (!rs->method || !rs->path) {
			eprintf ("Invalid http headers received from client\n");
			r_socket_http_close (rs);
			continue;
		}
		char *dir = NULL;

		if (r_config_get_i (core->config, "http.dirlist"))
			if (r_file_is_directory (rs->path))
				dir = strdup (rs->path);
		if (!strcmp (rs->method, "GET")) {
			if (!memcmp (rs->path, "/up", 3)) {
				if (r_config_get_i (core->config, "http.upget")) {
					const char *uproot = r_config_get (core->config, "http.uproot");
					if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) {
						char *ptr = rtr_dir_files (uproot);
						r_socket_http_response (rs, 200, ptr, 0, NULL);
						free (ptr);
					} else {
						char *path = r_file_root (uproot, rs->path + 4);
						if (r_file_exists (path)) {
							int sz = 0;
							char *f = r_file_slurp (path, &sz);
							if (f) {
								r_socket_http_response (rs, 200, f, sz, NULL);
								free (f);
							} else {
								r_socket_http_response (rs, 403, "Permission denied", 0, NULL);
								eprintf ("http: Cannot open '%s'\n", path);
							}
						} else {
							if (dir) {
								char *resp = rtr_dir_files (dir);
								r_socket_http_response (rs, 404, resp, 0, NULL);
								free (resp);
							} else {
								eprintf ("File '%s' not found\n", path);
								r_socket_http_response (rs, 404, "File not found\n", 0, NULL);
							}
						}
						free (path);
					}
				} else {
					r_socket_http_response (rs, 403,
							"Permission denied\n", 0, NULL);
				}
			} else if (!memcmp (rs->path, "/cmd/", 5)) {
				char *cmd = rs->path +5;
				char foo[32];
				const char *httpcmd = r_config_get (core->config, "http.uri");
				while (*cmd=='/') cmd++;
				if (httpcmd && *httpcmd) {
					int len;
					char *res;
					// do remote http query and proxy response
					snprintf (foo, sizeof (foo), "%s/%s", httpcmd, cmd);
					res = r_socket_http_get (foo, NULL, &len);
					if (res) {
						res[len]=0;
						r_cons_printf ("%s\n", res);
					}
				} else {
					char *out, *cmd = rs->path+5;
					r_str_uri_decode (cmd);
					// eprintf ("CMD (%s)\n", cmd);
					out = r_core_cmd_str_pipe (core, cmd);
					// eprintf ("\nOUT LEN = %d\n", strlen (out));
					if (out) {
						char *res = r_str_uri_encode (out);
						r_socket_http_response (rs, 200, out, 0,
							"Content-Type: text/plain\n");
						free (out);
						free (res);
					} else r_socket_http_response (rs, 200, "", 0, NULL);
				}
			} else {
				const char *root = r_config_get (core->config, "http.root");
				char *path = r_file_root (root, rs->path);
				// FD IS OK HERE
				if (rs->path [strlen (rs->path)-1] == '/') {
					path = r_str_concat (path, "index.html");
					//rs->path = r_str_concat (rs->path, "index.html");
				} else {
					//snprintf (path, sizeof (path), "%s/%s", root, rs->path);
					if (r_file_is_directory (path)) {
						char res[128];
						snprintf (res, sizeof (res),
							"Location: %s/\n", rs->path);
						r_socket_http_response (rs, 302,
							NULL, 0, res);
						r_socket_http_close (rs);
						free (path);
						free (dir);
						dir = NULL;
						continue;
					}
				}
				if (r_file_exists (path)) {
					int sz = 0;
					char *f = r_file_slurp (path, &sz);
					if (f) {
						const char *contenttype = NULL;
						if (strstr (path, ".js")) contenttype = "Content-Type: application/javascript\n";
						if (strstr (path, ".css")) contenttype = "Content-Type: text/css\n";
						if (strstr (path, ".html")) contenttype = "Content-Type: text/html\n";
						r_socket_http_response (rs, 200, f, sz, contenttype);
						free (f);
					} else {
						r_socket_http_response (rs, 403, "Permission denied", 0, NULL);
						eprintf ("http: Cannot open '%s'\n", path);
					}
				} else {
					if (dir) {
						char *resp = rtr_dir_files (dir);
						eprintf ("Dirlisting %s\n", dir);
						r_socket_http_response (rs, 404, resp, 0, NULL);
						free (resp);
					} else {
						eprintf ("File '%s' not found\n", path);
						r_socket_http_response (rs, 404, "File not found\n", 0, NULL);
					}
				}
				free (path);
			}
		} else 
		if (!strcmp (rs->method, "POST")) {
			ut8 *ret;
			int retlen;
			char buf[128];
			if (r_config_get_i (core->config, "http.upload")) {
				ret = r_socket_http_handle_upload (
					rs->data, rs->data_length, &retlen);
				if (ret) {
					ut64 size = r_config_get_i (core->config, "http.maxsize");
					if (size && retlen > size) {
						r_socket_http_response (rs, 403, "403 File too big\n", 0, NULL);
					} else {
						char *filename = r_file_root (
							r_config_get (core->config, "http.uproot"),
							rs->path + 4);
						eprintf ("UPLOADED '%s'\n", filename);
						r_file_dump (filename, ret, retlen);
						free (filename);
						snprintf (buf, sizeof (buf),
							"<html><body><h2>uploaded %d bytes. Thanks</h2>\n", retlen);
							r_socket_http_response (rs, 200, buf, 0, NULL);
					}
					free (ret);
				}
			} else {
				r_socket_http_response (rs, 403, "403 Forbidden\n", 0, NULL);
			}
		} else {
			r_socket_http_response (rs, 404, "Invalid protocol", 0, NULL);
		}
		r_socket_http_close (rs);
		free (dir);
	}
	core->http_up = R_FALSE;
	r_socket_free (s);
	r_cons_break_end ();
	r_config_set_i (core->config, "scr.html", x);
	r_config_set_i (core->config, "scr.color", y);
	r_config_set_i (core->config, "asm.bytes", z);
	r_config_set_i (core->config, "scr.interactive", u);
	r_config_set_i (core->config, "asm.cmtright", v);
	if (oldsandbox != -1)
		r_config_set_i (core->config, "cfg.sandbox", oldsandbox);
	return 0;
}
Esempio n. 19
0
static int cmd_project(void *data, const char *input) {
	RCore *core = (RCore *) data;
	const char *file, *arg = (input && *input)? input + 1: NULL;
	const char *fileproject = r_config_get (core->config, "prj.name");
	char *str = NULL;

	if (!input) {
		return false;
	}
	str = strdup (fileproject);
	arg = strchr (input, ' ');
	if (arg) {
		arg++;
	} else {
		if (*input) {
			arg = input + 1;
			if (*arg == '&') {
				arg++;
			}
		}
	}
	file = arg;
	switch (input[0]) {
	case 'c':
		if (input[1] == ' ') {
			r_core_project_cat (core, input + 2);
		} else {
			eprintf ("Usage: Pc [prjname]\n");
		}
		break;
	case 'o':
		//	if (r_file_is_regular (file))
		if (input[1] == '&') {
			r_core_project_open (core, file, true);
		} else if (input[1]) {
			r_core_project_open (core, file, false);
		} else {
			if (file && *file) {
				r_cons_println (file);
			}
		}
		break;
	case 'l':
		r_core_project_list (core, input[1]);
		break;
	case 'd':
	case '-':
		r_core_project_delete (core, file);
		break;
	case 's':
		if (!file || !file[0]) { /* if no argument specified use current project */
			file = str;
		}
		if (r_core_project_save (core, file)) {
			r_config_set (core->config, "prj.name", file);
			r_cons_println (file);
		}
		break;
	case 'S':
		if (input[1] == ' ') {
			r_core_project_save_rdb (core, input + 2, R_CORE_PRJ_ALL);
		} else {
			eprintf ("Usage: PS [file]\n");
		}
		break;
	case 'n':
		if (!fileproject || !*fileproject) {
			eprintf ("No project\n");
		} else {
			switch (input[1]) {
			case '-':
				/* remove lines containing specific words */
			{
				FILE *fd = r_sandbox_fopen (str, "w");
				if (!fd) {
					eprintf ("Cannot open %s\n", str);
				} else {
					char *str = r_core_project_notes_file (core, fileproject);
					char *data = r_file_slurp (str, NULL);
					int del = 0;
					if (data) {
						char *ptr, *nl;
						for (ptr = data; ptr; ptr = nl)  {
							nl = strchr (ptr, '\n');
							if (nl) {
								*nl++ = 0;
								if (strstr (ptr, input + 2)) {
									del++;
								} else {
									fprintf (fd, "%s\n", ptr);
								}
							}
						}
						free (data);
					}
					if (del > 0) {
						eprintf ("Deleted %d lines\n", del);
					}
					free (str);
					fclose (fd);
				}
			}
			break;
			case ' ':
				if (input[2] == '-') {
					char *str = r_core_project_notes_file (core, fileproject);
					// edit with cfg.editor
					const char *editor = r_config_get (core->config, "cfg.editor");
					if (str && *str && editor && *editor) {
						r_sys_cmdf ("%s %s", editor, str);
					} else {
						eprintf ("No cfg.editor configured\n");
					}
					free (str);
				} else {
					//char *str = r_core_project_notes_file (core, fileproject);
					// append line to project notes
					char *str = r_core_project_notes_file (core, fileproject);
					char *data = r_file_slurp (str, NULL);
					FILE *fd = r_sandbox_fopen (str, "a");
					if (fd) {
						fprintf (fd, "%s\n", input + 2);
						fclose (fd);
					}
					free (str);
					free (data);
				}
				break;
			case 'j':
				if (!input[2]) {
					int len = 0;
					/* get base64 string */
					char *str = r_core_project_notes_file (core, fileproject);
					if (str) {
						char *data = r_file_slurp (str, &len);
						char *res = r_base64_encode_dyn (data, len);
						if (res) {
							r_cons_println (res);
							free (res);
						}
						free (data);
						free (str);
					}
				} else if (input[2] == ' ') {
					/* set base64 string */
					ut8 *data = r_base64_decode_dyn (input + 3, -1);
					if (data) {
						char *str = r_core_project_notes_file (core, fileproject);
						if (str) {
							r_file_dump (str, data, strlen ((const char *) data), 0);
							free (str);
						}
						free (data);
					}
				} else {
					eprintf ("Usage: `Pnj` or `Pnj ...`\n");
				}
				break;
			case 'x':
				r_core_project_execute_cmds (core, fileproject);
				break;
			case 0:
			{
				char *str = r_core_project_notes_file (core, fileproject);
				char *data = r_file_slurp (str, NULL);
				if (data) {
					r_cons_println (data);
					free (data);
				}
				free (str);
			}
			break;
			case '?':
			{
				const char *help_msg[] = {
					"Usage:", "Pn[j-?] [...]", "Project Notes",
					"Pn", "", "show project notes",
					"Pn", " -", "edit notes with cfg.editor",
					"Pn-", "", "delete notes",
					"Pn-", "str", "delete lines matching /str/ in notes",
					"Pnx", "", "run project note commands",
					"Pnj", "", "show notes in base64",
					"Pnj", " [base64]", "set notes in base64",
					NULL
				};
				r_core_cmd_help (core, help_msg);
			}
			break;
			}
		}
		break;
	case 'i':
		if (file && *file) {
			char *prjName = r_core_project_info (core, file);
			r_cons_println (prjName);
			free (prjName);
		}
		break;
	default: {
		const char *help_msg[] = {
			"Usage:", "P[?osi] [file]", "Project management",
			"Pc", " [file]", "show project script to console",
			"Pd", " [file]", "delete project",
			"Pi", " [file]", "show project information",
			"Pl", "", "list all projects",
			"Pn", "[j]", "show project notes (Pnj for json)",
			"Pn", " [base64]", "set notes text",
			"Pn", " -", "edit notes with cfg.editor",
			"Po", " [file]", "open project",
			"Ps", " [file]", "save project",
			"PS", " [file]", "save script file",
			"P-", " [file]", "delete project (alias for Pd)",
			"NOTE:", "", "See 'e??prj.'",
			"NOTE:", "", "project are stored in ~/.config/radare2/projects",
			NULL
		};
		r_core_cmd_help (core, help_msg);
	}
		break;
	}
	free (str);
	return true;
}
Esempio n. 20
0
R_API char* r_egg_Cfile_parser(const char *file, const char *arch, const char *os, int bits) {
	char *output = NULL;
	char *fileExt = NULL; // "file" with extension (.s, .text, ...)
	struct cEnv_t *cEnv = r_egg_Cfile_set_cEnv (arch, os, bits);

	if (!cEnv) {
		goto fail;
	}

	r_str_sanitize (cEnv->CC);

	//printf ("==> Compile\n");
	printf ("'%s' %s -o '%s.tmp' -S -Os '%s'\n", cEnv->CC, cEnv->CFLAGS, file, file);

	output = r_sys_cmd_strf ("('%s' %s -o '%s.tmp' -S -Os '%s') 2>&1",
	  			cEnv->CC, cEnv->CFLAGS, file, file);
	if (output == NULL) {
		eprintf ("Compilation failed!\n");
		goto fail;
	}
	printf ("%s", output);

	if (!(fileExt = r_str_newf ("%s.s", file))) {
		goto fail;
	}

	if (!r_file_dump (fileExt, (const ut8*) cEnv->SHDR, strlen (cEnv->SHDR), false)) {
		eprintf ("Error while opening %s.s\n", file);
		goto fail;
	}

	if (!r_egg_Cfile_parseCompiled (file)) {
		goto fail;
	}

	//printf ("==> Assemble\n");
	printf ("'%s' %s -Os -o '%s.o' '%s.s'\n", cEnv->CC, cEnv->LDFLAGS, file, file);

	free (output);
	output = r_sys_cmd_strf ("'%s' %s -Os -o '%s.o' '%s.s'",
		   		cEnv->CC, cEnv->LDFLAGS, file, file);
	if (!output) {
		eprintf ("Assembly failed!\n");
		goto fail;
	}
	printf ("%s", output);

	//printf ("==> Link\n");
	printf ("rabin2 -o '%s.text' -O d/S/'%s' '%s.o'\n", file, cEnv->TEXT, file);

	free (output);
	output = r_sys_cmd_strf ("rabin2 -o '%s.text' -O d/S/'%s' '%s'.o",
		   		file, cEnv->TEXT, file);
	if (!output) {
		eprintf ("Linkage failed!\n");
		goto fail;
	}

	free (fileExt);
	if (!(fileExt = r_str_newf ("%s.o", file))) {
		goto fail;
	}

	if (!r_file_exists (fileExt)) {
		eprintf ("Cannot find %s.o\n", file);
		goto fail;
	}

	free (fileExt);
	if (!(fileExt = r_str_newf ("%s.text", file))) {
		goto fail;
	}
	if (r_file_size (fileExt) == 0) {
		printf ("FALLBACK: Using objcopy instead of rabin2");

		free (output);
		output = r_sys_cmd_strf ("'%s' -j .text -O binary '%s.o' '%s.text'", 
		  		cEnv->OBJCOPY, file, file);
		if (!output) {
			eprintf ("objcopy failed!\n");
			goto fail;
		}
	}

	size_t i;
	const char *extArray[] = {"bin", "tmp", "s", "o"};
	for (i = 0; i < 4; i++) {
		free (fileExt);
		if (!(fileExt = r_str_newf ("%s.%s", file, extArray[i]))) {
			goto fail;
		}
		r_file_rm (fileExt);
	}

	free (fileExt);
	if ((fileExt = r_str_newf ("%s.text", file)) == NULL) {
		goto fail;
	}

	free (output);
	r_egg_Cfile_free_cEnv (cEnv);
	return fileExt;

fail:
	free (fileExt);
	free (output);
	r_egg_Cfile_free_cEnv (cEnv);
	return NULL;
}
Esempio n. 21
0
R_API int r_bin_wr_output(RBin *bin, const char *filename) {
	return r_file_dump (filename, bin->cur.buf->buf,
			bin->cur.buf->length);
}
Esempio n. 22
0
/* TODO: simplify using r_write */
static int cmd_write(void *data, const char *input) {
	ut64 off;
	ut8 *buf;
	const char *arg;
	int wseek, i, size, len = strlen (input);
	char *tmp, *str, *ostr;
	RCore *core = (RCore *)data;
	#define WSEEK(x,y) if (wseek)r_core_seek_delta (x,y)
	wseek = r_config_get_i (core->config, "cfg.wseek");
	str = ostr = strdup (input+1);

	switch (*input) {
	case 'h':
		{
		char *p = strchr (input, ' ');
		if (p) {
			while (*p==' ') p++;
			p = r_file_path (p);
			if (p) {
				r_cons_printf ("%s\n", p);
				free (p);
			}
		}
		}
		break;
	case 'e':
		{
		ut64 addr = 0, len = 0, b_size = 0;
		st64 dist = 0;
		ut8* bytes = NULL;
		int cmd_suc = R_FALSE;
		char *input_shadow = NULL, *p = NULL;

		switch (input[1]) {
			case 'n':
				if (input[2] == ' ') {
					len = *input ? r_num_math (core->num, input+3) : 0;
					if (len > 0){
						ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, core->offset, len);
						core->offset = cur_off;
						r_core_block_read (core, 0);
					}
				}
				break;
			case 'N':
				if (input[2] == ' ') {
					input += 3;
					while (*input && *input == ' ') input++;
					addr = r_num_math (core->num, input);
					while (*input && *input != ' ') input++;
					input++;
					len = *input ? r_num_math (core->num, input) : 0;
					if (len > 0){
						ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, addr, len);
						cmd_suc = r_core_seek (core, cur_off, 1);
						core->offset = addr;
						r_core_block_read (core, 0);
					}
				}
				break;
			case 'x':
				if (input[2] == ' ') {
					input+=2;
					len = *input ? strlen (input) : 0;
					bytes = len > 1? malloc (len+1) : NULL;
					len = bytes ? r_hex_str2bin (input, bytes) : 0;
					if (len > 0) {
						ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, cur_off, len);
						if (cmd_suc) {
							r_core_write_at (core, cur_off, bytes, len);
						}
						core->offset = cur_off;
						r_core_block_read (core, 0);
					}
					free (bytes);
				}
				break;
			case 'X':
				if (input[2] == ' ') {
					addr = r_num_math (core->num, input+3);
					input += 3;
					while (*input && *input != ' ') input++;
					input++;
					len = *input ? strlen (input) : 0;
					bytes = len > 1? malloc (len+1) : NULL;
					len = bytes ? r_hex_str2bin (input, bytes) : 0;
					if (len > 0) {
						//ut64 cur_off = core->offset;
						cmd_suc = r_core_extend_at (core, addr, len);
						if (cmd_suc) {
							r_core_write_at (core, addr, bytes, len);
						}
						core->offset = addr;
						r_core_block_read (core, 0);
					}
					free (bytes);
				}
				break;
			case 's':
				input +=  3;
				while (*input && *input == ' ') input++;
				len = strlen (input);
				input_shadow = len > 0? malloc (len+1): 0;

				// since the distance can be negative,
				// the r_num_math will perform an unwanted operation
				// the solution is to tokenize the string :/
				if (input_shadow) {
					strncpy (input_shadow, input, len+1);
					p = strtok (input_shadow, " ");
					addr = p && *p ? r_num_math (core->num, p) : 0;

					p = strtok (NULL, " ");
					dist = p && *p ? r_num_math (core->num, p) : 0;

					p = strtok (NULL, " ");
					b_size = p && *p ? r_num_math (core->num, p) : 0;
					if (dist != 0){
						r_core_shift_block (core, addr, b_size, dist);
						r_core_seek (core, addr, 1);
						cmd_suc = R_TRUE;
					}
				}
				free (input_shadow);
				break;
			case '?':
			default:
				cmd_suc = R_FALSE;
		}


		if (cmd_suc == R_FALSE) {
			r_cons_printf ("|Usage: write extend\n"
			"wen <num>               insert num null bytes at current offset\n"
			"wex <hex_bytes>         insert bytes at current offset\n"
			"weN <addr> <len>        insert bytes at address\n"
			"weX <addr> <hex_bytes>  insert bytes at address\n"
			"wes <addr>  <dist> <block_size>   shift a blocksize left or write in the editor\n"
			);
		}
		}
		break;
	case 'p':
		if (input[1]=='-' || (input[1]==' '&&input[2]=='-')) {
			const char *tmpfile = ".tmp";
			char *out = r_core_editor (core, NULL);
			if (out) {
				// XXX hacky .. patch should support str, not only file
				r_file_dump (tmpfile, (ut8*)out, strlen (out));
				r_core_patch (core, tmpfile);
				r_file_rm (tmpfile);
				free (out);
			}
		} else {
			if (input[1]==' ' && input[2]) {
				r_core_patch (core, input+2);
			} else {
				eprintf ("Usage: wp [-|r2patch-file]\n"
			         "TODO: rapatch format documentation here\n");
			}
		}
		break;
	case 'u':
		// TODO: implement it in an API RCore.write_unified_hexpatch() is ETOOLONG
		if (input[1]==' ') {
			char *data = r_file_slurp (input+2, NULL);
			if (data) {
				char sign = ' ';
				int line = 0, offs = 0, hexa = 0;
				int newline = 1;
				for (i=0; data[i]; i++) {
					switch (data[i]) {
					case '+':
						if (newline)
							sign = 1;
						break;
					case '-':
						if (newline) {
							sign = 0;
							offs = i + ((data[i+1]==' ')?2:1);
						}
						break;
					case ' ':
						data[i] = 0;
						if (sign) {
							if (!line) line = i+1;
							else
							if (!hexa) hexa = i+1;
						}
						break;
					case '\r':
						break;
					case '\n':
						newline = 1;
						if (sign == -1) {
							offs = 0;
							line = 0;
							hexa = 0;
						} else if (sign) {
							if (offs && hexa) {
								r_cons_printf ("wx %s @ %s\n", data+hexa, data+offs);
							} else eprintf ("food\n");
							offs = 0;
							line = 0;
						} else hexa = 0;
						sign = -1;
						continue;
					}
					newline = 0;
				}
				free (data);
			}
		} else {
			eprintf ("|Usage: wu [unified-diff-patch]    # see 'cu'\n");
		}
		break;
	case 'r':
		off = r_num_math (core->num, input+1);
		len = (int)off;
		if (len>0) {
			buf = malloc (len);
			if (buf != NULL) {
				r_num_irand ();
				for (i=0; i<len; i++)
					buf[i] = r_num_rand (256);
				r_core_write_at (core, core->offset, buf, len);
				WSEEK (core, len);
				free (buf);
			} else eprintf ("Cannot allocate %d bytes\n", len);
		}
		break;
	case 'A':
		switch (input[1]) {
		case ' ':
			if (input[2] && input[3]==' ') {
				r_asm_set_pc (core->assembler, core->offset);
				eprintf ("modify (%c)=%s\n", input[2], input+4);
				len = r_asm_modify (core->assembler, core->block, input[2],
					r_num_math (core->num, input+4));
				eprintf ("len=%d\n", len);
				if (len>0) {
					r_core_write_at (core, core->offset, core->block, len);
					WSEEK (core, len);
				} else eprintf ("r_asm_modify = %d\n", len);
			} else eprintf ("Usage: wA [type] [value]\n");
			break;
		case '?':
		default:
			r_cons_printf ("|Usage: wA [type] [value]\n"
			"|Types:\n"
			"| r   raw write value\n"
			"| v   set value (taking care of current address)\n"
			"| d   destination register\n"
			"| 0   1st src register\n"
			"| 1   2nd src register\n"
			"|Example: wA r 0 # e800000000\n");
			break;
		}
		break;
	case 'c':
		switch (input[1]) {
		case 'i':
			r_io_cache_commit (core->io);
			r_core_block_read (core, 0);
			break;
		case 'r':
			r_io_cache_reset (core->io, R_TRUE);
			/* Before loading the core block we have to make sure that if
			 * the cache wrote past the original EOF these changes are no
			 * longer displayed. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core, 0);
			break;
		case '-':
			if (input[2]=='*') {
				r_io_cache_reset (core->io, R_TRUE);
			} else if (input[2]==' ') {
				char *p = strchr (input+3, ' ');
				ut64 to, from = core->offset;
				if (p) {
					*p = 0;
					from = r_num_math (core->num, input+3);
					to = r_num_math (core->num, input+3);
					if (to<from) {
						eprintf ("Invalid range (from>to)\n");
						return 0;
					}
				} else {
					from = r_num_math (core->num, input+3);
					to = from + core->blocksize;
				}
				r_io_cache_invalidate (core->io, from, to);
			} else {
				eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset);
				r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize);
			}
			/* See 'r' above. */
			memset (core->block, 0xff, core->blocksize);
			r_core_block_read (core, 0);
			break;
		case '?':
			r_cons_printf (
			"|Usage: wc[ir*?]\n"
			"| wc           list all write changes\n"
			"| wc- [a] [b]  remove write op at curseek or given addr\n"
			"| wc*          \"\" in radare commands\n"
			"| wcr          reset all write changes in cache\n"
			"| wci          commit write cache\n"
			"|NOTE: Requires 'e io.cache=true'\n");
			break;
		case '*':
			r_io_cache_list (core->io, R_TRUE);
			break;
		case '\0':
			if (!r_config_get_i (core->config, "io.cache"))
				eprintf ("[warning] e io.cache must be true\n");
			r_io_cache_list (core->io, R_FALSE);
			break;
		}
		break;
	case ' ':
		/* write string */
		len = r_str_unescape (str);
		r_core_write_at (core, core->offset, (const ut8*)str, len);
#if 0
		r_io_use_desc (core->io, core->file->desc);
		r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
		WSEEK (core, len);
		r_core_block_read (core, 0);
		break;
	case 't':
		if (*str != ' ') {
			eprintf ("Usage: wt file [size]\n");
		} else {
			tmp = strchr (str+1, ' ');
			if (tmp) {
				st64 sz = (st64) r_num_math (core->num, tmp+1);
				*tmp = 0;
				if (sz<1) eprintf ("Invalid length\n");
				else r_core_dump (core, str+1, core->offset, (ut64)sz);
			} else r_file_dump (str+1, core->block, core->blocksize);
		}
		break;
	case 'T':
		eprintf ("TODO: wT // why?\n");
		break;
	case 'f':
		arg = (const char *)(input+((input[1]==' ')?2:1));
		if (!strcmp (arg, "-")) {
			char *out = r_core_editor (core, NULL);
			if (out) {
				r_io_write_at (core->io, core->offset,
					(ut8*)out, strlen (out));
				free (out);
			}
		} else
		if ((buf = (ut8*) r_file_slurp (arg, &size))) {
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, buf, size);
			WSEEK (core, size);
			free (buf);
			r_core_block_read (core, 0);
		} else eprintf ("Cannot open file '%s'\n", arg);
		break;
	case 'F':
		arg = (const char *)(input+((input[1]==' ')?2:1));
		if (!strcmp (arg, "-")) {
			int len;
			ut8 *out;
			char *in = r_core_editor (core, NULL);
			if (in) {
				out = (ut8 *)strdup (in);
				if (out) {
					len = r_hex_str2bin (in, out);
					if (len>0)
						r_io_write_at (core->io, core->offset, out, len);
					free (out);
				}
				free (in);
			}
		} else
		if ((buf = r_file_slurp_hexpairs (arg, &size))) {
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, buf, size);
			WSEEK (core, size);
			free (buf);
			r_core_block_read (core, 0);
		} else eprintf ("Cannot open file '%s'\n", arg);
		break;
	case 'w':
		str++;
		len = (len-1)<<1;
		if (len>0) tmp = malloc (len+1);
		else tmp = NULL;
		if (tmp) {
			for (i=0; i<len; i++) {
				if (i%2) tmp[i] = 0;
				else tmp[i] = str[i>>1];
			}
			str = tmp;
			r_io_use_desc (core->io, core->file->desc);
			r_io_write_at (core->io, core->offset, (const ut8*)str, len);
			WSEEK (core, len);
			r_core_block_read (core, 0);
			free (tmp);
		} else eprintf ("Cannot malloc %d\n", len);
		break;
	case 'x':
		{
		int b, len = strlen (input);
		ut8 *buf = malloc (len+1);
		len = r_hex_str2bin (input+1, buf);
		if (len != 0) {
			if (len<0) len = -len+1;
			if (len<core->blocksize) {
				b = core->block[len]&0xf;
				b |= (buf[len]&0xf0);
			} else b = buf[len];
			buf[len] = b;
			r_core_write_at (core, core->offset, buf, len);
			WSEEK (core, len);
			r_core_block_read (core, 0);
		} else eprintf ("Error: invalid hexpair string\n");
		free (buf);
		}
		break;
	case 'a':
		switch (input[1]) {
		case 'o':
			if (input[2] == ' ')
				r_core_hack (core, input+3);
			else r_core_hack_help (core);
			break;
		case ' ':
		case '*':
			{ const char *file = input[1]=='*'? input+2: input+1;
			RAsmCode *acode;
			r_asm_set_pc (core->assembler, core->offset);
			acode = r_asm_massemble (core->assembler, file);
			if (acode) {
				if (input[1]=='*') {
					r_cons_printf ("wx %s\n", acode->buf_hex);
				} else {
					if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s) = wx %s\n", acode->len, input+2, acode->buf_hex);
					r_core_write_at (core, core->offset, acode->buf, acode->len);
					WSEEK (core, acode->len);
					r_core_block_read (core, 0);
				}
				r_asm_code_free (acode);
			}
			} break;
		case 'f':
			if ((input[2]==' '||input[2]=='*')) {
				const char *file = input[2]=='*'? input+4: input+3;
				RAsmCode *acode;
				r_asm_set_pc (core->assembler, core->offset);
				acode = r_asm_assemble_file (core->assembler, file);
				if (acode) {
					if (input[2]=='*') {
						r_cons_printf ("wx %s\n", acode->buf_hex);
					} else {
						if (r_config_get_i (core->config, "scr.prompt"))
						eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
						r_core_write_at (core, core->offset, acode->buf, acode->len);
						WSEEK (core, acode->len);
						r_core_block_read (core, 0);
					}
					r_asm_code_free (acode);
				} else eprintf ("Cannot assemble file\n");
			} else eprintf ("Wrong argument\n");
			break;
		default:
			r_cons_printf ("|Usage: wa[of*] [arg]\n"
				"| wa nop           : write nopcode using asm.arch and asm.bits\n"
				"| wa* mov eax, 33  : show 'wx' op with hexpair bytes of sassembled opcode\n"
				"| \"wa nop;nop\"     : assemble more than one instruction (note the quotes)\n"
				"| waf foo.asm      : assemble file and write bytes\n"
				"| wao nop          : convert current opcode into nops\n"
				"| wao?             : show help for assembler operation on current opcode (hack)\n");
			break;
		}
		break;
	case 'b':
		{
		int len = strlen (input);
		ut8 *buf = malloc (len+1);
		if (buf) {
			len = r_hex_str2bin (input+1, buf);
			if (len > 0) {
				r_mem_copyloop (core->block, buf, core->blocksize, len);
				r_core_write_at (core, core->offset, core->block, core->blocksize);
				WSEEK (core, core->blocksize);
				r_core_block_read (core, 0);
			} else eprintf ("Wrong argument\n");
			free (buf);
		} else eprintf ("Cannot malloc %d\n", len+1);
		}
		break;
	case 'm':
		size = r_hex_str2bin (input+1, (ut8*)str);
		switch (input[1]) {
		case '\0':
			eprintf ("Current write mask: TODO\n");
			// TODO
			break;
		case '?':
			break;
		case '-':
			r_io_set_write_mask (core->io, 0, 0);
			eprintf ("Write mask disabled\n");
			break;
		case ' ':
			if (size>0) {
				r_io_use_desc (core->io, core->file->desc);
				r_io_set_write_mask (core->io, (const ut8*)str, size);
				WSEEK (core, size);
				eprintf ("Write mask set to '");
				for (i=0; i<size; i++)
					eprintf ("%02x", str[i]);
				eprintf ("'\n");
			} else eprintf ("Invalid string\n");
			break;
		}
		break;
	case 'v':
		{
			int type = 0;
			ut8 addr1;
			ut16 addr2;
			ut32 addr4, addr4_;
			ut64 addr8;

			switch (input[1]) {
			case '?':
				r_cons_printf ("|Usage: wv[size] [value]    # write value of given size\n"
					"|  wv1 234      # write one byte with this value\n"
					"|  wv 0x834002  # write dword with this value\n"
					"|Supported sizes are: 1, 2, 4, 8\n");
				return 0;
			case '1': type = 1; break;
			case '2': type = 2; break;
			case '4': type = 4; break;
			case '8': type = 8; break;
			}
			off = r_num_math (core->num, input+2);
			r_io_use_desc (core->io, core->file->desc);
			r_io_seek (core->io, core->offset, R_IO_SEEK_SET);
			if (type == 0)
				type = (off&UT64_32U)? 8: 4;
			switch (type) {
			case 1:
				addr1 = (ut8)off;
				r_io_write (core->io, (const ut8 *)&addr1, 1);
				WSEEK (core, 1);
				break;
			case 2:
				addr2 = (ut16)off;
				r_io_write (core->io, (const ut8 *)&addr2, 2);
				WSEEK (core, 2);
				break;
			case 4:
				addr4_ = (ut32)off;
				//drop_endian((ut8*)&addr4_, (ut8*)&addr4, 4); /* addr4_ = addr4 */
				//endian_memcpy((ut8*)&addr4, (ut8*)&addr4_, 4); /* addr4 = addr4_ */
				memcpy ((ut8*)&addr4, (ut8*)&addr4_, 4); // XXX needs endian here too
				r_io_write (core->io, (const ut8 *)&addr4, 4);
				WSEEK (core, 4);
				break;
			case 8:
				/* 8 byte addr */
				memcpy ((ut8*)&addr8, (ut8*)&off, 8); // XXX needs endian here
			//	endian_memcpy((ut8*)&addr8, (ut8*)&off, 8);
				r_io_write (core->io, (const ut8 *)&addr8, 8);
				WSEEK (core, 8);
				break;
			}
			r_core_block_read (core, 0);
		}
		break;
	case 'o':
		switch (input[1]) {
			case 'a':
			case 's':
			case 'e':
			case 'A':
			case 'x':
			case 'r':
			case 'l':
			case 'm':
			case 'd':
			case 'o':
			case 'w':
				if (input[2]!=' ') {
					if (input[1]=='e') r_cons_printf (
						"Usage: 'woe from-to step'\n");
					else r_cons_printf (
						"Usage: 'wo%c 00 11 22'\n", input[1]);
					free (ostr);
					return 0;
				}
			case '2':
			case '4':
				r_core_write_op (core, input+3, input[1]);
				r_core_block_read (core, 0);
				break;
			case 'R':
				r_core_cmd0 (core, "wr $b");
				break;
			case 'n':
				r_core_write_op (core, "ff", 'x');
				r_core_block_read (core, 0);
				break;
			case '\0':
			case '?':
			default:
				r_cons_printf (
					"|Usage: wo[asmdxoArl24] [hexpairs] @ addr[:bsize]\n"
					"|Example:\n"
					"|  wox 0x90   ; xor cur block with 0x90\n"
					"|  wox 90     ; xor cur block with 0x90\n"
					"|  wox 0x0203 ; xor cur block with 0203\n"
					"|  woa 02 03  ; add [0203][0203][...] to curblk\n"
					"|  woe 02 03  \n"
					"|Supported operations:\n"
					"|  wow  ==  write looped value (alias for 'wb')\n"
					"|  woa  +=  addition\n"
					"|  wos  -=  substraction\n"
					"|  wom  *=  multiply\n"
					"|  wod  /=  divide\n"
					"|  wox  ^=  xor\n"
					"|  woo  |=  or\n"
					"|  woA  &=  and\n"
					"|  woR  random bytes (alias for 'wr $b'\n"
					"|  wor  >>= shift right\n"
					"|  wol  <<= shift left\n"
					"|  wo2  2=  2 byte endian swap\n"
					"|  wo4  4=  4 byte endian swap\n"
						);
				break;
		}
		break;
	case 'd':
		if (input[1]==' ') {
			char *arg, *inp = strdup (input+2);
			arg = strchr (inp, ' ');
			if (arg) {
				*arg = 0;
				ut64 addr = r_num_math (core->num, input+2);
				ut64 len = r_num_math (core->num, arg+1);
				ut8 *data = malloc (len);
				r_io_read_at (core->io, addr, data, len);
				r_io_write_at (core->io, core->offset, data, len);
				free (data);
			} else eprintf ("See wd?\n");
			free (inp);
		} else eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n");
		break;
	case 's':
		{
			ut8 ulen;
			len = r_str_unescape (str+1);
			if (len>255) {
				eprintf ("Too large\n");
			} else {
				ulen = (ut8)len;
				r_core_write_at (core, core->offset, &ulen, 1);
				r_core_write_at (core, core->offset+1, (const ut8*)str+1, len);
				WSEEK (core, len);
				r_core_block_read (core, 0);
			}
		}
		break;
	default:
	case '?':
		if (core->oobi) {
			eprintf ("Writing oobi buffer!\n");
			r_io_use_desc (core->io, core->file->desc);
			r_io_write (core->io, core->oobi, core->oobi_len);
			WSEEK (core, core->oobi_len);
			r_core_block_read (core, 0);
		} else r_cons_printf (
			"|Usage: w[x] [str] [<file] [<<EOF] [@addr]\n"
			"| w foobar     write string 'foobar'\n"
			"| wh r2        whereis/which shell command\n"
			"| wr 10        write 10 random bytes\n"
			"| ww foobar    write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'\n"
			"| wa push ebp  write opcode, separated by ';' (use '\"' around the command)\n"
			"| waf file     assemble file and write bytes\n"
			"| wA r 0       alter/modify opcode at current seek (see wA?)\n"
			"| wb 010203    fill current block with cyclic hexpairs\n"
			"| wc[ir*?]     write cache undo/commit/reset/list (io.cache)\n"
			"| wd [off] [n] duplicate N bytes from offset at current seek (memcpy) (see y?)\n"
			"| wx 9090      write two intel nops\n"
			"| wv eip+34    write 32-64 bit value\n"
			"| wo? hex      write in block with operation. 'wo?' fmi\n"
			"| wm f0ff      set binary mask hexpair to be used as cyclic write mask\n"
			"| ws pstring   write 1 byte for length and then the string\n"
			"| wf -|file    write contents of file at current offset\n"
			"| wF -|file    write contents of hexpairs file here\n"
			"| wp -|file    apply radare patch file. See wp? fmi\n"
			"| wt file [sz] write to file (from current seek, blocksize or sz bytes)\n"
			);
			//TODO: add support for offset+seek
			// " wf file o s ; write contents of file from optional offset 'o' and size 's'.\n"
		break;
	}
Esempio n. 23
0
R_API int r_diff_buffers_static(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
	int i, len;
	int hit = 0;
	la = R_ABS(la);
	lb = R_ABS(lb);
	if (la != lb) {
	 	len = R_MIN(la, lb);
		fprintf(stderr,
			"Buffer truncated to %d bytes (%d not compared)\n",
			len, R_ABS(lb-la));
	} else len = la;
	for(i = 0; i<len; i++) {
		if (a[i]!=b[i]) {
			hit++;
		} else {
			if (hit>0) {
				struct r_diff_op_t o = {
					.a_off = d->off_a+i-hit, .a_buf = a+i-hit, .a_len = hit,
					.b_off = d->off_b+i-hit, .b_buf = b+i-hit, .b_len = hit
				};
				d->callback (d, d->user, &o);
				hit = 0;
			}
		}
	}
	if (hit>0) {
		struct r_diff_op_t o = {
			.a_off = d->off_a+i-hit, .a_buf = a+i-hit, .a_len = hit,
			.b_off = d->off_b+i-hit, .b_buf = b+i-hit, .b_len = hit
		};
		d->callback (d, d->user, &o);
		hit = 0;
	}
	return 0;
}

// XXX: temporary files are
R_API int r_diff_buffers_radiff(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
	char *ptr, *str, buf[64], oop = 0;
	int ret, atl, btl, hit;
	ut8 at[128], bt[128];
	ut64 ooa, oob;
	FILE *fd;

	hit = atl = btl = 0;
	ooa = oob = 0LL;
	oop = -1;

	r_file_dump (".a", a, la, 0);
	r_file_dump (".b", b, lb, 0);
	r_sys_cmd ("radiff -d .a .b | rsc uncolor > .d");
	fd = fopen (".d", "r");

	while (!feof (fd)) {
		ut64 oa, ob; // offset
		int ba, bb = 0; // byte
		char op; // operation

		oa = ob = 0LL;
		if (!fgets (buf, 63, fd))
			break;
		if (feof (fd))
			break;
		str = buf;

		ptr = strchr (buf, ' ');
		if (!ptr) continue;
		*ptr='\0';
		sscanf (str, "0x%08"PFMT64x"", &oa);

		str = r_str_ichr (ptr+1, ' ');
		if (*str!='|'&&*str!='>'&&*str!='<') {
			ptr = strchr (str, ' ');
			if (!ptr) continue;
			*ptr='\0';
			sscanf (str, "%02x", &ba);
		} else ba = 0;

		str = r_str_ichr (ptr+1, ' ');
		ptr = strchr (str, ' ');
		if (!ptr) continue;
		*ptr='\0';
		sscanf (str, "%c", &op);

		str = r_str_ichr (ptr+1, ' ');
		if (str[0]!='0' || str[1]!='x') {
			ptr = strchr(str, ' ');
			if (!ptr) continue;
			*ptr = '\0';
			sscanf (str, "%02x", &bb);
		}

		str = ptr+1;
		ptr = strchr (str, '\n');
		if (!ptr) continue;
		*ptr='\0';
		sscanf (str, "0x%08"PFMT64x"", &ob);

		if (oop == op || oop==-1) {
			if (hit == 0) {
				ooa = oa;
				oob = ob;
			}
			at[atl] = ba;
			bt[btl] = bb;
			switch (op) {
			case '|':
				atl++;
				btl++;
				break;
			case '>':
				btl++;
				break;
			case '<':
				atl++;
				break;
			}
			hit++;
		} else {
			if (hit>0) {
				struct r_diff_op_t o = {
					.a_off = ooa, .a_buf = at, .a_len = atl,
					.b_off = oob, .b_buf = bt, .b_len = btl
				};
				ret = d->callback(d, d->user, &o);
				if (!ret)
					break;
				atl = btl = 0;
				hit = 0;
			}
		}
		oop = op;
	}
	if (hit>0) {
		struct r_diff_op_t o = {
			.a_off = ooa, .a_buf = at, .a_len = atl,
			.b_off = oob, .b_buf = bt, .b_len = btl
		};
		if (!d->callback (d, d->user, &o)) {
			fclose (fd);
			return 0;
		}
		atl = btl = 0;
		hit = 0;
	}
	fclose (fd);
	unlink (".a");
	unlink (".b");
	unlink (".d");
	return 0;
}

R_API int r_diff_buffers(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb) {
	if (d->delta)
		return r_diff_buffers_delta (d, a, la, b, lb);
	return r_diff_buffers_static (d, a, la, b, lb);
}

/* TODO: Move into r_util maybe? */
R_API int r_diff_buffers_distance(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb,
		ut32 *distance, double *similarity) {
	int i, j, cost, tmin, **m;

	if (!a || !b || la < 1 || lb < 1)
		return R_FALSE;

	if ((m = malloc ((la+1) * sizeof(int*))) == NULL)
		return R_FALSE;
	for(i = 0; i <= la; i++)
		if ((m[i] = malloc ((lb+1) * sizeof(int))) == NULL) {
			while (i--)
				free (m[i]);
			free (m);
			return R_FALSE;
		}

	for (i = 0; i <= la; i++)
		m[i][0] = i;
	for (j = 0; j <= lb; j++)
		m[0][j] = j;

	for (i = 1; i <= la; i++) {
		for (j = 1; j <= lb; j++) {
			if (a[i-1] == b[j-1])
				cost = 0;
			else cost = 1;
			tmin = R_MIN (m[i-1][j] + 1, m[i][j-1] + 1);
			m[i][j] = R_MIN (tmin, m[i-1][j-1] + cost);
		}
	}

	if (distance != NULL)
		*distance = m[la][lb];
	if (similarity != NULL)
		*similarity = (double)1 - (double)(m[la][lb])/(double)(R_MAX(la, lb));

	for(i = 0; i <= la; i++)
		free (m[i]);
	free (m);

	return R_TRUE;
}
Esempio n. 24
0
static int extract_binobj (const RBinFile *bf, const RBinObject *o, int idx ) {
	ut64 boffset = o ? o->boffset : 0;
	ut64 bin_size = o ? o->obj_size : 0;
	const ut8 *bytes = bf ? r_buf_buffer (bf->buf) : NULL;
	//ut64 sz = bf ? r_buf_size (bf->buf) : 0;
	RBinInfo *info = o ? o->info : NULL;
	const char *arch = info ? info->arch : "unknown";
	char bits = info ? info->bits : 0;
	const char *filename = bf ? bf->file : NULL;
	char *path = NULL, *outpath = NULL, *outfile = NULL, *ptr = NULL;
	ut32 outfile_sz = 0, outpath_sz = 0;
	int res = R_FALSE;

	if (!bf || !o || !filename ) return R_FALSE;

	path = strdup (filename);

	// XXX: Wrong for w32 (/)

	if (r_what_os_am_i () == ON_NIX_OS && (ptr = strrchr (path, '/'))){
		*ptr = '\0';
		ptr++;
	} else if ((ptr = strrchr (path, '\\'))) {
		*ptr = '\0';
		ptr++;
	} else ptr = path;

	outpath_sz = strlen (path) + 20;

	if (outpath_sz)
		outpath = malloc (outpath_sz);

	if (outpath)
		snprintf (outpath, outpath_sz, "%s.fat", ptr);

	if (!outpath || !r_sys_rmkdir (outpath)) {
		free (path);
		free (outpath);
		eprintf ("Error creating dir structure\n");
		return R_FALSE;
	}

	outfile_sz = outpath_sz + strlen (ptr) + strlen (arch) + 3 + 10 + 10;
	if (outfile_sz)
		outfile = malloc (outfile_sz);

	if (outfile)
		snprintf (outfile, outfile_sz, "%s/%s.%s_%i.%d",
			outpath, ptr, arch, bits, idx);

	if (!outfile || !r_file_dump (outfile, bytes+boffset, bin_size)) {
		eprintf ("Error extracting %s\n", outfile);
		res = R_FALSE;
	} else {
		printf ("%s created (%"PFMT64d")\n", outfile, bin_size);
		res = R_TRUE;
	}

	free (outfile);
	free (outpath);
	free (path);
	return res;
}
Esempio n. 25
0
int main(int argc, char **argv) {
	int c, bits = 0;
	int action = ACTION_UNK;
	const char *op = NULL;
	char *arch = NULL, *arch_name = NULL;
	ut64 offset;

	bin = r_bin_new ();
	l = r_lib_new ("radare_plugin");
	r_lib_add_handler (l, R_LIB_TYPE_BIN, "bin plugins",
					   &__lib_bin_cb, &__lib_bin_dt, NULL);
	r_lib_add_handler (l, R_LIB_TYPE_BIN_XTR, "bin xtr plugins",
					   &__lib_bin_xtr_cb, &__lib_bin_xtr_dt, NULL);

	{ /* load plugins everywhere */
		char *homeplugindir = r_str_home (".radare/plugins");
		r_lib_opendir (l, getenv ("LIBR_PLUGINS"));
		r_lib_opendir (l, homeplugindir);
		r_lib_opendir (l, LIBDIR"/radare2/");
	}

	while ((c = getopt (argc, argv, "Af:a:B:b:c:CdMm:n:@:VisSzIHelRwO:o:p:rvLhx")) != -1) {
		switch(c) {
		case 'A':
			action |= ACTION_LISTARCHS;
			break;
		case 'a':
			if (optarg) arch = strdup (optarg);
			break;
		case 'c':
			if (!optarg) {
				eprintf ("Missing argument for -c");
				return 1;
			}
			action = ACTION_CREATE;
			create = strdup (optarg);
			break;
		case 'C':
			action |= ACTION_CLASSES;
			break;
		case 'f':
			if (optarg) arch_name = strdup (optarg);
			break;
		case 'b':
			bits = r_num_math (NULL, optarg);
			break;
		case 'm':
			at = r_num_math (NULL, optarg);
			action |= ACTION_SRCLINE;
			break;
		case 'i':
			action |= ACTION_IMPORTS;
			break;
		case 's':
			action |= ACTION_SYMBOLS;
			break;
		case 'S':
			action |= ACTION_SECTIONS;
			break;
		case 'z':
			action |= ACTION_STRINGS;
			break;
		case 'I':
			action |= ACTION_INFO;
			break;
		case 'H':
			action |= ACTION_FIELDS;
			break;
		case 'd':
			action |= ACTION_DWARF;
			break;
		case 'e':
			action |= ACTION_ENTRIES;
			break;
		case 'M':
			action |= ACTION_MAIN;
			break;
		case 'l':
			action |= ACTION_LIBS;
			break;
		case 'R':
			action |= ACTION_RELOCS;
			break;
		case 'x':
			action |= ACTION_EXTRACT;
			break;
		case 'w':
			rw = R_TRUE;
			break;
		case 'O':
			op = optarg;
			action |= ACTION_OPERATION;
			if (optind==argc) {
				eprintf ("Missing filename\n");
				return 1;
			}
			//	return rabin_do_operation (op);
			break;
		case 'o':
			output = optarg;
			break;
		case 'r':
			rad = R_TRUE;
			break;
		case 'v':
			va = R_TRUE;
			break;
		case 'L':
			r_bin_list (bin);
			return 1;
		case 'B':
			gbaddr = r_num_math (NULL, optarg);
			break;
		case '@':
			at = r_num_math (NULL, optarg);
			break;
		case 'n':
			name = optarg;
			break;
		case 'V':
			printf ("rabin2 v"R2_VERSION"\n");
			return 0;
		case 'h':
		default:
			action |= ACTION_HELP;
		}
	}

	file = argv[optind];
	if (action == ACTION_HELP || action == ACTION_UNK || file == NULL)
		return rabin_show_help ();

	if (arch) {
		char *ptr;
		ptr = strchr (arch, '_');
		if (ptr) {
			*ptr = '\0';
			bits = r_num_math (NULL, ptr+1);
		}
	}
	if (action & ACTION_CREATE) {
		// TODO: move in a function outside
		RBuffer *b;
		int datalen, codelen;
		ut8 *data = NULL, *code = NULL;
		char *p2, *p = strchr (create, ':');
		if (!p) {
			eprintf ("Invalid format for -c flag. Use 'format:codehexpair:datahexpair'\n");
			return 1;
		}
		*p++ = 0;
		p2 = strchr (p, ':');
		if (p2) {
			// has data
			*p2++ = 0;
			data = malloc (strlen (p2));
			datalen = r_hex_str2bin (p2, data);
		} else {
			data = NULL;
			datalen = 0;
		}
		code = malloc (strlen (p));
		codelen = r_hex_str2bin (p, code);
		if (!arch) arch = "x86";
		if (!bits) bits = 32;

		if (!r_bin_use_arch (bin, arch, bits, create)) {
			eprintf ("Cannot set arch\n");
			return 1;
		}
		b = r_bin_create (bin, code, codelen, data, datalen);
		if (b) {
			if (r_file_dump (file, b->buf, b->length)) {
				eprintf ("dumped %d bytes in '%s'\n", b->length, file);
				r_file_chmod (file, "+x", 0);
			} else eprintf ("error dumping into a.out\n");
			r_buf_free (b);
		} else eprintf ("Cannot create binary for this format '%s'.\n", create);
		r_bin_free (bin);
		return 0;
	}

	if (!r_bin_load (bin, file, R_FALSE) && !r_bin_load (bin, file, R_TRUE)) {
		eprintf ("r_bin: Cannot open '%s'\n", file);
		return 1;
	}

	if (action & ACTION_LISTARCHS || ((arch || bits || arch_name) &&
		!r_bin_select (bin, arch, bits, arch_name))) {
		r_bin_list_archs (bin);
		free (arch);
		free (arch_name);
		r_bin_free (bin);
		return 1;
	}

	if (gbaddr != 0LL)
		bin->curarch.baddr = gbaddr;

	RCore core;
	core.bin = bin;
	RCoreBinFilter filter;
	filter.offset = at;
	filter.name = name;

	offset = r_bin_get_offset (bin);
	r_cons_new ()->is_interactive = R_FALSE;
	if (action&ACTION_SECTIONS)
		r_core_bin_info (&core, R_CORE_BIN_ACC_SECTIONS, rad, va, &filter, 0);
	if (action&ACTION_ENTRIES)
		r_core_bin_info (&core, R_CORE_BIN_ACC_ENTRIES, rad, va, NULL, offset);
	if (action&ACTION_MAIN)
		r_core_bin_info (&core, R_CORE_BIN_ACC_MAIN, rad, va, NULL, offset);
	if (action&ACTION_IMPORTS)
		r_core_bin_info (&core, R_CORE_BIN_ACC_IMPORTS, rad, va, &filter, offset);
	if (action&ACTION_CLASSES)
		r_core_bin_info (&core, R_CORE_BIN_ACC_CLASSES, rad, va, NULL, 0);
	if (action&ACTION_SYMBOLS)
		r_core_bin_info (&core, R_CORE_BIN_ACC_SYMBOLS, rad, va, &filter, offset);
	if (action&ACTION_STRINGS)
		r_core_bin_info (&core, R_CORE_BIN_ACC_STRINGS, rad, va, NULL, 0);
	if (action&ACTION_INFO)
		r_core_bin_info (&core, R_CORE_BIN_ACC_INFO, rad, va, NULL, 0);
	if (action&ACTION_FIELDS)
		r_core_bin_info (&core, R_CORE_BIN_ACC_FIELDS, rad, va, NULL, 0);
	if (action&ACTION_LIBS)
		r_core_bin_info (&core, R_CORE_BIN_ACC_LIBS, rad, va, NULL, 0);
	if (action&ACTION_RELOCS)
		r_core_bin_info (&core, R_CORE_BIN_ACC_RELOCS, rad, va, NULL, 0);
	if (action&ACTION_DWARF)
		rabin_show_dwarf (&core);
	if (action&ACTION_SRCLINE)
		rabin_show_srcline (at);
	if (action&ACTION_EXTRACT)
		rabin_extract ((arch==NULL && arch_name==NULL && bits==0));
	if (op != NULL && action&ACTION_OPERATION)
		rabin_do_operation (op);

	free (arch);
	r_bin_free (bin);
	r_cons_flush ();

	return 0;
}
Esempio n. 26
0
int main(int argc, char **argv) {
	const char *query = NULL;
	int c, bits = 0, actions_done = 0, actions = 0, action = ACTION_UNK;
	char *homeplugindir = r_str_home (R2_HOMEDIR"/plugins");
	char *ptr, *arch = NULL, *arch_name = NULL;
	const char *op = NULL;
	RCoreBinFilter filter;
	RCore core;
	RCoreFile *cf = NULL;
	int xtr_idx = 0; // load all files if extraction is necessary.
	int fd = -1;
	int rawstr = 0;

	r_core_init (&core);
	bin = core.bin;
	l = r_lib_new ("radare_plugin");
	r_lib_add_handler (l, R_LIB_TYPE_BIN, "bin plugins",
			   &__lib_bin_cb, &__lib_bin_dt, NULL);
	r_lib_add_handler (l, R_LIB_TYPE_BIN_XTR, "bin xtr plugins",
			   &__lib_bin_xtr_cb, &__lib_bin_xtr_dt, NULL);

	/* load plugins everywhere */
	r_lib_opendir (l, getenv ("LIBR_PLUGINS"));
	r_lib_opendir (l, homeplugindir);
	r_lib_opendir (l, LIBDIR"/radare2/"R2_VERSION);

#define is_active(x) (action&x)
#define set_action(x) actions++; action |=x
	while ((c = getopt (argc, argv, "jgqAf:a:B:b:c:Ck:dMm:n:N:@:isSIHelRwO:o:rvLhxzZ")) != -1) {
		switch (c) {
		case 'g':
			set_action (ACTION_CLASSES);
			set_action (ACTION_IMPORTS);
			set_action (ACTION_SYMBOLS);
			set_action (ACTION_SECTIONS);
			set_action (ACTION_STRINGS);
			set_action (ACTION_SIZE);
			set_action (ACTION_INFO);
			set_action (ACTION_FIELDS);
			set_action (ACTION_DWARF);
			set_action (ACTION_ENTRIES);
			set_action (ACTION_MAIN);
			set_action (ACTION_LIBS);
			set_action (ACTION_RELOCS);
			set_action (ACTION_EXTRACT);
			break;
		case 'q': rad = R_CORE_BIN_SIMPLE; break;
		case 'j': rad = R_CORE_BIN_JSON; break;
		case 'A': set_action (ACTION_LISTARCHS); break;
		case 'a': if (optarg) arch = optarg; break;
		case 'c':
			if (!optarg) {
				eprintf ("Missing argument for -c");
				return 1;
			}
			set_action (ACTION_CREATE);
			create = strdup (optarg);
			break;
		case 'k': query = optarg; break;
		case 'C': set_action (ACTION_CLASSES); break;
		case 'f': if (optarg) arch_name = strdup (optarg); break;
		case 'b': bits = r_num_math (NULL, optarg); break;
		case 'm':
			at = r_num_math (NULL, optarg);
			set_action (ACTION_SRCLINE);
			break;
		case 'i': set_action (ACTION_IMPORTS); break;
		case 's': set_action (ACTION_SYMBOLS); break;
		case 'S': set_action (ACTION_SECTIONS); break;
		case 'z':
			if (is_active (ACTION_STRINGS)) {
				rawstr = R_TRUE;
			} else set_action (ACTION_STRINGS);
			break;
		case 'Z': set_action (ACTION_SIZE); break;
		case 'I': set_action (ACTION_INFO); break;
		case 'H': set_action (ACTION_FIELDS); break;
		case 'd': set_action (ACTION_DWARF); break;
		case 'e': set_action (ACTION_ENTRIES); break;
		case 'M': set_action (ACTION_MAIN); break;
		case 'l': set_action (ACTION_LIBS); break;
		case 'R': set_action (ACTION_RELOCS); break;
		case 'x': set_action (ACTION_EXTRACT); break;
		case 'w': rw = R_TRUE; break;
		case 'O':
			op = optarg;
			set_action (ACTION_OPERATION);
			if (op && !strcmp (op, "help")) {
				printf ("Operation string:\n"
						"  Dump symbols: d/s/1024\n"
						"  Dump section: d/S/.text\n"
						"  Resize section: r/.data/1024\n");
				return 0;
			}
			if (optind==argc) {
				eprintf ("Missing filename\n");
				return 1;
			}
			break;
		case 'o': output = optarg; break;
		case 'r': rad = R_TRUE; break;
		case 'v': va = R_TRUE; break;
		case 'L': r_bin_list (bin); return 1;
		case 'B': baddr = r_num_math (NULL, optarg); break;
		case '@': at = r_num_math (NULL, optarg); break;
		case 'n': name = optarg; break;
		case 'N': bin->minstrlen = r_num_math (NULL, optarg); break;
		//case 'V': return blob_version ("rabin2");
		case 'h': return rabin_show_help (1);
		default: action |= ACTION_HELP;
		}
	}

	file = argv[optind];
	if (!query)
	if (action & ACTION_HELP || action == ACTION_UNK || file == NULL) {
		if (va) return blob_version ("rabin2");
		return rabin_show_help (0);
	}

	if (arch) {
		ptr = strchr (arch, '_');
		if (ptr) {
			*ptr = '\0';
			bits = r_num_math (NULL, ptr+1);
		}
	}
	if (action & ACTION_CREATE) {
		// TODO: move in a function outside
		RBuffer *b;
		int datalen, codelen;
		ut8 *data = NULL, *code = NULL;
		char *p2, *p = strchr (create, ':');
		if (!p) {
			eprintf ("Invalid format for -c flag. Use 'format:codehexpair:datahexpair'\n");
			return 1;
		}
		*p++ = 0;
		p2 = strchr (p, ':');
		if (p2) {
			// has data
			*p2++ = 0;
			data = malloc (strlen (p2)+1);
			datalen = r_hex_str2bin (p2, data);
		} else {
			data = NULL;
			datalen = 0;
		}
		code = malloc (strlen (p)+1);
		if (!code) {
		    return 1;
	    }
		codelen = r_hex_str2bin (p, code);
		if (!arch) arch = "x86";
		if (!bits) bits = 32;

		if (!r_bin_use_arch (bin, arch, bits, create)) {
			eprintf ("Cannot set arch\n");
			return 1;
		}
		b = r_bin_create (bin, code, codelen, data, datalen);
		if (b) {
			if (r_file_dump (file, b->buf, b->length)) {
				eprintf ("dumped %d bytes in '%s'\n", b->length, file);
				r_file_chmod (file, "+x", 0);
			} else eprintf ("error dumping into a.out\n");
			r_buf_free (b);
		} else eprintf ("Cannot create binary for this format '%s'.\n", create);
		r_bin_free (bin);
		return 0;
	}
	r_config_set_i (core.config, "bin.rawstr", rawstr);
	cf = r_core_file_open (&core, file, R_IO_READ, 0);
	fd = cf ? r_core_file_cur_fd (&core) : -1;
	if (!cf || fd == -1) {
		eprintf ("r_core: Cannot open file\n");
		return 1;
	}

	if (!r_bin_load (bin, file, baddr, 0, xtr_idx, fd, rawstr)) {
		if (!r_bin_load (bin, file, baddr, 0, xtr_idx, fd, rawstr)) {
			eprintf ("r_bin: Cannot open file\n");
			return 1;
		}
	}

	if (query) {
		if (!strcmp (query, "-")) {
			__sdb_prompt (bin->cur->sdb);
		} else sdb_query (bin->cur->sdb, query);
		return 0;
	}

	// XXX: TODO move this to libr/core/bin.c
	if (action & ACTION_LISTARCHS || ((arch || bits || arch_name) &&
		!r_bin_select (bin, arch, bits, arch_name))) {
		if (rad == R_CORE_BIN_JSON) {
			int i;
			printf ("[");
			for (i = 0; i < bin->narch; i++) {
				if (r_bin_select_idx (bin, bin->file, i)) {
					RBinObject *o = r_bin_cur_object (bin);
					RBinInfo *info = o ? o->info : NULL;
					printf ("%s{\"arch\":\"%s\",\"bits\":%d,"
						"\"offset\":%"PFMT64d",\"machine\":\"%s\"}",
						i?",":"",info->arch, info->bits,
						bin->cur->offset, info->machine);
				}
			}
			printf ("]");
		} else r_bin_list_archs (bin, 1);
		free (arch_name);
	}

	if (baddr != 0LL) {
		r_bin_set_baddr (bin, baddr);
		bin->cur->o->baddr = baddr;
	}

	core.bin = bin;
	filter.offset = at;
	filter.name = name;

	r_cons_new ()->is_interactive = R_FALSE;

#define isradjson (rad==R_CORE_BIN_JSON&&actions>0)
#define run_action(n,x,y) {\
	if (action&x) {\
		if (isradjson) r_cons_printf ("\"%s\":",n);\
		if (!r_core_bin_info (&core, y, rad, va, &filter, 0)) {\
			if (isradjson) r_cons_printf("false");\
		};\
		actions_done++;\
		if (isradjson) r_cons_printf (actions==actions_done? "":",");\
	}\
}
	if (isradjson) r_cons_printf ("{");
	run_action ("sections", ACTION_SECTIONS, R_CORE_BIN_ACC_SECTIONS);
	run_action ("entries", ACTION_ENTRIES, R_CORE_BIN_ACC_ENTRIES);
	run_action ("main", ACTION_MAIN, R_CORE_BIN_ACC_MAIN);
	run_action ("imports", ACTION_IMPORTS, R_CORE_BIN_ACC_IMPORTS);
	run_action ("classes", ACTION_CLASSES, R_CORE_BIN_ACC_CLASSES);
	run_action ("symbols", ACTION_SYMBOLS, R_CORE_BIN_ACC_SYMBOLS);
	run_action ("strings", ACTION_STRINGS, R_CORE_BIN_ACC_STRINGS);
	run_action ("info", ACTION_INFO, R_CORE_BIN_ACC_INFO);
	run_action ("fields", ACTION_FIELDS, R_CORE_BIN_ACC_FIELDS);
	run_action ("libs", ACTION_LIBS, R_CORE_BIN_ACC_LIBS);
	run_action ("relocs", ACTION_RELOCS, R_CORE_BIN_ACC_RELOCS);
	run_action ("dwarf", ACTION_DWARF, R_CORE_BIN_ACC_DWARF);
	run_action ("size", ACTION_SIZE, R_CORE_BIN_ACC_SIZE);
	if (action&ACTION_SRCLINE)
		rabin_show_srcline (at);
	if (action&ACTION_EXTRACT)
		rabin_extract ((arch==NULL && arch_name==NULL && bits==0));
	if (op != NULL && action&ACTION_OPERATION)
		rabin_do_operation (op);
	if (isradjson)
		printf ("}");
	r_cons_flush ();
	r_core_fini (&core);

	return 0;
}
Esempio n. 27
0
File: run.c Progetto: f0829/radare2
R_API int r_run_start(RRunProfile *p) {
#if LIBC_HAVE_FORK
	if (p->_execve) {
		exit (execv (p->_program, (char* const*)p->_args));
	}
#endif
#if __APPLE__ && !__POWERPC__ && LIBC_HAVE_FORK
	posix_spawnattr_t attr = {0};
	pid_t pid = -1;
	int ret;
	posix_spawnattr_init (&attr);
	if (p->_args[0]) {
		char **envp = r_sys_get_environ();
		ut32 spflags = 0; //POSIX_SPAWN_START_SUSPENDED;
		spflags |= POSIX_SPAWN_SETEXEC;
		if (p->_aslr == 0) {
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
			spflags |= _POSIX_SPAWN_DISABLE_ASLR;
		}
		(void)posix_spawnattr_setflags (&attr, spflags);
		if (p->_bits) {
			size_t copied = 1;
			cpu_type_t cpu;
#if __i386__ || __x86_64__
			cpu = CPU_TYPE_I386;
			if (p->_bits == 64) {
				cpu |= CPU_ARCH_ABI64;
			}
#else
			cpu = CPU_TYPE_ANY;
#endif
			posix_spawnattr_setbinpref_np (
					&attr, 1, &cpu, &copied);
		}
		ret = posix_spawnp (&pid, p->_args[0],
			NULL, &attr, p->_args, envp);
		switch (ret) {
		case 0:
			break;
		case 22:
			eprintf ("posix_spawnp: Invalid argument\n");
			break;
		case 86:
			eprintf ("posix_spawnp: Unsupported architecture\n");
			break;
		default:
			eprintf ("posix_spawnp: unknown error %d\n", ret);
			perror ("posix_spawnp");
			break;
		}
		exit (ret);
	}
#endif
	if (p->_system) {
		if (p->_pid) {
			eprintf ("PID: Cannot determine pid with 'system' directive. Use 'program'.\n");
		}
		exit (r_sys_cmd (p->_system));
	}
	if (p->_program) {
		if (!r_file_exists (p->_program)) {
			char *progpath = r_file_path (p->_program);
			if (progpath && *progpath) {
				free (p->_program);
				p->_program = progpath;
			} else {
				free (progpath);
				eprintf ("rarun2: %s: file not found\n", p->_program);
				return 1;
			}
		}
#if __UNIX__
		// XXX HACK close all non-tty fds
		{ int i;
			for (i = 3; i < 10; i++) {
				close (i);
			}
		}
		// TODO: use posix_spawn
		if (p->_setgid) {
			int ret = setgid (atoi (p->_setgid));
			if (ret < 0) {
				return 1;
			}
		}
		if (p->_pid) {
			eprintf ("PID: %d\n", getpid ());
		}
		if (p->_pidfile) {
			char pidstr[32];
			snprintf (pidstr, sizeof (pidstr), "%d\n", getpid ());
			r_file_dump (p->_pidfile,
				(const ut8*)pidstr,
				strlen (pidstr), 0);
		}
#endif

		if (p->_nice) {
#if __UNIX__ && !defined(__HAIKU__)
			if (nice (p->_nice) == -1) {
				return 1;
			}
#else
			eprintf ("nice not supported for this platform\n");
#endif
		}
// TODO: must be HAVE_EXECVE
#if LIBC_HAVE_FORK
		exit (execv (p->_program, (char* const*)p->_args));
#endif
	}
	if (p->_runlib) {
		if (!p->_runlib_fcn) {
			eprintf ("No function specified. Please set runlib.fcn\n");
			return 1;
		}
		void *addr = r_lib_dl_open (p->_runlib);
		if (!addr) {
			eprintf ("Could not load the library '%s'\n", p->_runlib);
			return 1;
		}
		void (*fcn)(void) = r_lib_dl_sym (addr, p->_runlib_fcn);
		if (!fcn) {
			eprintf ("Could not find the function '%s'\n", p->_runlib_fcn);
			return 1;
		}
		switch (p->_argc) {
		case 0:
			fcn ();
			break;
		case 1:
			r_run_call1 (fcn, p->_args[1]);
			break;
		case 2:
			r_run_call2 (fcn, p->_args[1], p->_args[2]);
			break;
		case 3:
			r_run_call3 (fcn, p->_args[1], p->_args[2], p->_args[3]);
			break;
		case 4:
			r_run_call4 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4]);
			break;
		case 5:
			r_run_call5 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
				p->_args[5]);
			break;
		case 6:
			r_run_call6 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
				p->_args[5], p->_args[6]);
			break;
		case 7:
			r_run_call7 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
				p->_args[5], p->_args[6], p->_args[7]);
			break;
		case 8:
			r_run_call8 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
				p->_args[5], p->_args[6], p->_args[7], p->_args[8]);
			break;
		case 9:
			r_run_call9 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
				p->_args[5], p->_args[6], p->_args[7], p->_args[8], p->_args[9]);
			break;
		case 10:
			r_run_call10 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4],
				p->_args[5], p->_args[6], p->_args[7], p->_args[8], p->_args[9], p->_args[10]);
			break;
		default:
			eprintf ("Too many arguments.\n");
			return 1;
		}
		r_lib_dl_close (addr);
	}
	return 0;
}