Exemple #1
0
static int __core_patch_bracket(RCore *core, const char *str, ut64 *noff) {
	char tmp[128];
	char *s, *p, *q, *off;
	RBuffer *b = r_buf_new ();
	if (!b) {
		return 0;
	}
	p = off = strdup (str);
	if (!p) {
		r_buf_free (b);
		return 0;
	}
	for (;*p;) {
		if (*p=='\n') {
			*p++ = 0;
		} else {
			p++;
			continue;
		}
		if (*str == '}')
			break;
		if ((q = strstr (str, "${"))) {
			char *end = strchr (q+2,'}');
			if (end) {
				*q = *end = 0;
				*noff = r_num_math (core->num, q+2);
				r_buf_append_bytes (b, (const ut8*)str, strlen (str));
				snprintf (tmp, sizeof (tmp), "0x%08"PFMT64x, *noff);
				r_buf_append_bytes (b, (const ut8*)tmp, strlen (tmp));
				r_buf_append_bytes (b, (const ut8*)end+1, strlen (end+1));
			}
		} else {
			r_buf_append_bytes (b, (const ut8*)str, strlen (str));
		}
		str = p;
	}

	s = r_buf_to_string (b);
	r_egg_load (core->egg, s, 0);
	free (s);

	r_egg_compile (core->egg);
	r_egg_assemble (core->egg);

	r_buf_free (b);
	b = r_egg_get_bin (core->egg);

	if (strcmp (off, "+")) {
		*noff = r_num_math (core->num, off);
	}
	r_core_write_at (core, *noff, b->buf, b->length);
	*noff += b->length;
	free (off);
	return 1;
}
Exemple #2
0
R_API bool r_buf_append_ut32(RBuffer *b, ut32 n) {
	if (b->empty) b->length = b->empty = 0;
	if (b->fd != -1) {
		return r_buf_append_bytes (b, (const ut8*)&n, sizeof (n));
	}
	if (!(b->buf = realloc (b->buf, b->length+sizeof (n))))
		return false;
	memmove (b->buf+b->length, &n, sizeof (n));
	b->length += sizeof (n);
	return true;
}
Exemple #3
0
R_API char *r_buf_free_to_string (RBuffer *b) {
	char *p;
	if (!b) return NULL;
	if (b->mmap) {
		p = r_buf_to_string (b);
	} else {
		r_buf_append_bytes (b, (const ut8*)"", 1);
		p = (char *)b->buf;
	}
	free (b);
	return p;
}
Exemple #4
0
R_API bool r_buf_append_buf(RBuffer *b, RBuffer *a) {
	if (!b) return false;
	if (b->fd != -1) {
		r_buf_append_bytes (b, a->buf, a->length);
		return true;
	}
	if (b->empty) {
		b->length = 0;
		b->empty = 0;
	}
	if ((b->buf = realloc (b->buf, b->length + a->length))) {
		memmove (b->buf+b->length, a->buf, a->length);
		b->length += a->length;
		return true;
	}
	return false;
}
Exemple #5
0
R_API char *r_buf_free_to_string(RBuffer *b) {
	char *p;
	if (!b) {
		return NULL;
	}
	if (b->mmap) {
		p = r_buf_to_string (b);
	} else {
		r_buf_append_bytes (b, (const ut8*)"", 1);
		p = malloc (b->length + 1);
		if (!p) {
			return NULL;	
		}
		memmove (p, b->buf, b->length);
		p[b->length] = 0;
	}
	r_buf_free (b);
	return p;
}
Exemple #6
0
R_API int r_buf_append_string (RBuffer *b, const char *str) {
	return r_buf_append_bytes (b, (const ut8*)str, strlen (str));
}
Exemple #7
0
static RBuffer *build (REgg *egg) {
	RBuffer *buf, *sc;
	ut8 aux[32], nkey;
	const char *default_key = DEFAULT_XOR_KEY;
	char *key = r_egg_option_get (egg, "key");
	int i;

	if (!key || !*key) {
		free (key);
		key = strdup (default_key);
		eprintf ("XOR key not provided. Using (%s) as the key\n", key);
	}
	nkey = r_num_math (NULL, key);
	if (nkey == 0) {
		eprintf ("Invalid key (%s)\n", key);
		free (key);
		return false;
	}
	if (nkey != (nkey & 0xff)) {
		nkey &= 0xff;
		eprintf ("xor key wrapped to (%d)\n", nkey);
	}
	if (r_buf_size (egg->bin) > 240) { // XXX
		eprintf ("shellcode is too long :(\n");
		free (key);
		return NULL;
	}
	sc = egg->bin; // hack
	if (!r_buf_size (sc)) {
		eprintf ("No shellcode found!\n");
		free (key);
		return NULL;
	}

	for (i = 0; i<r_buf_size (sc); i++) {
		// eprintf ("%02x -> %02x\n", sc->buf[i], sc->buf[i] ^nkey);
		if ((r_buf_read8_at (sc, i) ^ nkey)==0) {
			eprintf ("This xor key generates null bytes. Try again.\n");
			free (key);
			return NULL;
		}
	}
	buf = r_buf_new ();
	sc = r_buf_new ();

	// TODO: alphanumeric? :D
	// This is the x86-32/64 xor encoder
	r_buf_append_buf (sc, egg->bin);
	if (egg->arch == R_SYS_ARCH_X86) {
		#define STUBLEN 18
		ut8 stub[STUBLEN] =
			"\xe8\xff\xff\xff\xff" // call $$+4
			"\xc1" // ffc1 = inc ecx
			"\x5e" // pop esi
			"\x48\x83\xc6\x0d" // add rsi, xx ... 64bit
			// loop0:
			"\x30\x1e" // xor [esi], bl
			"\x48\xff\xc6" // inc rsi
			"\xe2\xf9"; // loop loop0
		// ecx = length
		aux[0] = 0x6a; // push length
		aux[1] = r_buf_size (sc);
		aux[2] = 0x59; // pop ecx
		// ebx = key
		aux[3] = 0x6a; // push key
		aux[4] = nkey;
		aux[5] = 0x5b; // pop ebx
		r_buf_set_bytes (buf, aux, 6);

		r_buf_append_bytes (buf, stub, STUBLEN);

		for (i = 0; i<r_buf_size (sc); i++) {
			ut8 v = r_buf_read8_at (sc, i) ^ nkey;
			r_buf_write_at (sc, i, &v, sizeof (v));
		}
		r_buf_append_buf (buf, sc);
	}
	r_buf_free (sc);
	free (key);
	return buf;
}
Exemple #8
0
static RBuffer *build (REgg *egg) {
	RBuffer *buf, *sc;
	ut8 aux[32], nkey;
	int i;
	char *key = r_egg_option_get (egg, "key");

	if (!key || !*key) {
		eprintf ("Invalid key (null)\n");
		return R_FALSE;
	}
	nkey = r_num_math (NULL, key);
	if (nkey == 0) {
		eprintf ("Invalid key (%s)\n", key);
		return R_FALSE;
	}
	if (nkey != (nkey & 0xff)) {
		nkey &= 0xff;
		eprintf ("xor key wrapped to (%d)\n", nkey);
	}
	if (egg->bin->length > 240) { // XXX
		eprintf ("shellcode is too long :(\n");
		return NULL;
	}
	sc = egg->bin; // hack
	for (i = 0; i<sc->length; i++) {
		// eprintf ("%02x -> %02x\n", sc->buf[i], sc->buf[i] ^nkey);
		if ((sc->buf[i]^nkey)==0) {
			eprintf ("This xor key generates null bytes. Try again.\n");
			return NULL;
		}
	}
	buf = r_buf_new ();
	sc = r_buf_new ();

	// TODO: alphanumeric? :D
	// This is the x86-32/64 xor encoder
	r_buf_append_buf (sc, egg->bin);
	if (egg->arch == R_SYS_ARCH_X86) {
		#define STUBLEN 18
		ut8 stub[STUBLEN] =
			"\xe8\xff\xff\xff\xff" // call $$+4
			"\xc1" // ffc1 = inc ecx
			"\x5e" // pop esi
			"\x48\x83\xc6\x0d" // add rsi, xx ... 64bit
			// loop0:
			"\x30\x1e" // xor [esi], bl
			"\x48\xff\xc6" // inc rsi
			"\xe2\xf9"; // loop loop0
		// ecx = length
		aux[0] = 0x6a; // push length
		aux[1] = sc->length;
		aux[2] = 0x59; // pop ecx
		// ebx = key
		aux[3] = 0x6a; // push key
		aux[4] = nkey;
		aux[5] = 0x5b; // pop ebx
		r_buf_set_bytes (buf, aux, 6);

		r_buf_append_bytes (buf, stub, STUBLEN);

		for (i = 0; i<sc->length; i++) {
//			 eprintf ("%02x -> %02x\n", sc->buf[i], sc->buf[i] ^nkey);
			sc->buf[i]^=nkey;
		}
		r_buf_append_buf (buf, sc);
	}
	r_buf_free (sc);
	return buf;
}
Exemple #9
0
/* TODO: Needs more testing and ERROR HANDLING */
struct r_bin_dyldcache_lib_t *r_bin_dyldcache_extract(struct r_bin_dyldcache_obj_t* bin, int idx, int *nlib) {
	struct r_bin_dyldcache_lib_t *ret = NULL;
	struct mach_header *mh;
	RBuffer* dbuf;
	ut64 curoffset, liboff, libla, libpath, linkedit_offset;
	ut8 *data, *cmdptr;
	char *libname;
	int cmd, libsz = 0;

