Ejemplo n.º 1
0
static RList *parseSegments(RBuffer *buf, int off, int count) {
	ut8 *b = calloc (count, 32);
	(void)r_buf_read_at (buf, off, b, count * 32);
	int x = off;
	int X = 0;
	int i;
	RList *segments = r_list_newf ((RListFree)r_bin_section_free);
	if (!segments) {
		return NULL;
	}
	// eprintf ("Segments: %d\n", count);
	for (i = 0; i < count; i++) {
		int A = r_read_le32 (b + X + 16);
		int B = r_read_le32 (b + X + 16 + 8);
		//	eprintf ("0x%08x  segment  0x%08x 0x%08x  %s\n",
		//		x, A, A + B, b + X);
		const char *cname = (const char *)(b + X);
		char *name = r_str_ndup (cname, r_str_nlen (cname, 16));
		RBinSection *section = newSection (name, A, A + B, true);
		free (name);
		r_list_append (segments, section);
		x += 32;
		X += 32;
	}
	return segments;
}
Ejemplo n.º 2
0
// metadata section starts at offset 0x40 and ends around 0xb0 depending on filenamelength
static SymbolsMetadata parseMetadata(RBuffer *buf, int off) {
	SymbolsMetadata sm = { 0 };
	ut8 b[0x100] = { 0 };
	(void)r_buf_read_at (buf, off, b, sizeof (b));
	sm.addr = off;
	sm.cputype = r_read_le32 (b);
	sm.arch = typeString (sm.cputype, &sm.bits);
	//  eprintf ("0x%08x  cputype  0x%x -> %s\n", 0x40, sm.cputype, typeString (sm.cputype));
	// bits = (strstr (typeString (sm.cputype, &sm.bits), "64"))? 64: 32;
	sm.subtype = r_read_le32 (b + 4);
	sm.cpu = subtypeString (sm.subtype);
	//  eprintf ("0x%08x  subtype  0x%x -> %s\n", 0x44, sm.subtype, subtypeString (sm.subtype));
	sm.n_segments = r_read_le32 (b + 8);
	// int count = r_read_le32 (b + 0x48);
	sm.namelen = r_read_le32 (b + 0xc);
	// eprintf ("0x%08x  count    %d\n", 0x48, count);
	// eprintf ("0x%08x  strlen   %d\n", 0x4c, sm.namelen);
	// eprintf ("0x%08x  filename %s\n", 0x50, b + 16);
	int delta = 16;
	sm.segments = parseSegments (buf, off + sm.namelen + delta, sm.n_segments);
	sm.size = (sm.n_segments * 32) + 120;

	// hack to detect format
	ut32 nm, nm2, nm3;
	r_buf_read_at (buf, off + sm.size, (ut8*)&nm, sizeof (nm));
	r_buf_read_at (buf, off + sm.size + 4, (ut8*)&nm2, sizeof (nm2));
	r_buf_read_at (buf, off + sm.size + 8, (ut8*)&nm3, sizeof (nm3));
	// eprintf ("0x%x next %x %x %x\n", off + sm.size, nm, nm2, nm3);
	if (r_read_le32 (&nm3) != 0xa1b22b1a) {
		sm.size -= 8;
		//		is64 = true;
	}
	return sm;
}
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
// 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.º 5
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.º 6
0
static ut32 readLE32(RBuffer *buf, int off) {
	int left = 0;
	const ut8 *data = r_buf_get_at (buf, off, &left);
	return left > 3? r_read_le32 (data): 0;
}
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
static ut32 readDword (RCoreObjc *objc, ut64 addr) {
	ut8 buf[4];
	(void)r_io_read_at (objc->core->io, addr, buf, sizeof (buf));
	return r_read_le32 (buf);
}
Ejemplo n.º 9
0
static RList* symbols(RBinFile *arch) {
    ut32 *vtable = (ut32*)arch->buf->buf;
    RList *ret = NULL;
    const char *name;
    SMD_Header *hdr;
    int i;

    if (!(ret = r_list_new ()))
        return NULL;
    ret->free = free;
    // TODO: store all this stuff in SDB
    hdr = (SMD_Header*)(arch->buf->buf + 0x100);
    addsym (ret, "rom_start", hdr->RomStart);
    addsym (ret, "rom_end", hdr->RomEnd);
    addsym (ret, "ram_start", hdr->RamStart);
    addsym (ret, "ram_end", hdr->RamEnd);
    showstr ("Copyright", hdr->CopyRights, 32);
    showstr ("DomesticName", hdr->DomesticName, 48);
    showstr ("OverseasName", hdr->OverseasName, 48);
    showstr ("ProductCode", hdr->ProductCode, 14);
    eprintf ("Checksum: 0x%04x\n", (ut32)hdr->CheckSum);
    showstr ("Peripherials", hdr->Peripherials, 16);
    showstr ("SramCode", hdr->CountryCode, 12);
    showstr ("ModemCode", hdr->CountryCode, 12);
    showstr ("CountryCode", hdr->CountryCode, 16);
    /* parse vtable */
    for (i=0; i<64; i++) {
        switch (i) {
        case 0:
            name = "SSP";
            break;
        case 1:
            name = "Reset";
            break;
        case 2:
            name = "BusErr";
            break;
        case 3:
            name = "InvOpCode";
            break;
        case 4:
            name = "DivBy0";
            break;
        case 5:
            name = "Check";
            break;
        case 6:
            name = "TrapV";
            break;
        case 7:
            name = "GPF";
            break;
        case 8:
            name = "Trace";
            break;
        case 9:
            name = "Reserv0";
            break;
        case 10:
            name = "Reserv1";
            break;
        case 11:
            name = "Reserv2";
            break;
        case 12:
            name = "Reserv3";
            break;
        case 13:
            name = "Reserv4";
            break;
        case 14:
            name = "BadInt";
            break;
        case 15:
            name = "Reserv10";
            break;
        case 16:
            name = "Reserv11";
            break;
        case 17:
            name = "Reserv12";
            break;
        case 18:
            name = "Reserv13";
            break;
        case 19:
            name = "Reserv14";
            break;
        case 20:
            name = "Reserv15";
            break;
        case 21:
            name = "Reserv16";
            break;
        case 22:
            name = "Reserv17";
            break;
        case 23:
            name = "BadIRQ";
            break;
        case 24:
            name = "IRQ1";
            break;
        case 25:
            name = "EXT";
            break;
        case 26:
            name = "IRQ3";
            break;
        case 27:
            name = "HBLANK";
            break;
        case 28:
            name = "IRQ5";
            break;
        case 29:
            name = "VBLANK";
            break;
        case 30:
            name = "IRQ7";
            break;
        case 31:
            name = "Trap0";
            break;
        case 32:
            name = "Trap1";
            break;
        case 33:
            name = "Trap2";
            break;
        case 34:
            name = "Trap3";
            break;
        case 35:
            name = "Trap4";
            break;
        case 36:
            name = "Trap5";
            break;
        case 37:
            name = "Trap6";
            break;
        case 38:
            name = "Trap7";
            break;
        case 39:
            name = "Trap8";
            break;
        case 40:
            name = "Trap9";
            break;
        case 41:
            name = "Trap10";
            break;
        case 42:
            name = "Trap11";
            break;
        case 43:
            name = "Trap12";
            break;
        case 44:
            name = "Trap13";
            break;
        case 45:
            name = "Trap14";
            break;
        case 46:
            name = "Trap15";
            break;
        case 47:
            name = "Reserv30";
            break;
        case 48:
            name = "Reserv31";
            break;
        case 49:
            name = "Reserv32";
            break;
        case 50:
            name = "Reserv33";
            break;
        case 51:
            name = "Reserv34";
            break;
        case 52:
            name = "Reserv35";
            break;
        case 53:
            name = "Reserv36";
            break;
        case 54:
            name = "Reserv37";
            break;
        case 55:
            name = "Reserv38";
            break;
        case 56:
            name = "Reserv39";
            break;
        case 57:
            name = "Reserv3A";
            break;
        case 58:
            name = "Reserv3B";
            break;
        case 59:
            name = "Reserv3C";
            break;
        case 60:
            name = "Reserv3D";
            break;
        case 61:
            name = "Reserv3E";
            break;
        case 62:
            name = "Reserv3F";
            break;
        default:
            name = NULL;
        }
        if (name && vtable[i]) {
            ut32 addr = 0;
            // XXX don't know if always LE
            addr = r_read_le32 (&vtable[i]);
            addsym (ret, name, addr);
        }
    }
    return ret;
}