Пример #1
0
// TODO: move somewhere else
R_API RAsmOp *r_core_disassemble (RCore *core, ut64 addr) {
	int delta;
	ut8 buf[128];
	static RBuffer *b = NULL; // XXX: never freed and non-thread safe. move to RCore
	RAsmOp *op;
	if (b == NULL) {
		b = r_buf_new ();
		if (!r_core_read_at (core, addr, buf, sizeof (buf)))
			return NULL;
		b->base = addr;
		r_buf_set_bytes (b, buf, sizeof (buf));
	} else {
		if ((addr < b->base) || addr > (b->base+b->length-32)) {
			if (!r_core_read_at (core, addr, buf, sizeof (buf)))
				return NULL;
			b->base = addr;
			r_buf_set_bytes (b, buf, sizeof (buf));
		}
	}
	delta = addr - b->base;
	op = R_NEW (RAsmOp);
	r_asm_set_pc (core->assembler, addr);
	if (r_asm_disassemble (core->assembler, op, b->buf+delta, b->length)<1) {
		free (op);
		return NULL;
	}
	return op;
}
Пример #2
0
int r_io_zip_slurp_file(RIOZipFileObj *zfo) {
	int res = R_FALSE;
	struct zip_stat sb;
	struct zip_file *zFile = NULL;
	struct zip * zipArch ;

	if (!zfo) return res;
	zipArch = r_io_zip_open_archive (
		zfo->archivename, zfo->flags,
		zfo->mode, zfo->rw);
	//eprintf("Slurping file");

	if (zipArch && zfo && zfo->entry != -1) {
		zFile = zip_fopen_index (zipArch, zfo->entry, 0);
		if (!zfo->b)
			zfo->b = r_buf_new ();
		zip_stat_init (&sb);
		if (zFile && zfo->b && !zip_stat_index(zipArch,
				zfo->entry, 0, &sb) ) {
			ut8 *buf = malloc (sb.size);
			memset (buf, 0, sb.size);
			if (buf) {
				zip_fread (zFile, buf, sb.size);
				r_buf_set_bytes (zfo->b, buf, sb.size);
				res = zfo->opened = R_TRUE;
				free (buf);
			}
		}
		zip_fclose (zFile);
	}
	zip_close (zipArch);
	return res;
}
Пример #3
0
static int r_io_zip_slurp_file(RIOZipFileObj *zfo) {
	struct zip_file *zFile = NULL;
	struct zip *zipArch;
	struct zip_stat sb;
	bool res = false;
	if (!zfo) {
		return res;
	}
	zipArch = r_io_zip_open_archive (
		zfo->archivename, zfo->perm,
		zfo->mode, zfo->rw);

	if (zipArch && zfo && zfo->entry != -1) {
		zFile = zip_fopen_index (zipArch, zfo->entry, 0);
		if (!zfo->b) {
			zfo->b = r_buf_new ();
		}
		zip_stat_init (&sb);
		if (zFile && zfo->b && !zip_stat_index (zipArch, zfo->entry, 0, &sb)) {
			ut8 *buf = malloc (sb.size);
			memset (buf, 0, sb.size);
			if (buf) {
				zip_fread (zFile, buf, sb.size);
				r_buf_set_bytes (zfo->b, buf, sb.size);
				res = true;
				zfo->opened = true;
				free (buf);
			}
		}
		zip_fclose (zFile);
	}
	zip_close (zipArch);
	return res;
}
Пример #4
0
R_API RBuffer *r_buf_new_with_bytes (const ut8 *bytes, ut64 len) {
	RBuffer *b = r_buf_new ();
	if (b && bytes && (len > 0 && len != UT64_MAX)) {
		r_buf_set_bytes (b, bytes, len);
	}
	return b;
}
Пример #5
0
R_API int r_core_yank_set (RCore *core, ut64 addr, const ut8 *buf, ut32 len) {
	//free (core->yank_buf);
	if (buf && len) {
		r_buf_set_bytes (core->yank_buf, buf, len);
		core->yank_buf->base = addr;
		return R_TRUE;
	}
	return R_FALSE;
}
Пример #6
0
static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb) {
	if (!buf || !sz || sz == UT64_MAX) {
		return NULL;
	}
	RBuffer *tbuf = r_buf_new();
	r_buf_set_bytes (tbuf, buf, sz);
	void *res = r_bin_coff_new_buf (tbuf, arch->rbin->verbose);
	r_buf_free (tbuf);
	return res;
}
Пример #7
0
static void * load_bytes(const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
	void *res = NULL;
	RBuffer *tbuf = NULL;
	if (!buf || sz == 0 || sz == UT64_MAX) return NULL;
	tbuf = r_buf_new ();
	r_buf_set_bytes (tbuf, buf, sz);
	res = r_bin_dex_new_buf (tbuf);
	r_buf_free (tbuf);
	return res;
}
Пример #8
0
static RBuffer *build (REgg *egg) {
	RBuffer *buf = r_buf_new ();
	const ut8 *sc = NULL;
	int cd = 0;
	char *port = r_egg_option_get (egg, "port");
	//TODO: char *udp = r_egg_option_get (egg, "udp");
	switch (egg->os) {
	case R_EGG_OS_OSX:
	case R_EGG_OS_DARWIN:
		switch (egg->arch) {
		case R_SYS_ARCH_X86:
			if (suid) {
				sc = x86_osx_suid_binsh;
				cd = 7+36;
			} else {
				sc = x86_osx_binsh;
				cd = 36;
			}
		case R_SYS_ARCH_ARM:
			// TODO
			break;
		}
		break;
	case R_EGG_OS_LINUX:
		if (suid) eprintf ("no suid for this platform\n");
		suid = 0;
		switch (egg->arch) {
		case R_SYS_ARCH_X86:
			switch (egg->bits) {
			case 32: sc = x86_linux_binsh; break;
			case 64: sc = x86_64_linux_binsh; break;
			default: eprintf ("Unsupportted\n");
			}
			break;
		case R_SYS_ARCH_ARM:
			sc = arm_linux_binsh;
			break;
		}
		break;
	default:
		eprintf ("unsupported os %x\n", egg->os);
		break;
	}
	if (sc) {
		r_buf_set_bytes (buf, sc, strlen ((const char *)sc));
		if (shell && *shell) {
			if (cd) r_buf_write_at (buf, cd, (const ut8*)shell, strlen (shell)+1);
			else eprintf ("Cannot set shell\n");
		}
	}
	free (suid);
	free (shell);
	return buf;
}
Пример #9
0
struct r_bin_mz_obj_t* r_bin_mz_new_buf(const struct r_buf_t *buf) {
	struct r_bin_mz_obj_t *bin = R_NEW0 (struct r_bin_mz_obj_t);
	if (!bin) {
		return NULL;
	}
	bin->b = r_buf_new ();
	bin->size = buf->length;
	if (!r_buf_set_bytes (bin->b, buf->buf, bin->size)){
		return r_bin_mz_free (bin);
	}
	return r_bin_mz_init (bin) ? bin : r_bin_mz_free (bin);
}
Пример #10
0
static void * load_bytes(const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
	void *res = NULL;
	RBuffer *tbuf = NULL;
	struct r_bin_java_obj_t* bin_obj = NULL;
	if (!buf || sz == 0 || sz == UT64_MAX) return NULL;
	tbuf = r_buf_new();
	r_buf_set_bytes (tbuf, buf, sz);
	res = bin_obj = r_bin_java_new_buf (tbuf, loadaddr, sdb);
	add_bin_obj_to_sdb (bin_obj);
	r_buf_free (tbuf);
	return res;
}
Пример #11
0
struct r_bin_te_obj_t* r_bin_te_new_buf(struct r_buf_t *buf) {
	struct r_bin_te_obj_t *bin = R_NEW0 (struct r_bin_te_obj_t);
	if (!bin) return NULL;
	bin->kv = sdb_new0 ();
	bin->b = r_buf_new ();
	bin->size = buf->length;
	if (!r_buf_set_bytes (bin->b, buf->buf, bin->size)){
		return r_bin_te_free(bin);
	}
	if (!r_bin_te_init(bin))
		return r_bin_te_free(bin);
	return bin;
}
Пример #12
0
static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz,
		ut64 loadaddr, Sdb *sdb) {
	const struct r_bin_mz_obj_t *res = NULL;
	RBuffer *tbuf = NULL;
	if (!buf || sz == 0 || sz == UT64_MAX) return NULL;
	tbuf = r_buf_new ();
	r_buf_set_bytes (tbuf, buf, sz);
	res = r_bin_mz_new_buf (tbuf);
	if (res)
		sdb_ns_set (sdb, "info", res->kv);
	r_buf_free (tbuf);
	return (void *)res;
}
Пример #13
0
struct r_bin_dyldcache_obj_t* r_bin_dyldcache_from_bytes_new(const ut8* buf, ut64 size) {
	struct r_bin_dyldcache_obj_t *bin;
	if (!(bin = malloc (sizeof (struct r_bin_dyldcache_obj_t))))
		return NULL;
	memset (bin, 0, sizeof (struct r_bin_dyldcache_obj_t));
	if (!buf)
		return r_bin_dyldcache_free(bin);
	bin->b = r_buf_new();
	if (!r_buf_set_bytes(bin->b, buf, size))
		return r_bin_dyldcache_free(bin);
	if (!r_bin_dyldcache_init(bin))
		return r_bin_dyldcache_free(bin);
	return bin;
}
Пример #14
0
RBinJavaObj* r_bin_java_new(const char* file) {
	ut8 *buf;
	RBinJavaObj *bin = R_NEW0 (RBinJavaObj);
	bin->file = file;
	if (!(buf = (ut8*)r_file_slurp (file, &bin->size))) 
		return r_bin_java_free (bin);
	bin->b = r_buf_new ();
	if (!r_buf_set_bytes (bin->b, buf, bin->size))
		return r_bin_java_free (bin);
	free (buf);
	if (!javasm_init (bin))
		return r_bin_java_free (bin);
	return bin;
}
Пример #15
0
static int r_bin_coff_init(struct r_bin_coff_obj *obj, RBuffer *buf) {
	obj->b = r_buf_new ();
	obj->size = buf->length;
	if (!r_buf_set_bytes (obj->b, buf->buf, obj->size)){
		r_buf_free (obj->b);
		return false;
	}
	r_bin_coff_init_hdr(obj);
	r_bin_coff_init_opt_hdr(obj);

	r_bin_coff_init_scn_hdr(obj);
	r_bin_coff_init_symtable(obj);
	return true;
}
Пример #16
0
static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
	RBuffer *tbuf = NULL;
	RRarBinObj *res = NULL;
	if (!buf || sz == 0 || sz == UT64_MAX) {
		return NULL;
	}
	res = R_NEW0 (RRarBinObj);
	tbuf = r_buf_new ();
	r_buf_set_bytes (tbuf, buf, sz);
	res->buf = tbuf;
	res->kv = sdb;
	res->loadaddr = loadaddr;
	return res;
}
Пример #17
0
struct r_bin_te_obj_t* r_bin_te_new(const char* file) {
	ut8 *buf;
	struct r_bin_te_obj_t *bin = R_NEW0 (struct r_bin_te_obj_t);
	if (!bin) return NULL;
	bin->file = file;
	if (!(buf = (ut8*)r_file_slurp(file, &bin->size)))
		return r_bin_te_free(bin);
	bin->b = r_buf_new ();
	if (!r_buf_set_bytes (bin->b, buf, bin->size))
		return r_bin_te_free(bin);
	free (buf);
	if (!r_bin_te_init(bin))
		return r_bin_te_free(bin);
	return bin;
}
Пример #18
0
struct r_bin_dyldcache_obj_t* r_bin_dyldcache_new(const char* file) {
	struct r_bin_dyldcache_obj_t *bin;
	ut8 *buf;
	if (!(bin = malloc (sizeof (struct r_bin_dyldcache_obj_t))))
		return NULL;
	memset (bin, 0, sizeof (struct r_bin_dyldcache_obj_t));
	bin->file = file;
	if (!(buf = (ut8*)r_file_slurp(file, &bin->size))) 
		return r_bin_dyldcache_free(bin);
	bin->b = r_buf_new();
	if (!r_buf_set_bytes(bin->b, buf, bin->size))
		return r_bin_dyldcache_free(bin);
	free (buf);
	if (!r_bin_dyldcache_init(bin))
		return r_bin_dyldcache_free(bin);
	return bin;
}
Пример #19
0
static void *load_bytes(RBinFile *bf, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
	struct r_bin_java_obj_t *bin_obj = NULL;
	RBuffer *tbuf = NULL;
	void *res = NULL;
	if (!buf || sz == 0 || sz == UT64_MAX) {
		return NULL;
	}
	tbuf = r_buf_new ();
	r_buf_set_bytes (tbuf, buf, sz);
	res = bin_obj = r_bin_java_new_buf (tbuf, loadaddr, sdb);
	add_bin_obj_to_sdb (bin_obj);
	if (bf && bf->file) {
		bin_obj->file = strdup (bf->file);
	}
	r_buf_free (tbuf);
	return res;
}
Пример #20
0
struct r_bin_dex_obj_t* r_bin_dex_new_buf(RBuffer *buf) {
	struct r_bin_dex_obj_t *bin = R_NEW0 (struct r_bin_dex_obj_t);;
	if (!bin) return NULL;
	bin->size = buf->length;
	bin->b = r_buf_new ();
	if (!r_buf_set_bytes (bin->b, buf->buf, bin->size)){
		r_buf_free (bin->b);
		free (bin);
		return NULL;
	}
	// XXX: use r_buf_getc()
	// XXX: this is not endian safe
	/* header */
	r_buf_read_at (bin->b, 0, (ut8*)&bin->header, sizeof (struct dex_header_t));

