Example #1
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;
}
Example #2
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;
}
Example #3
0
static void * load_bytes(RBinFile *bf, const ut8 *buf, ut64 sz,
		ut64 loadaddr, Sdb *sdb) {
	const struct r_bin_mz_obj_t *res = NULL;
	RBuffer *tbuf = NULL;
	if (!buf || !sz || 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;
}
Example #4
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;
}
Example #5
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;
}
Example #6
0
/* inspired in http://www.phreedom.org/solar/code/tinype/tiny.97/tiny.asm */
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen) {
	RBuffer *buf = r_buf_new ();
#define B(x,y) r_buf_append_bytes(buf,(const ut8*)x,y)
#define D(x) r_buf_append_ut32(buf,x)
	D (I_MAGIC); // i386 only atm
	D (codelen);
	D (datalen);
	D (4096); // bss
	D (0); // syms
	D (8*4); // entry
	D (4096); // spsz
	D (4096); // pcsz
	B (code, codelen);
	if (datalen>0)
		B (data, datalen);
	return buf;
}
Example #7
0
File: buf.c Project: P4N74/radare2
R_API RBuffer *r_buf_new_file(const char *file, bool newFile) {
	const int mode = 0644;
	int flags = O_RDWR;
	if (newFile) {
		flags |= O_CREAT;
	}
	int fd = r_sandbox_open (file, flags, mode);
	if (fd != -1) {
		RBuffer *b = r_buf_new ();
		if (!b) {
			r_sandbox_close (fd);
			return NULL;
		}
		b->fd = fd;
		return b;
	}
	return NULL; /* we just freed b, don't return it */
}
Example #8
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;
}
Example #9
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;
}
Example #10
0
File: mz.c Project: agatti/radare2
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;
}
Example #11
0
int r_io_zip_slurp_file(RIOZipFileObj *zip_file_obj) {
	struct zip_file *zFile = NULL;
	int result = R_FALSE;
	struct zip * zipArch = r_io_zip_open_archive(zip_file_obj->archivename, zip_file_obj->flags, zip_file_obj->mode, zip_file_obj->rw);
	struct zip_stat sb; 
	//eprintf("Slurping file");
	if (zip_file_obj && zip_file_obj->entry != -1) {

		zFile = zip_fopen_index(zipArch, zip_file_obj->entry, 0);
		if (!zip_file_obj->b) {
			zip_file_obj->b = r_buf_new();
		}
		zip_stat_init(&sb);

		if (zFile && zip_file_obj->b && !zip_stat_index(zipArch, zip_file_obj->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(zip_file_obj->b, buf, sb.size);
				zip_file_obj->opened = 1;
				result = R_TRUE;
			}
			if (buf)
				free(buf);
		}
		if (zFile) {
			zip_fclose(zFile);
		}
	}
	if (zipArch)
		zip_close(zipArch);

	return result;
}
Example #12
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;
}
Example #13
0
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen) {
	ut32 filesize, codeva, datava;
	ut32 ncmds, cmdsize, magiclen;
	ut32 p_codefsz = 0, p_codeva = 0, p_codesz = 0, p_codepa = 0;
	ut32 p_datafsz = 0, p_datava = 0, p_datasz = 0, p_datapa = 0;
	ut32 p_cmdsize = 0, p_entry = 0, p_tmp = 0;
	ut32 baddr = 0x1000;
	int is_arm = !strcmp (bin->curarch.info->arch, "arm");
	RBuffer *buf = r_buf_new ();
	if (bin->curarch.info->bits == 64) {
		eprintf ("TODO: Please use mach064 instead of mach0\n");
		return 0;
	}

#define B(x,y) r_buf_append_bytes(buf,(const ut8*)x,y)
#define D(x) r_buf_append_ut32(buf,x)
#define Z(x) r_buf_append_nbytes(buf,x)
#define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)y,z)
#define WZ(x,y) p_tmp=buf->length;Z(x);W(p_tmp,y,strlen(y))

	/* MACH0 HEADER */
	B ("\xce\xfa\xed\xfe", 4); // header
	if (is_arm) {
		D (12); // cpu type (arm)
		D (3); // subtype (all?)
	} else {
		/* x86-32 */
		D (7); // cpu type (x86)
		D (3); // subtype (i386-all)
	}
	D (2); // filetype (executable)

	if (data && datalen>0) {
		ncmds = 3;
		cmdsize = 0;
	} else {
		ncmds = 2;
		cmdsize = 0;
	}
	
	/* COMMANDS */
	D (ncmds); // ncmds
	p_cmdsize = buf->length;
	D (-1); // cmdsize
	D (0); // flags
	magiclen = buf->length;

	/* TEXT SEGMENT */
	D (1);   // cmd.LC_SEGMENT
	D (124); // sizeof (cmd)
	WZ (16, "__TEXT");
	D (baddr); // vmaddr
	D (0x1000); // vmsize XXX
	D (0); // fileoff
	p_codefsz = buf->length;
	D (-1); // filesize
	D (7); // maxprot
	D (5); // initprot
	D (1); // nsects
	D (0); // flags
	WZ (16, "__text");
	WZ (16, "__TEXT");
	p_codeva = buf->length; // virtual address
	D (-1);
	p_codesz = buf->length; // size of code (end-start)
	D (-1);
	p_codepa = buf->length; // code - baddr
	D (-1); //_start-0x1000);
	D (2); // align
	D (0); // reloff
	D (0); // nrelocs
	D (0); // flags
	D (0); // reserved
	D (0);

	if (data && datalen>0) {
		/* DATA SEGMENT */
		D (1);   // cmd.LC_SEGMENT
		D (124); // sizeof (cmd)
		p_tmp = buf->length;
		Z (16);
		W (p_tmp, "__TEXT", 6); // segment name
		D (0x2000); // vmaddr
		D (0x1000); // vmsize
		D (0); // fileoff
		p_datafsz = buf->length;
		D (-1); // filesize
		D (6); // maxprot
		D (6); // initprot
		D (1); // nsects
		D (0); // flags

		WZ (16, "__data");
		WZ (16, "__DATA");

		p_datava = buf->length;
		D (-1);
		p_datasz = buf->length;
		D (-1);
		p_datapa = buf->length;
		D (-1); //_start-0x1000);
		D (2); // align
		D (0); // reloff
		D (0); // nrelocs
		D (0); // flags
		D (0); // reserved
		D (0);
	}

	/* THREAD STATE */
	D (5); // LC_UNIXTHREAD
	D (80); // sizeof (cmd)
	if (is_arm) {
		/* arm */
		D (1); // i386-thread-state
		D (17); // thread-state-count
		p_entry = buf->length + (16*sizeof (ut32));
		Z (17 * sizeof (ut32));
		// mach0-arm has one byte more
	} else {
		/* x86-32 */
		D (1); // i386-thread-state
		D (16); // thread-state-count
		p_entry = buf->length + (10*sizeof (ut32));
		Z (16 * sizeof (ut32));
	}

	cmdsize = buf->length - magiclen;

	codeva = buf->length + baddr;
	datava = buf->length + codelen + baddr;
	W (p_entry, &codeva, 4); // set PC

	/* fill header variables */
	W (p_cmdsize, &cmdsize, 4);
	filesize = magiclen + cmdsize + codelen + datalen;
	// TEXT SEGMENT //
	W (p_codefsz, &filesize, 4);
	W (p_codeva, &codeva, 4);
	W (p_codesz, &codelen, 4);
	p_tmp = codeva - baddr;
	W (p_codepa, &p_tmp, 4);

	B (code, codelen);

	if (data && datalen>0) {
		/* append data */
		W (p_datafsz, &filesize, 4);
		W (p_datava, &datava, 4);
		W (p_datasz, &datalen, 4);
		p_tmp = datava - baddr;
		W (p_datapa, &p_tmp, 4);
		B (data, datalen);
	}

	return buf;
}
Example #14
0
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RBinArchOptions *opt) {
	ut32 filesize, code_va, code_pa, phoff;
	ut32 p_start, p_phoff, p_phdr;
	ut32 p_ehdrsz, p_phdrsz;
	ut16 ehdrsz, phdrsz;
	ut32 p_vaddr, p_paddr, p_fs, p_fs2;
	ut32 baddr;
	int is_arm = 0;
	RBuffer *buf = r_buf_new ();

	r_return_val_if_fail (bin && opt && opt->arch, NULL);
	is_arm = !strcmp (opt->arch, "arm");
	// XXX: hardcoded
	if (is_arm) {
		baddr = 0x40000;
	} else {
		baddr = 0x8048000;
	}

#define B(x,y) r_buf_append_bytes(buf,(const ut8*)(x),y)
#define D(x) r_buf_append_ut32(buf,x)
#define H(x) r_buf_append_ut16(buf,x)
#define Z(x) r_buf_append_nbytes(buf,x)
#define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)(y),z)
#define WZ(x,y) p_tmp=r_buf_size (buf);Z(x);W(p_tmp,y,strlen(y))

	B ("\x7F" "ELF" "\x01\x01\x01\x00", 8);
	Z (8);
	H (2); // ET_EXEC
	if (is_arm) {
		H (40); // e_machne = EM_ARM
	} else {
		H (3); // e_machne = EM_I386
	}

	D (1);
	p_start = r_buf_size (buf);
	D (-1); // _start
	p_phoff = r_buf_size (buf);
	D (-1); // phoff -- program headers offset
	D (0);  // shoff -- section headers offset
	D (0); // flags
	p_ehdrsz = r_buf_size (buf);
	H (-1); // ehdrsz
	p_phdrsz = r_buf_size (buf);
	H (-1); // phdrsz
	H (1);
	H (0);
	H (0);
	H (0);
	// phdr:
	p_phdr = r_buf_size (buf);
	D (1);
	D (0);
	p_vaddr = r_buf_size (buf);
	D (-1); // vaddr = $$
	p_paddr = r_buf_size (buf);
	D (-1); // paddr = $$
	p_fs = r_buf_size (buf);
	D (-1); // filesize
	p_fs2 = r_buf_size (buf);
	D (-1); // filesize
	D (5); // flags
	D (0x1000); // align

	ehdrsz = p_phdr;
	phdrsz = r_buf_size (buf) - p_phdr;
	code_pa = r_buf_size (buf);
	code_va = code_pa + baddr;
	phoff = 0x34;//p_phdr ;
	filesize = code_pa + codelen + datalen;

	W (p_start, &code_va, 4);
	W (p_phoff, &phoff, 4);
	W (p_ehdrsz, &ehdrsz, 2);
	W (p_phdrsz, &phdrsz, 2);

	code_va = baddr; // hack
	W (p_vaddr, &code_va, 4);
	code_pa = baddr; // hack
	W (p_paddr, &code_pa, 4);

	W (p_fs, &filesize, 4);
	W (p_fs2, &filesize, 4);

	B (code, codelen);

	if (data && datalen > 0) {
		//ut32 data_section = buf->length;
		eprintf ("Warning: DATA section not support for ELF yet\n");
		B (data, datalen);
	}
	return buf;
}
Example #15
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;
}
Example #16
0
R_API RBuffer *r_buf_new_sparse() {
	RBuffer *b = r_buf_new ();
	b->sparse = r_list_newf ((RListFree)free);
	return b;
}
Example #17
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;
}
Example #18
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;
}
Example #19
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;
}
Example #20
0
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen) {
	const bool use_pagezero = true;
	const bool use_main = true;
	const bool use_dylinker = true;
	const bool use_libsystem = true;
	const bool use_linkedit = true;
	ut64 filesize, codeva, datava;
	ut32 ncmds, magiclen, headerlen;
	ut64 p_codefsz=0, p_codeva=0, p_codesz=0, p_codepa=0;
	ut64 p_datafsz=0, p_datava=0, p_datasz=0, p_datapa=0;
	ut64 p_cmdsize=0, p_entry=0, p_tmp=0;
	ut64 baddr = 0x100001000LL;
// TODO: baddr must be overriden with -b
	RBuffer *buf = r_buf_new ();

#define B(x,y) r_buf_append_bytes(buf,(const ut8*)x,y)
#define D(x) r_buf_append_ut32(buf,x)
#define Q(x) r_buf_append_ut64(buf,x)
#define Z(x) r_buf_append_nbytes(buf,x)
#define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)y,z)
#define WZ(x,y) p_tmp=buf->length;Z(x);W(p_tmp,y,strlen(y))

	/* MACH0 HEADER */
	// 32bit B ("\xce\xfa\xed\xfe", 4); // header
	B ("\xcf\xfa\xed\xfe", 4); // header
	D (7 | 0x01000000); // cpu type (x86) | ABI64
	//D (3); // subtype (i386-all)
	D(0x80000003); // x86-64 subtype
	D (2); // filetype (executable)

	ncmds = (data && datalen>0)? 3: 2;
	if (use_pagezero) {
		ncmds++;
	}
	if (use_dylinker) {
		ncmds++;
		if (use_linkedit) {
			ncmds += 3;
		}
		if (use_libsystem) {
			ncmds++;
		}
	}

	/* COMMANDS */
	D (ncmds); // ncmds
	p_cmdsize = buf->length;
	D (-1); // headsize // cmdsize?
	D (0);//0x85); // flags
	D (0); // reserved -- only found in x86-64

	magiclen = buf->length;

	if (use_pagezero) {
		/* PAGEZERO */
		D (0x19);   // cmd.LC_SEGMENT
		D (72); // sizeof (cmd)
		WZ (16, "__PAGEZERO");
		Q (0); // vmaddr
		Q (0x1000); // vmsize XXX
		Q (0); // fileoff
		Q (0); // filesize
		D (0); // maxprot
		D (0); // initprot
		D (0); // nsects
		D (0); // flags
	}

	/* TEXT SEGMENT */
	D (0x19);   // cmd.LC_SEGMENT_64
	//D (124+16+8); // sizeof (cmd)
	D (124+28); // sizeof (cmd)
	WZ (16, "__TEXT");
	Q (baddr); // vmaddr
	Q (0x1000); // vmsize XXX

	Q (0); // fileoff
	p_codefsz = buf->length;
	Q (-1); // filesize
	D (7); // maxprot
	D (5); // initprot
	D (1); // nsects
	D (0); // flags
	// define section
	WZ (16, "__text");
	WZ (16, "__TEXT");
	p_codeva = buf->length; // virtual address
	Q (-1);
	p_codesz = buf->length; // size of code (end-start)
	Q (-1);
	p_codepa = buf->length; // code - baddr
	D (-1); // offset, _start-0x1000);
	D (2); // align
	D (0); // reloff
	D (0); // nrelocs
	D (0); // flags
	D (0); // reserved1
	D (0); // reserved2
	D (0); // reserved3

	if (data && datalen>0) {
		/* DATA SEGMENT */
		D (0x19);   // cmd.LC_SEGMENT_64
		D (124+28); // sizeof (cmd)
		p_tmp = buf->length;
		Z (16);
		W (p_tmp, "__TEXT", 6); // segment name
//XXX must be vmaddr+baddr
		Q (0x2000); // vmaddr
//XXX must be vmaddr+baddr
		Q (0x1000); // vmsize
		Q (0); // fileoff
		p_datafsz = buf->length;
		Q (-1); // filesize
		D (6); // maxprot
		D (6); // initprot
		D (1); // nsects
		D (0); // flags

		WZ (16, "__data");
		WZ (16, "__DATA");

		p_datava = buf->length;
		Q (-1);
		p_datasz = buf->length;
		Q (-1);
		p_datapa = buf->length;
		D (-1); //_start-0x1000);
		D (2); // align
		D (0); // reloff
		D (0); // nrelocs
		D (0); // flags
		D (0); // reserved1
		D (0); // reserved2
		D (0); // reserved3
	}

	if (use_dylinker) {
		if (use_linkedit) {
			/* LINKEDIT */
			D (0x19);   // cmd.LC_SEGMENT
			D (72); // sizeof (cmd)
			WZ (16, "__LINKEDIT");
			Q (0x3000); // vmaddr
			Q (0x00001000); // vmsize XXX
			Q (0x1000); // fileoff
			Q (0); // filesize
			D (7); // maxprot
			D (3); // initprot
			D (0); // nsects
			D (0); // flags

			/* LC_SYMTAB */
			D (2); // cmd.LC_SYMTAB
			D (24); // sizeof (cmd)
			D (0x1000); // symtab offset
			D (0); // symtab size
			D (0x1000); // strtab offset
			D (0); // strtab size

			/* LC_DYSYMTAB */
			D (0xb); // cmd.LC_DYSYMTAB
			D (80); // sizeof (cmd)
			Z (18 * sizeof (ut32)); // empty
		}

		const char *dyld = "/usr/lib/dyld";
		const int dyld_len = strlen (dyld) + 1;
		D(0xe); /* LC_DYLINKER */
		D((4 * 3) + dyld_len);
		D(dyld_len - 2);
		WZ(dyld_len, dyld); // path

		if (use_libsystem) {
			/* add libSystem at least ... */
			const char *lib = "/usr/lib/libSystem.B.dylib";
			const int lib_len = strlen (lib) + 1;
			D (0xc); /* LC_LOAD_DYLIB */
			D (24 + lib_len); // cmdsize
			D (24); // offset where the lib string start
			D (0x2);
			D (0x1);
			D (0x1);
			WZ (lib_len, lib);
		}
	}
	if (use_main) {
		/* LC_MAIN */
		D (0x80000028);   // cmd.LC_MAIN
		D (24); // sizeof (cmd)
		D (baddr); // entryoff
		D (0); // stacksize
		D (0); // ???
		D (0); // ???
	} else {
#define STATESIZE (21*sizeof (ut64))
		/* THREAD STATE */
		D (5); // LC_UNIXTHREAD
		D (184); // sizeof (cmd)
		D (4); // 1=i386, 4=x86_64
		D (42); // thread-state-count
		p_entry = buf->length + (16*sizeof (ut64));
		Z (STATESIZE);
	}

	WZ (4096 - buf->length, "");
	headerlen = buf->length - magiclen;

	codeva = buf->length + baddr;
	datava = buf->length + codelen + baddr;

	if (p_entry != 0) {
		W (p_entry, &codeva, 8); // set PC
	}

	/* fill header variables */
	W (p_cmdsize, &headerlen, 4);
	filesize = magiclen + headerlen + codelen + datalen;
	// TEXT SEGMENT //
	W (p_codefsz, &filesize, 8);
	W (p_codefsz-16, &filesize, 8); // vmsize = filesize
	W (p_codeva, &codeva, 8);
	{
		ut64 clen = codelen;
		W (p_codesz, &clen, 8);
	}
	p_tmp = codeva - baddr;
	W (p_codepa, &p_tmp, 8);

	B (code, codelen);

	if (data && datalen>0) {
		/* append data */
		W (p_datafsz, &filesize, 8);
		W (p_datava, &datava, 8);
		W (p_datasz, &datalen, 8);
		p_tmp = datava - baddr;
		W (p_datapa, &p_tmp, 8);
		B (data, datalen);
	}

	return buf;
}
Example #21
0
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen) {
	ut32 filesize, code_va, code_pa, phoff;
	ut32 p_start, p_phoff, p_phdr;
	ut32 p_ehdrsz, p_phdrsz;
	ut16 ehdrsz, phdrsz;
	ut32 p_vaddr, p_paddr, p_fs, p_fs2;
	ut32 baddr = 0x8048000;
	RBuffer *buf = r_buf_new ();

#define B(x,y) r_buf_append_bytes(buf,(const ut8*)x,y)
#define D(x) r_buf_append_ut32(buf,x)
#define H(x) r_buf_append_ut16(buf,x)
#define Z(x) r_buf_append_nbytes(buf,x)
#define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)y,z)
#define WZ(x,y) p_tmp=buf->length;Z(x);W(p_tmp,y,strlen(y))

	B ("\x7F" "CGC" "\x01\x01\x01\x43", 8);
	Z (8);
	H (2); // ET_EXEC
	H (3); // e_machne = EM_I386

	D (1);
	p_start = buf->length;
	D (-1); // _start
	p_phoff = buf->length;
	D (-1); // phoff -- program headers offset
	D (0);  // shoff -- section headers offset
	D (0);  // flags
	p_ehdrsz = buf->length;
	H (-1); // ehdrsz
	p_phdrsz = buf->length;
	H (-1); // phdrsz
	H (1);
	H (0);
	H (0);
	H (0);
	// phdr:
	p_phdr = buf->length;
	D (1);
	D (0);
	p_vaddr = buf->length;
	D (-1); // vaddr = $$
	p_paddr = buf->length;
	D (-1); // paddr = $$
	p_fs = buf->length;
	D (-1); // filesize
	p_fs2 = buf->length;
	D (-1); // filesize
	D (5); // flags
	D (0x1000); // align

	ehdrsz = p_phdr;
	phdrsz = buf->length - p_phdr;
	code_pa = buf->length;
	code_va = code_pa + baddr;
	phoff = 0x34;//p_phdr ;
	filesize = code_pa + codelen + datalen;

	W (p_start, &code_va, 4);
	W (p_phoff, &phoff, 4);
	W (p_ehdrsz, &ehdrsz, 2);
	W (p_phdrsz, &phdrsz, 2);

	code_va = baddr; // hack
	W (p_vaddr, &code_va, 4);
	code_pa = baddr; // hack
	W (p_paddr, &code_pa, 4);

	W (p_fs, &filesize, 4);
	W (p_fs2, &filesize, 4);

	B (code, codelen);

	if (data && datalen>0) {
		//ut32 data_section = buf->length;
		eprintf ("Warning: DATA section not support for ELF yet\n");
		B (data, datalen);
	}
	return buf;
}
Example #22
0
/* inspired in http://www.phreedom.org/solar/code/tinype/tiny.97/tiny.asm */
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen) {
	RBuffer *buf = r_buf_new ();
	return buf;
}
Example #23
0
R_API RBuffer *r_buf_new_with_bytes (const ut8 *bytes, ut64 len) {
	RBuffer *b = r_buf_new ();
	if (bytes && (len > 0 && len != UT64_MAX))
		r_buf_set_bytes (b, bytes, len);
	return b;
}
Example #24
0
File: dex.c Project: P4N74/radare2
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;
}
Example #25
0
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen) {
	ut64 filesize, codeva, datava;
	ut32 ncmds, magiclen, headerlen;
	ut64 p_codefsz=0, p_codeva=0, p_codesz=0, p_codepa=0;
	ut64 p_datafsz=0, p_datava=0, p_datasz=0, p_datapa=0;
	ut64 p_cmdsize=0, p_entry=0, p_tmp=0;
	ut64 baddr = 0x100001000LL;
// TODO: baddr must be overriden with -b
	RBuffer *buf = r_buf_new ();

#define B(x,y) r_buf_append_bytes(buf,(const ut8*)x,y)
#define D(x) r_buf_append_ut32(buf,x)
#define Q(x) r_buf_append_ut64(buf,x)
#define Z(x) r_buf_append_nbytes(buf,x)
#define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)y,z)
#define WZ(x,y) p_tmp=buf->length;Z(x);W(p_tmp,y,strlen(y))

	/* MACH0 HEADER */
	// 32bit B ("\xce\xfa\xed\xfe", 4); // header
	B ("\xcf\xfa\xed\xfe", 4); // header
	D (7 | 0x01000000); // cpu type (x86) | ABI64
	//D (3); // subtype (i386-all)
	D(0x80000003); // unknown subtype issue
	D (2); // filetype (executable)

	ncmds = (data && datalen>0)? 3: 2;
	
	/* COMMANDS */
	D (ncmds); // ncmds
	p_cmdsize = buf->length;
	D (-1); // headsize // cmdsize?
	D (0);//0x85); // flags
	D (0); // reserved -- only found in x86-64

	magiclen = buf->length;

	/* TEXT SEGMENT */
	D (0x19);   // cmd.LC_SEGMENT_64
	//D (124+16+8); // sizeof (cmd)
	D (124+28); // sizeof (cmd)
	WZ (16, "__TEXT");
	Q (baddr); // vmaddr
	Q (0x1000); // vmsize XXX

	Q (0); // fileoff
	p_codefsz = buf->length;
	Q (-1); // filesize
	D (7); // maxprot
	D (5); // initprot
	D (1); // nsects
	D (0); // flags
	// define section
	WZ (16, "__text");
	WZ (16, "__TEXT");
	p_codeva = buf->length; // virtual address
	Q (-1);
	p_codesz = buf->length; // size of code (end-start)
	Q (-1);
	p_codepa = buf->length; // code - baddr
	D (-1); // offset, _start-0x1000);
	D (2); // align
	D (0); // reloff
	D (0); // nrelocs
	D (0); // flags
	D (0); // reserved1
	D (0); // reserved2
	D (0); // reserved3

	if (data && datalen>0) {
		/* DATA SEGMENT */
		D (0x19);   // cmd.LC_SEGMENT_64
		D (124+28); // sizeof (cmd)
		p_tmp = buf->length;
		Z (16);
		W (p_tmp, "__TEXT", 6); // segment name
//XXX must be vmaddr+baddr
		Q (0x2000); // vmaddr
//XXX must be vmaddr+baddr
		Q (0x1000); // vmsize
		Q (0); // fileoff
		p_datafsz = buf->length;
		Q (-1); // filesize
		D (6); // maxprot
		D (6); // initprot
		D (1); // nsects
		D (0); // flags

		WZ (16, "__data");
		WZ (16, "__DATA");

		p_datava = buf->length;
		Q (-1);
		p_datasz = buf->length;
		Q (-1);
		p_datapa = buf->length;
		D (-1); //_start-0x1000);
		D (2); // align
		D (0); // reloff
		D (0); // nrelocs
		D (0); // flags
		D (0); // reserved1
		D (0); // reserved2
		D (0); // reserved3
	}

#define STATESIZE (21*sizeof (ut64))
	/* THREAD STATE */
	D (5); // LC_UNIXTHREAD
	D (184); // sizeof (cmd)
	
	D (4); // 1=i386, 4=x86_64
	D (42); // thread-state-count
	p_entry = buf->length + (16*sizeof (ut64));
	Z (STATESIZE);

	headerlen = buf->length - magiclen;

	codeva = buf->length + baddr;
	datava = buf->length + codelen + baddr;
	W (p_entry, &codeva, 8); // set PC

	/* fill header variables */
	W (p_cmdsize, &headerlen, 4);
	filesize = magiclen + headerlen + codelen + datalen;
	// TEXT SEGMENT //
	W (p_codefsz, &filesize, 8);
	W (p_codeva, &codeva, 8);
	{
		ut64 clen = codelen;
		W (p_codesz, &clen, 8);
	}
	p_tmp = codeva - baddr;
	W (p_codepa, &p_tmp, 8);

	B (code, codelen);

	if (data && datalen>0) {
		/* append data */
		W (p_datafsz, &filesize, 8);
		W (p_datava, &datava, 8);
		W (p_datasz, &datalen, 8);
		p_tmp = datava - baddr;
		W (p_datapa, &p_tmp, 8);
		B (data, datalen);
	}

	return buf;
}
Example #26
0
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RBinArchOptions *opt) {
	ut32 p_start, p_phoff, p_phdr;
	ut32 p_vaddr, p_paddr, p_fs, p_fs2;
	ut32 p_ehdrsz, p_phdrsz;
	ut64 filesize, code_va, code_pa, phoff;
	ut16 ehdrsz, phdrsz;
	ut64 baddr = 0x400000LL;
	RBuffer *buf = r_buf_new ();

#define B(x,y) r_buf_append_bytes(buf,(const ut8*)(x),y)
#define Q(x) r_buf_append_ut64(buf,x)
#define D(x) r_buf_append_ut32(buf,x)
#define H(x) r_buf_append_ut16(buf,x)
#define Z(x) r_buf_append_nbytes(buf,x)
#define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)(y),z)

	/* Ehdr */
	B ("\x7F" "ELF" "\x02\x01\x01\x00", 8); // e_ident (ei_class = ELFCLASS64)
	Z (8);
	H (2); // e_type = ET_EXEC
	H (62); // e_machine = EM_X86_64
	D (1); // e_version = EV_CURRENT
	p_start = r_buf_size (buf);
	Q (-1); // e_entry = 0xFFFFFFFF
	p_phoff = r_buf_size (buf);
	Q (-1); // e_phoff = 0xFFFFFFFF
	Q (0);  // e_shoff = 0xFFFFFFFF
	D (0);  // e_flags
	p_ehdrsz = r_buf_size (buf);
	H (-1); // e_ehsize = 0xFFFFFFFF
	p_phdrsz = r_buf_size (buf);
	H (-1); // e_phentsize = 0xFFFFFFFF
	H (1);  // e_phnum
	H (0);  // e_shentsize
	H (0);  // e_shnum
	H (0);  // e_shstrndx

	/* Phdr */
	p_phdr = r_buf_size (buf);
	D (1); // p_type
	D (5);  // p_flags = PF_R | PF_X
	Q (0);  // p_offset
	p_vaddr = r_buf_size (buf);
	Q (-1); // p_vaddr = 0xFFFFFFFF
	p_paddr = r_buf_size (buf);
	Q (-1); // p_paddr = 0xFFFFFFFF
	p_fs = r_buf_size (buf);
	Q (-1); // p_filesz
	p_fs2 = r_buf_size (buf);
	Q (-1); // p_memsz
	Q (0x200000); // p_align

	/* Calc fields */
	ehdrsz = p_phdr;
	phdrsz = r_buf_size (buf) - p_phdr;
	code_pa = r_buf_size (buf);
	code_va = code_pa + baddr;
	phoff = p_phdr;
	filesize = code_pa + codelen + datalen;

	/* Write fields */
	W (p_start, &code_va, 8);
	W (p_phoff, &phoff, 8);
	W (p_ehdrsz, &ehdrsz, 2);
	W (p_phdrsz, &phdrsz, 2);
	W (p_fs, &filesize, 8);
	W (p_fs2, &filesize, 8);

	W (p_vaddr, &baddr, 8);
	W (p_paddr, &baddr, 8);

	/* Append code */
	B (code, codelen);

	if (data && datalen>0) {
		eprintf ("Warning: DATA section not support for ELF yet\n");
		B (data, datalen);
	}
	return buf;
}
Example #27
0
File: dex.c Project: VPaulV/radare2
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;
}