Ejemplo n.º 1
0
static bool check_bytes(const ut8 *buf, ut64 length) {
	const ut8* buf_hdr = buf;
	ut16 cksum1, cksum2;

	if ((length & 0x8000) == 0x200) {
		buf_hdr += 0x200;
	}
	if (length < 0x8000) {
		return false;
	}
	//determine if ROM is headered, and add a 0x200 gap if so.
	cksum1 = r_read_le16 (buf_hdr + 0x7FDC);
	cksum2 = r_read_le16 (buf_hdr + 0x7FDE);

	if (cksum1 == (ut16)~cksum2) {
		return true;
	}

	if (length < 0xffee) {
		return false;
	}
	cksum1 = r_read_le16(buf_hdr + 0xFFDC);
	cksum2 = r_read_le16(buf_hdr + 0xFFDE);
	return (cksum1 == (ut16)~cksum2);
}
Ejemplo n.º 2
0
Archivo: mz.c Proyecto: agatti/radare2
// This function reads from the file buffer,
// thus using endian-agnostic functions
int cmp_segs(const void *a, const void *b) {
	const ut16 * const ma = (const ut16 * const)a;
	const ut16 * const mb = (const ut16 * const)b;
	if (!ma || !mb) {
		return 0;
	}
	return (int)(r_read_le16 (ma) - r_read_le16 (mb));
}
Ejemplo n.º 3
0
static void headers64(RBinFile *bf) {
#define p bf->rbin->cb_printf
	const ut8 *buf = r_buf_get_at (bf->buf, 0, NULL);
	p ("0x00000000  ELF64       0x%08x\n", r_read_le32 (buf));
	p ("0x00000010  Type        0x%04x\n", r_read_le16 (buf + 0x10));
	p ("0x00000012  Machine     0x%04x\n", r_read_le16 (buf + 0x12));
	p ("0x00000014  Version     0x%08x\n", r_read_le32 (buf + 0x14));
	p ("0x00000018  Entrypoint  0x%08"PFMT64x"\n", r_read_le64 (buf + 0x18));
	p ("0x00000020  PhOff       0x%08"PFMT64x"\n", r_read_le64 (buf + 0x20));
	p ("0x00000028  ShOff       0x%08"PFMT64x"\n", r_read_le64 (buf + 0x28));
}
Ejemplo n.º 4
0
Archivo: mz.c Proyecto: agatti/radare2
// This function reads from the file buffer,
// thus using endian-agnostic functions
void trv_segs (const void *seg, const void *segs) {
	const ut8 * const mseg = (const ut8 * const)seg;
	ut16 ** const msegs = (ut16 **)segs;
	if (mseg && msegs && *msegs) {
		r_write_le16(*msegs, r_read_le16(mseg));
		*msegs = *msegs + 1;
	}
}
Ejemplo n.º 5
0
// header starts at offset 0 and ends at offset 0x40
static SymbolsHeader parseHeader(RBuffer *buf) {
	ut8 b[64];
	SymbolsHeader sh = { 0 };
	(void)r_buf_read_at (buf, 0, b, sizeof (b));
	sh.magic = r_read_le32 (b);
	sh.version = r_read_le32 (b + 4);
	sh.valid = sh.magic == 0xff01ff02;
	int i;
	for (i = 0; i < 16; i++) {
		sh.uuid[i] = b[24 + i];
	}
	sh.unk0 = r_read_le16 (b + 0x28);
	sh.unk1 = r_read_le16 (b + 0x2c); // is slotsize + 1 :?
	sh.slotsize = r_read_le16 (b + 0x2e);
	sh.size = 0x40;
	return sh;
}
Ejemplo n.º 6
0
R_API ut64 r_mem_get_num(const ut8 *b, int size) {
	// LITTLE ENDIAN is the default for streams
	switch (size) {
	case 1:
		return r_read_le8 (b);
	case 2:
		return r_read_le16 (b);
	case 4:
		return r_read_le32 (b);
	case 8:
		return r_read_le64 (b);
	}
	return 0LL;
}
Ejemplo n.º 7
0
Archivo: dex.c Proyecto: 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;
}
Ejemplo n.º 8
0
Archivo: mz.c Proyecto: agatti/radare2
struct r_bin_mz_segment_t * r_bin_mz_get_segments(const struct r_bin_mz_obj_t *bin) {
#if 0
	int i;
	struct r_bin_mz_segment_t *ret;