	/* strings */
	bin->strings = (ut32 *) malloc (bin->header.strings_size * sizeof (ut32) + 1);
	r_buf_read_at (bin->b, bin->header.strings_offset, (ut8*)bin->strings,
			bin->header.strings_size * sizeof (ut32));
	/* classes */
	bin->classes = (struct dex_class_t *) malloc (bin->header.class_size *
			sizeof (struct dex_class_t) + 1);
	r_buf_read_at (bin->b, bin->header.class_offset, (ut8*)bin->classes,
			bin->header.class_size * sizeof (struct dex_class_t));
//{ ut8 *b = (ut8*)&bin->methods; eprintf ("CLASS %02x %02x %02x %02x\n", b[0], b[1], b[2], b[3]); }
	/* methods */
	bin->methods = (struct dex_method_t *) calloc (bin->header.method_size *
			sizeof (struct dex_method_t) + 1, 1);
	r_buf_read_at (bin->b, bin->header.method_offset, (ut8*)bin->methods,
			bin->header.method_size * sizeof (struct dex_method_t));
	/* types */
	bin->types = (struct dex_type_t *) calloc (bin->header.types_size *
			sizeof (struct dex_type_t) + 1, 1);
	r_buf_read_at (bin->b, bin->header.types_offset, (ut8*)bin->types,
			bin->header.types_size * sizeof (struct dex_type_t));
	/* fields */
	bin->fields = (struct dex_field_t *) calloc (bin->header.fields_size *
			sizeof (struct dex_field_t) + 1, 1);
	r_buf_read_at (bin->b, bin->header.fields_offset, (ut8*)bin->fields,
			bin->header.fields_size * sizeof (struct dex_field_t));
	return bin;
}
Пример #21
0
static int r_bin_bflt_init(struct r_bin_bflt_obj *obj, RBuffer *buf) {
	if (!(obj->b = r_buf_new ())) {
		return false;
	}
	obj->size = buf->length;
	obj->endian = false;
	obj->reloc_table = NULL;
	obj->got_table = NULL;
	obj->n_got = 0;
	obj->hdr = NULL;

	if(!r_buf_set_bytes (obj->b, buf->buf, obj->size)) {
		r_buf_free (obj->b);
		return false;
	}
	if (!bflt_init_hdr (obj)) {
		return false;
	}
	return true;
}
Пример #22
0
struct r_bin_mz_obj_t* r_bin_mz_new(const char* file) {
	const ut8 *buf;
	struct r_bin_mz_obj_t *bin = R_NEW0 (struct r_bin_mz_obj_t);
	if (!bin) {
		return NULL;
	}
	bin->file = file;
	if (!(buf = (ut8*)r_file_slurp (file, &bin->size))) {
		return r_bin_mz_free (bin);
	}
	bin->b = r_buf_new ();
	if (!r_buf_set_bytes (bin->b, buf, bin->size)) {
		free ((void *)buf);
		return r_bin_mz_free (bin);
	}
	free ((void *)buf);
	if (!r_bin_mz_init (bin)) {
		return r_bin_mz_free (bin);
	}
	return bin;
}
Пример #23
0
struct r_bin_dex_obj_t* r_bin_dex_new_buf(RBuffer *buf) {
	struct r_bin_dex_obj_t *bin = R_NEW0 (struct r_bin_dex_obj_t);
	if (!bin) {
		goto fail;
	}
	bin->size = buf->length;
	bin->b = r_buf_new ();
	if (!r_buf_set_bytes (bin->b, buf->buf, bin->size)) {
		goto fail;
	}
	// XXX: this is not endian safe
	// XXX: no need to dup all data!! just pointers to the bin->b
	// XXX: return value not checked
	/* header */
	//r_buf_read_at (bin->b, 0, (ut8*)&bin->header, sizeof (struct dex_header_t));
	if (bin->size < sizeof(struct dex_header_t))
		goto fail;
	bin->header = (*(struct dex_header_t*)bin->b->buf);