	if (bin->nlibs < 0 || idx < 0 || idx > bin->nlibs)
		return NULL;
	*nlib = bin->nlibs;
	ret = R_NEW0 (struct r_bin_dyldcache_lib_t);
	if (!ret) {
		perror ("malloc (ret)");
		return NULL;
	}
	curoffset = bin->hdr.startaddr+idx*32;
	libla = *(ut64*)(bin->b->buf+curoffset);
	liboff = libla - *(ut64*)&bin->b->buf[bin->hdr.baseaddroff];
	if (liboff > bin->size) {
		eprintf ("Corrupted file\n");
		free (ret);
		return NULL;
	}
	ret->offset = liboff;
	libpath = *(ut64*)(bin->b->buf+curoffset + 24);
	/* Locate lib hdr in cache */
	data = bin->b->buf+liboff;
	mh = (struct mach_header *)data;
	/* Check it is mach-o */
	if (mh->magic != 0xfeedface) {
		eprintf ("Not mach-o\n");
		free (ret);
		return NULL;
	}
	/* Write mach-o hdr */
	if (!(dbuf = r_buf_new ())) {
		eprintf ("new (dbuf)\n");
		free (ret);
		return NULL;
	}
	r_buf_set_bytes (dbuf, data, sizeof (struct mach_header));
	cmdptr = data + sizeof(struct mach_header);
	/* Write load commands */
	for (cmd = 0; cmd < mh->ncmds; cmd++) {
		struct load_command *lc = (struct load_command *)cmdptr;
		cmdptr += lc->cmdsize;
		r_buf_append_bytes (dbuf, (ut8*)lc, lc->cmdsize);
	}
	/* Write segments */
	for (cmd = linkedit_offset = 0, cmdptr = data + sizeof (struct mach_header); cmd < mh->ncmds; cmd++) {
		struct load_command *lc = (struct load_command *)cmdptr;
		cmdptr += lc->cmdsize;
		switch (lc->cmd) {
		case LC_SEGMENT:
			{
			/* Write segment and patch offset */
			struct segment_command *seg = (struct segment_command *)lc;
			int t = seg->filesize;
			if (seg->fileoff+seg->filesize > bin->b->length)
				t = bin->b->length - seg->fileoff;
			r_buf_append_bytes (dbuf, bin->b->buf+seg->fileoff, t);
			r_bin_dyldcache_apply_patch (dbuf, dbuf->length,
				(ut64)((size_t)&seg->fileoff - (size_t)data));
			/* Patch section offsets */
			int sect_offset = seg->fileoff - libsz;
			libsz = dbuf->length;
			if (!strcmp(seg->segname, "__LINKEDIT"))
				linkedit_offset = sect_offset;
			if (seg->nsects > 0) {
				struct section *sects = (struct section *)((ut8 *)seg + sizeof(struct segment_command));
				int nsect;
				for (nsect = 0; nsect < seg->nsects; nsect++) {
					if (sects[nsect].offset > libsz) {
						r_bin_dyldcache_apply_patch (dbuf, sects[nsect].offset - sect_offset,
							(ut64)((size_t)&sects[nsect].offset - (size_t)data));
					}
				}
			}
			}
			break;
		case LC_SYMTAB:
			{
			struct symtab_command *st = (struct symtab_command *)lc;
			NZ_OFFSET (st->symoff);
			NZ_OFFSET (st->stroff);
			}
			break;
		case LC_DYSYMTAB:
			{
			struct dysymtab_command *st = (struct dysymtab_command *)lc;
			NZ_OFFSET (st->tocoff);
			NZ_OFFSET (st->modtaboff);
			NZ_OFFSET (st->extrefsymoff);
			NZ_OFFSET (st->indirectsymoff);
			NZ_OFFSET (st->extreloff);
			NZ_OFFSET (st->locreloff);
			}
			break;
		case LC_DYLD_INFO:
		case LC_DYLD_INFO_ONLY:
			{
			struct dyld_info_command *st = (struct dyld_info_command *)lc;
			NZ_OFFSET (st->rebase_off);
			NZ_OFFSET (st->bind_off);
			NZ_OFFSET (st->weak_bind_off);
			NZ_OFFSET (st->lazy_bind_off);
			NZ_OFFSET (st->export_off);
			}
			break;
		}
	}
	/* Fill r_bin_dyldcache_lib_t ret */
	ret->b = dbuf;
	libname = (char*)(bin->b->buf+libpath);
	strncpy (ret->path, libname, sizeof (ret->path)-1);
	ret->size = libsz;
	return ret;
}
Exemple #10
0
// http://code.google.com/p/smali/wiki/TypesMethodsAndFields
R_API char *r_bin_demangle_java(const char *str) {
	const char *w = NULL;
	int is_array = 0;
	const char *ptr;
	int is_ret = 0;
	int wlen = 0;
	RBuffer *buf;
	int n = 0;
	char *ret;

	ptr = strchr (str, '(');
	if (!ptr)
		return NULL;
	buf = r_buf_new ();
	if (!buf) return NULL;
	r_buf_append_bytes (buf, (const ut8*)str, (int)(size_t)(ptr-str));
	r_buf_append_bytes (buf, (const ut8*)" (", 2);
	while (*str) {
		switch (*str) {
		case ')':
			is_ret = 1;
			break;
		case '[':
			is_array = 1;
			break;
		case 'L':
			str++;
			ptr = strchr (str, ';');
			if (ptr) {
				w = str;
				wlen = (int)(size_t)(ptr-str);
			}
			str = ptr;
			break;
		case 'I': w = "int"; wlen = 3; break;
		case 'C': w = "char"; wlen = 4; break;
		case 'B': w = "byte"; wlen = 4; break;
		case 'V': w = "void"; wlen = 4; break;
		case 'J': w = "long"; wlen = 4; break;
		case 'F': w = "float"; wlen = 5; break;
		case 'S': w = "short"; wlen = 5; break;
		case 'D': w = "double"; wlen = 6; break;
		case 'Z': w = "boolean"; wlen = 7; break;
		}
		if (w) {
			if (is_ret) {
				r_buf_prepend_bytes (buf, (const ut8*)" ", 1);
				r_buf_prepend_bytes (buf, (const ut8*)w, wlen);
				r_buf_append_bytes (buf, (const ut8*)")", 1);
				break;
			} else {
				if (n++>0)
					r_buf_append_bytes (buf, (const ut8*)", ", 2);
				r_buf_append_bytes (buf, (const ut8*)w, wlen);
			}
			if (is_array) {
				r_buf_append_bytes (buf, (const ut8*)"[]", 2);
				is_array = 0;
			}
		}
		w = NULL;
		if (!str) break;
		str++;
	}
	ret = r_buf_to_string (buf);
	r_buf_free (buf);
	return ret;
}
Exemple #11
0
R_API int r_core_patch (RCore *core, const char *patch) {
	char *p, *p2, *q, str[200], tmp[64];
	ut64 noff = 0LL;
	FILE *fd = r_sandbox_fopen (patch, "r");
	if (fd==NULL) {
		eprintf ("Cannot open patch file\n");
		return 1;
	}

	while (!feof (fd)) {
		fgets (str, sizeof (str), fd);
		if (*str=='#' || *str=='\n' || *str=='\r')
			continue;
		if (*str==':') {
			r_core_cmd0 (core, str+1);
			continue;
		}
		if (*str=='.' || *str=='!') {
			r_core_cmd0 (core, str);
			continue;
		}
		p = strchr (str+1, ' ');
		if (p) {
			*p = 0;
			for (++p; *p==' '; p++); // XXX: skipsspaces here
			switch (*p) {
			case '{': {
				char *s, *off = strdup (str);
				RBuffer *b = r_buf_new ();
				
				while (!feof (fd)) {
					fgets (str, sizeof (str), fd);
					if (*str=='}')
						break;
					if ((q=strstr (str, "${"))) {
						char *end = strchr (q+2,'}');
						if (end) {
							*q = *end = 0;
							noff = r_num_math (core->num, q+2);
							r_buf_append_bytes (b, (const ut8*)str, strlen (str));
							snprintf (tmp, sizeof (tmp), "0x%08"PFMT64x, noff);
							r_buf_append_bytes (b, (const ut8*)tmp, strlen (tmp));
							r_buf_append_bytes (b, (const ut8*)end+1, strlen (end+1));
						}
					} else r_buf_append_bytes (b, (const ut8*)str, strlen (str));
				}

				s = r_buf_to_string (b);
				r_egg_load (core->egg, s, 0);
				free (s);
			
				r_egg_compile (core->egg);
				r_egg_assemble (core->egg);

				r_buf_free (b);
				b = r_egg_get_bin (core->egg);

				if (strcmp (off, "+"))
					noff = r_num_math (core->num, off);
				r_core_write_at (core, noff, b->buf, b->length);
				noff += b->length;
				r_buf_free (b);
				free (off);
				}
				break;
			case '"':
				p2 = strchr (p+1,'"');
				if (p2) *p2=0;
				r_core_cmdf (core, "s %s", str);
				r_core_cmdf (core, "\"w %s\"", p+1);
				break;
			case ':':
				r_core_cmdf (core, "s %s", str);
				r_core_cmdf (core, "wa %s", p);
				break;
			default:
				r_core_cmdf (core, "s %s", str);
				r_core_cmdf (core, "wx %s", p);
				break;
			}
		}
	}
	fclose (fd);
	return 0;
}