	const MZ_image_relocation_entry * const relocs = bin->relocation_entries;
	const int num_relocs = bin->dos_header->num_relocs;

	eprintf ("cs 0x%x\n", bin->dos_header->cs);
	eprintf ("ss 0x%x\n", bin->dos_header->ss);
	for (i = 0; i < num_relocs; i++) {
		eprintf ("0x%08x segment 0x%08lx\n", relocs[i].offset, relocs[i].segment);
		// ut65 paddr = r_bin_mz_seg_to_paddr (bin, relocs[i].segment) + relocs[i].offset;
		// eprintf ("pa 0x%08llx\n", paddr);
	}
	btree_add (&tree, (void *)&first_segment, cmp_segs);
	/* Add segment address of stack segment if it's resides inside dos
	executable.
	*/
	if (r_bin_mz_seg_to_paddr (bin, stack_segment) < bin->dos_file_size) {
		btree_add (&tree, (void *)&stack_segment, cmp_segs);
	}
	return NULL;
#endif
#if 1
	struct btree_node *tree;
	struct r_bin_mz_segment_t *ret;
	ut16 *segments, *curr_seg;
	int i, num_segs;
	ut64 paddr;
	const ut16 first_segment = 0;
	const ut16 stack_segment = bin->dos_header->ss;
	const MZ_image_relocation_entry * const relocs = bin->relocation_entries;
	const int num_relocs = bin->dos_header->num_relocs;
	const ut64 last_parag = ((bin->dos_file_size + 0xF) >> 4) - \
		bin->dos_header->header_paragraphs;

	btree_init (&tree);
	for (i = 0; i < num_relocs; i++) {
		paddr = r_bin_mz_seg_to_paddr (bin, relocs[i].segment) + relocs[i].offset;
		if ((paddr + 2) < bin->dos_file_size) {
			curr_seg = (ut16 *)(bin->b->buf + paddr);
			/* Add segment only if it's located inside dos executable data */
			if (r_read_le16 (curr_seg) <= last_parag) {
				btree_add (&tree, curr_seg, cmp_segs);
			}
		}
	}

	/* Add segment address of first segment to make sure that it will be
	added. If relocations empty or there isn't first segment in relocations.)
	*/
	btree_add (&tree, (void *)&first_segment, cmp_segs);
	/* Add segment address of stack segment if it's resides inside dos
	executable.
	*/
	if (r_bin_mz_seg_to_paddr (bin, stack_segment) < bin->dos_file_size) {
		btree_add (&tree, (void *)&stack_segment, cmp_segs);
	}

	if (!num_relocs) {
		btree_cleartree (tree, NULL);
		return NULL;
	}
	segments = calloc (1 + num_relocs, sizeof (*segments));
	if (!segments) {
		eprintf ("Error: calloc (segments)\n");
		btree_cleartree (tree, NULL);
		return NULL;
	}
	curr_seg = segments;
	btree_traverse (tree, 0, &curr_seg, trv_segs);
	num_segs = curr_seg - segments;
	ret = calloc (num_segs + 1, sizeof (struct r_bin_mz_segment_t));
	if (!ret) {
		free (segments);
		btree_cleartree (tree, NULL);
		eprintf ("Error: calloc (struct r_bin_mz_segment_t)\n");
		return NULL;
	}

	btree_cleartree (tree, NULL);

	ret[0].paddr = r_bin_mz_seg_to_paddr (bin, segments[0]);
	for (i = 1; i < num_segs; i++) {
		ret[i].paddr = r_bin_mz_seg_to_paddr (bin, segments[i]);
		ret[i - 1].size = ret[i].paddr - ret[i - 1].paddr;
	}
	ret[i - 1].size = bin->dos_file_size - ret[i - 1].paddr;
	ret[i].last = 1;
	free (segments);
	return ret;
#endif
}
Ejemplo n.º 9
0
/**
 * crc16 - compute the CRC-16 for the data buffer
 * @crc:	previous CRC value
 * @buffer:	data pointer
 * @len:	number of bytes in the buffer
 *
 * Returns the updated CRC value.
 */
R_API ut16 r_hash_crc16(ut16 crc, ut8 const *buffer, ut64 len) {
	while (len--) {
		crc = crc16_byte (crc, *buffer++);
	}
	return r_read_le16 (&crc);
}