	/* strings */
//eprintf ("strings size: %d\n", bin->header.strings_size);
	#define STRINGS_SIZE ((bin->header.strings_size+1)*sizeof(ut32))
	bin->strings = (ut32 *) calloc (bin->header.strings_size + 1, sizeof (ut32));
	if (!bin->strings) {
		goto fail;
	}
	if (bin->header.strings_size > bin->size) {
		free (bin->strings);
		goto fail;
	}
	r_buf_read_at (bin->b, bin->header.strings_offset, (ut8*)bin->strings, bin->header.strings_size * sizeof (ut32));
	/* classes */
	int classes_size = bin->header.class_size * sizeof (struct dex_class_t);
	if (bin->header.class_offset + classes_size >= bin->size) {
		classes_size = bin->size - bin->header.class_offset;
	}
	if (classes_size<0) {
		classes_size = 0;
	}
	bin->header.class_size = classes_size / sizeof (struct dex_class_t);
	bin->classes = (struct dex_class_t *) malloc (classes_size);
	r_buf_read_at (bin->b, bin->header.class_offset, (ut8*)bin->classes, classes_size);
//{ ut8 *b = (ut8*)&bin->methods; eprintf ("CLASS %02x %02x %02x %02x\n", b[0], b[1], b[2], b[3]); }


	/* methods */
	int methods_size = bin->header.method_size * sizeof (struct dex_method_t);
	if (bin->header.method_offset + methods_size >= bin->size) {
		methods_size = bin->size - bin->header.method_offset;
	}
	if (methods_size < 0) {
		methods_size = 0;
	}
	bin->header.method_size = methods_size / sizeof (struct dex_method_t);
	bin->methods = (struct dex_method_t *) calloc (methods_size, 1);
	r_buf_read_at (bin->b, bin->header.method_offset, (ut8*)bin->methods, methods_size);


	/* types */
	int types_size = bin->header.types_size * sizeof (struct dex_type_t);
	if (bin->header.types_offset + types_size >= bin->size) {
		types_size = bin->size - bin->header.types_offset;
	}
	if (types_size < 0) {
		types_size = 0;
	}
	bin->header.types_size = types_size / sizeof (struct dex_type_t);
	bin->types = (struct dex_type_t *) calloc (types_size, 1);
	r_buf_read_at (bin->b, bin->header.types_offset, (ut8*)bin->types, types_size);

	/* fields */
	int fields_size = bin->header.fields_size * sizeof (struct dex_type_t);
	if (bin->header.fields_offset + fields_size >= bin->size) {
		fields_size = bin->size - bin->header.fields_offset;
	}
	if (fields_size<0) {
		fields_size = 0;
	}
	bin->header.fields_size = fields_size / sizeof (struct dex_field_t);
	bin->fields = (struct dex_field_t *) calloc (fields_size, 1);
	r_buf_read_at (bin->b, bin->header.fields_offset, (ut8*)bin->fields, fields_size);
	return bin;
fail:
	if (bin) {
		r_buf_free (bin->b);
		free (bin);
	}
	return NULL;
}
Пример #24
0
RBinDexObj *r_bin_dex_new_buf(RBuffer *buf) {
	RBinDexObj *bin = R_NEW0 (RBinDexObj);
	int i;
	ut8 *bufptr;
	struct dex_header_t *dexhdr;
	if (!bin) {
		goto fail;
	}
	bin->size = buf->length;
	bin->b = r_buf_new ();
	if (!r_buf_set_bytes (bin->b, buf->buf, bin->size)) {
		goto fail;
	}
	/* header */
	if (bin->size < sizeof (struct dex_header_t)) {
		goto fail;
	}
	bufptr = bin->b->buf;
	dexhdr = &bin->header;

	//check boundaries of bufptr
	if (bin->size < 112) {
		goto fail;
	}

	memcpy (&dexhdr->magic, bufptr, 8);
	dexhdr->checksum = r_read_le32 (bufptr + 8);
	memcpy (&dexhdr->signature, bufptr + 12, 20);
	dexhdr->size = r_read_le32 (bufptr + 32);
	dexhdr->header_size = r_read_le32 (bufptr + 36);
	dexhdr->endian = r_read_le32 (bufptr + 40);
	// TODO: this offsets and size will be used for checking,
	// so they should be checked. Check overlap, < 0, > bin.size
	dexhdr->linksection_size = r_read_le32 (bufptr + 44);
	dexhdr->linksection_offset = r_read_le32 (bufptr + 48);
	dexhdr->map_offset = r_read_le32 (bufptr + 52);
	dexhdr->strings_size = r_read_le32 (bufptr + 56);
	dexhdr->strings_offset = r_read_le32 (bufptr + 60);
	dexhdr->types_size = r_read_le32 (bufptr + 64);
	dexhdr->types_offset = r_read_le32 (bufptr + 68);
	dexhdr->prototypes_size = r_read_le32 (bufptr + 72);
	dexhdr->prototypes_offset = r_read_le32 (bufptr + 76);
	dexhdr->fields_size = r_read_le32 (bufptr + 80);
	dexhdr->fields_offset = r_read_le32 (bufptr + 84);
	dexhdr->method_size = r_read_le32 (bufptr + 88);
	dexhdr->method_offset = r_read_le32 (bufptr + 92);
	dexhdr->class_size = r_read_le32 (bufptr + 96);
	dexhdr->class_offset = r_read_le32 (bufptr + 100);
	dexhdr->data_size = r_read_le32 (bufptr + 104);
	dexhdr->data_offset = r_read_le32 (bufptr + 108);

	/* strings */
	#define STRINGS_SIZE ((dexhdr->strings_size + 1) * sizeof (ut32))
	bin->strings = (ut32 *) calloc (dexhdr->strings_size + 1, sizeof (ut32));
	if (!bin->strings) {
		goto fail;
	}
	if (dexhdr->strings_size > bin->size) {
		free (bin->strings);
		goto fail;
	}
	for (i = 0; i < dexhdr->strings_size; i++) {
		ut64 offset = dexhdr->strings_offset + i * sizeof (ut32);
		//make sure we can read from bufptr without oob
		if (offset + 4 > bin->size) {
			free (bin->strings);
			goto fail;
		}
		bin->strings[i] = r_read_le32 (bufptr + offset);
	}
	/* classes */
	// TODO: not sure about if that is needed
	int classes_size = dexhdr->class_size * DEX_CLASS_SIZE;
	if (dexhdr->class_offset + classes_size >= bin->size) {
		classes_size = bin->size - dexhdr->class_offset;
	}
	if (classes_size < 0) {
		classes_size = 0;
	}

	dexhdr->class_size = classes_size / DEX_CLASS_SIZE;
	bin->classes = (struct dex_class_t *) calloc (dexhdr->class_size, sizeof (struct dex_class_t));
	for (i = 0; i < dexhdr->class_size; i++) {
		ut64 offset = dexhdr->class_offset + i * DEX_CLASS_SIZE;
		if (offset + 32 > bin->size) {
			free (bin->strings);
			free (bin->classes);
			goto fail;
		}
		bin->classes[i].class_id = r_read_le32 (bufptr + offset + 0);
		bin->classes[i].access_flags = r_read_le32 (bufptr + offset + 4);
		bin->classes[i].super_class = r_read_le32 (bufptr + offset + 8);
		bin->classes[i].interfaces_offset = r_read_le32 (bufptr + offset + 12);
		bin->classes[i].source_file = r_read_le32 (bufptr + offset + 16);
		bin->classes[i].anotations_offset = r_read_le32 (bufptr + offset + 20);
		bin->classes[i].class_data_offset = r_read_le32 (bufptr + offset + 24);
		bin->classes[i].static_values_offset = r_read_le32 (bufptr + offset + 28);
	}

	/* methods */
	int methods_size = dexhdr->method_size * sizeof (struct dex_method_t);
	if (dexhdr->method_offset + methods_size >= bin->size) {
		methods_size = bin->size - dexhdr->method_offset;
	}
	if (methods_size < 0) {
		methods_size = 0;
	}
	dexhdr->method_size = methods_size / sizeof (struct dex_method_t);
	bin->methods = (struct dex_method_t *) calloc (methods_size + 1, 1);
	for (i = 0; i < dexhdr->method_size; i++) {
		ut64 offset = dexhdr->method_offset + i * sizeof (struct dex_method_t);
		if (offset + 8 > bin->size) {
			free (bin->strings);
			free (bin->classes);
			free (bin->methods);
			goto fail;
		}
		bin->methods[i].class_id = r_read_le16 (bufptr + offset + 0);
		bin->methods[i].proto_id = r_read_le16 (bufptr + offset + 2);
		bin->methods[i].name_id = r_read_le32 (bufptr + offset + 4);
	}

	/* types */
	int types_size = dexhdr->types_size * sizeof (struct dex_type_t);
	if (dexhdr->types_offset + types_size >= bin->size) {
		types_size = bin->size - dexhdr->types_offset;
	}
	if (types_size < 0) {
		types_size = 0;
	}
	dexhdr->types_size = types_size / sizeof (struct dex_type_t);
	bin->types = (struct dex_type_t *) calloc (types_size + 1, 1);
	for (i = 0; i < dexhdr->types_size; i++) {
		ut64 offset = dexhdr->types_offset + i * sizeof (struct dex_type_t);
		if (offset + 4 > bin->size) {
			free (bin->strings);
			free (bin->classes);
			free (bin->methods);
			free (bin->types);
			goto fail;
		}
		bin->types[i].descriptor_id = r_read_le32 (bufptr + offset);
	}

	/* fields */
	int fields_size = dexhdr->fields_size * sizeof (struct dex_field_t);
	if (dexhdr->fields_offset + fields_size >= bin->size) {
		fields_size = bin->size - dexhdr->fields_offset;
	}
	if (fields_size < 0) {
		fields_size = 0;
	}
	dexhdr->fields_size = fields_size / sizeof (struct dex_field_t);
	bin->fields = (struct dex_field_t *) calloc (fields_size + 1, 1);
	for (i = 0; i < dexhdr->fields_size; i++) {
		ut64 offset = dexhdr->fields_offset + i * sizeof (struct dex_field_t);
		if (offset + 8 > bin->size) {
			free (bin->strings);
			free (bin->classes);
			free (bin->methods);
			free (bin->types);
			free (bin->fields);
			goto fail;
		}
		bin->fields[i].class_id = r_read_le16 (bufptr + offset + 0);
		bin->fields[i].type_id = r_read_le16 (bufptr + offset + 2);
		bin->fields[i].name_id = r_read_le32 (bufptr + offset + 4);
	}

	/* proto */
	int protos_size = dexhdr->prototypes_size * sizeof (struct dex_proto_t);
	if (dexhdr->prototypes_offset + protos_size >= bin->size) {
		protos_size = bin->size - dexhdr->prototypes_offset;
	}
	if (protos_size < 1) {
		dexhdr->prototypes_size = 0;
		return bin;
	}
	dexhdr->prototypes_size = protos_size / sizeof (struct dex_proto_t);
	bin->protos = (struct dex_proto_t *) calloc (protos_size, 1);
	for (i = 0; i < dexhdr->prototypes_size; i++) {
		ut64 offset = dexhdr->prototypes_offset + i * sizeof (struct dex_proto_t);
		if (offset + 12 > bin->size) {
			free (bin->strings);
			free (bin->classes);
			free (bin->methods);
			free (bin->types);
			free (bin->fields);
			free (bin->protos);
			goto fail;
		}
		bin->protos[i].shorty_id = r_read_le32 (bufptr + offset + 0);
		bin->protos[i].return_type_id = r_read_le32 (bufptr + offset + 4);
		bin->protos[i].parameters_off = r_read_le32 (bufptr + offset + 8);
	}

	return bin;
	
fail:
	if (bin) {
		r_buf_free (bin->b);
		free (bin);
	}
	return NULL;
}
Пример #25
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;
}
Пример #26
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;
}
Пример #27
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;
}