示例#1
0
void
LE32toHost(uint8_t *ptr)
{
	uint32_t	val;

	val = readLE32(ptr);
	*(uint32_t *)ptr = val;
}
示例#2
0
static RList* entries(RBinFile *bf) {
	RList* ret = r_list_newf (free);
	RBinAddr *ptr = NULL;
	if (ret) {
		if ((ptr = R_NEW0 (RBinAddr))) {
			ut64 entry = (ut64)readLE32(bf->buf, 0x80);
			ut64 size = (ut64)readLE32(bf->buf, 0x84);
			// eprintf ("0x%x 0x%x\n", entry, size);
			ptr->paddr = entry;
			ptr->vaddr = entry;
			r_list_append (ret, ptr);
		} else {
			r_list_free (ret);
			ret = NULL;
		}
	}
	return ret;
}
示例#3
0
static void parseMod (RBinFile *bf, RBinNROObj *bin, ut32 mod0, ut64 baddr) {
	ut32 ptr = readLE32 (bf->buf, mod0);
	eprintf ("magic %x at 0x%x\n", ptr, mod0);
	if (ptr == 0x30444f4d) { // MOD0
		eprintf ("is mode0\n");
		MODHeader mh = {
			.magic = readLE32 (bf->buf, mod0),
			.dynamic = readLE32 (bf->buf, mod0 + 4),
			.bss_start = readLE32 (bf->buf, mod0 + 8),
			.bss_end = readLE32 (bf->buf, mod0 + 12),
			.unwind_start = readLE32 (bf->buf, mod0 + 16),
			.unwind_end = readLE32 (bf->buf, mod0 + 20),
			.mod_object = readLE32 (bf->buf, mod0 + 24),
		};
		mh.mod_object += mod0;
		eprintf ("magic 0x%x\n", mh.magic);
		eprintf ("dynamic 0x%x\n", mh.dynamic);
		eprintf ("bss 0x%x 0x%x\n", mh.bss_start, mh.bss_end);
		eprintf ("unwind 0x%x 0x%x\n", mh.unwind_start, mh.unwind_end);
		eprintf ("-------------\n");
		eprintf ("mod 0x%x\n", mh.mod_object);
#define MO_(x) readLE64(bf->buf, mh.mod_object + r_offsetof(MODObject, x))
		MODObject mo = {
			.next = MO_(next),
			.prev = MO_(prev),
			.relplt = MO_(relplt),
			.reldyn = MO_(reldyn),
			.base = MO_(base),
			.dynamic = MO_(dynamic),
			.is_rela = MO_(is_rela),
			.relplt_size = MO_(relplt_size),
			.init = MO_(init),
			.fini = MO_(fini),
			.bucket = MO_(bucket),
			.chain = MO_(chain),
			.strtab = MO_(strtab),
			.symtab = MO_(symtab),
			.strtab_size = MO_(strtab_size)
		};
		eprintf ("next 0x%llx\n", mo.next);
		eprintf ("prev 0x%llx\n", mo.prev);
		eprintf ("base 0x%llx\n", mo.base);
		eprintf ("init 0x%llx\n", mo.init);
		eprintf ("fini 0x%llx\n", mo.fini);
		eprintf ("relplt 0x%llx\n", mo.relplt - mo.base);
		eprintf ("symtab = 0x%llx\n", mo.symtab - mo.base);
		eprintf ("strtab = 0x%llx\n", mo.strtab - mo.base);
		eprintf ("strtabsz = 0x%llx\n", mo.strtab_size);
		//ut32 modo = mh.mod_object;
		ut64 strtab = mo.strtab - mo.base;
		ut64 symtab = mo.symtab - mo.base;
		walkSymbols (bf, bin, symtab, strtab, mo.strtab_size, mo.relplt - mo.base, baddr);
	}
}
示例#4
0
static void *load_bytes(RBinFile *bf, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb) {
	RBinNROObj *bin = R_NEW0 (RBinNROObj);
	if (!bin) {
		return NULL;
	}
	ut64 ba = baddr (bf);
	bin->methods_list = r_list_newf ((RListFree)free);
	bin->imports_list = r_list_newf ((RListFree)free);
	bin->classes_list = r_list_newf ((RListFree)free);
	ut32 mod0 = readLE32 (bf->buf, NRO_OFFSET_MODMEMOFF);
	parseMod (bf, bin, mod0, ba);
	return (void *) bin;//(size_t) check_bytes (buf, sz);
}
示例#5
0
文件: bin_nro.c 项目: radare/radare2
static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb) {
	RBinNXOObj *bin = R_NEW0 (RBinNXOObj);
	if (!bin) {
		return false;
	}
	ut64 ba = baddr (bf);
	bin->methods_list = r_list_newf ((RListFree)free);
	bin->imports_list = r_list_newf ((RListFree)free);
	bin->classes_list = r_list_newf ((RListFree)free);
	ut32 mod0 = readLE32 (bf->buf, NRO_OFFSET_MODMEMOFF);
	parseMod (bf->buf, bin, mod0, ba);
	*bin_obj = bin;
	return true;
}
示例#6
0
static RList* sections(RBinFile *bf) {
	RList *ret = NULL;
	RBinSection *ptr = NULL;
	if (!(ret = r_list_newf (free))) {
		return NULL;
	}
	if (!(ptr = R_NEW0 (RBinSection))) {
		return ret;
	}
	ut64 vaddr = (ut64)readLE32 (bf->buf, 0x80);
	ut64 psize = (ut64)readLE32(bf->buf, 0x84);
	ptr->name = strdup ("system");
	ptr->size = psize;
	ptr->arch = strdup ("arm");
	ptr->bits = 16;
	ptr->vsize = psize;
	ptr->paddr = 0x100;
	ptr->vaddr = vaddr;
	ptr->perm = R_PERM_RX;
	ptr->add = true;
	r_list_append (ret, ptr);

	return ret;
}
示例#7
0
int metaRead(int fd, unsigned int field_id, unsigned int *buf) {
	int convertTwoByteToSingleChar(unsigned int *, const unsigned int *, int);
	unsigned long audio_bytes, mdversion, numfields, fieldlen, wrk, savpos;
	unsigned int fid, nfv=0, i, j, ret, ret1 = 0;
	unsigned char tmpbuf[128];
//	char msg[128], digits[16];;

	savpos = lseek(fd, 0, SEEK_CUR);  // save current position
	
	wrk = lseek(fd, 0, SEEK_SET);
	ret = readLE32(fd, (long)&audio_bytes, CURRENT_POS);
//	printf("%s has %ld audio bytes\n",argv[n], wrk);
	wrk = lseek(fd, audio_bytes + 4, SEEK_SET);
	ret = readLE32(fd, (long)&mdversion, CURRENT_POS);
	if((mdversion == 0) || (mdversion > META_CURRENT_VERSION)) {
		goto failed;
	}
	ret = readLE32(fd, (long)&numfields, CURRENT_POS);
//	printf("num fields=%ld\n", numfields);

//	strcpy(msg,"metaRead numfields ");
//	unsignedlongToHexString((long)numfields,digits);
//	strcat(msg, digits);
//	logString(msg, ASAP);
	
	for(i=0; i<(int)numfields; i++) {
		ret = readLE16(fd, (long)&fid, CURRENT_POS);
//		printf("\n  field id=%d\n",fid);
		ret = readLE32(fd, (long)&fieldlen, CURRENT_POS);
//		printf("    filed length=%d\n", fieldlen);
		ret = read(fd, (unsigned long)&nfv << 1, 1);
		nfv &= 1;
//		printf("    num field values=%d\n", nfv);
		for(j=0; j<nfv; j++) {
			unsigned int fl;
			ret = readLE16(fd, (long)&fl, CURRENT_POS);
//			printf("    field value length[%d]=%d\n",j,fl);
			ret = read(fd, (unsigned long) tmpbuf << 1, fl);
			if(field_id == fid) {
				ret1 = fl;
				goto foundit;
			}
//			printf("    field value[%d]=",j);
/*			for(k=0; k<fl; k++) {
				printf("0x%.2x ", buf[k]);
			}
			printf("\n");
*/
//			printf("'%s'",buf);
/*			if(fid == 0) { // categories
				unsigned int m = buf[0] - '0';
				if((m >= 0 && m < 9)) {
					printf(" (%s) ", categories[m]);
				}
			}
			printf("\n");
			*/
		}
	}
failed:
//	strcpy(msg, "metaRead failed");
//	logString(msg, ASAP);
	
	wrk = lseek(fd, savpos, SEEK_SET);
	return(-1);
foundit:
//	strcpy(msg,"metaRead found item ");
//	unsignedlongToHexString((long)ret1,digits);
//	strcat(msg, digits);
//	logString(msg, ASAP);
	
	ret = convertTwoByteToSingleChar(buf,(const unsigned int *)tmpbuf,ret1);
	wrk = lseek(fd, savpos, SEEK_SET);
	return(ret1);
}
示例#8
0
static RList *sections(RBinFile *bf) {
	RList *ret = NULL;
	RBinSection *ptr = NULL;
	RBuffer *b = bf->buf;
	if (!bf->o->info) {
		return NULL;
	}
	if (!(ret = r_list_new ())) {
		return NULL;
	}
	ret->free = free;

	ut64 ba = baddr (bf);

	if (!(ptr = R_NEW0 (RBinSection))) {
		return ret;
	}
	strncpy (ptr->name, "header", R_BIN_SIZEOF_STRINGS);
	ptr->size = 0x80;
	ptr->vsize = 0x80;
	ptr->paddr = 0;
	ptr->vaddr = 0;
	ptr->srwx = R_BIN_SCN_READABLE;
	ptr->add = false;
	r_list_append (ret, ptr);

	int bufsz = r_buf_size (bf->buf);

	ut32 mod0 = readLE32 (bf->buf, NRO_OFFSET_MODMEMOFF);
	if (mod0 && mod0 + 8 < bufsz) {
		if (!(ptr = R_NEW0 (RBinSection))) {
			return ret;
		}
		ut32 mod0sz = readLE32 (bf->buf, mod0 + 4);
		strncpy (ptr->name, "mod0", R_BIN_SIZEOF_STRINGS);
		ptr->size = mod0sz;
		ptr->vsize = mod0sz;
		ptr->paddr = mod0;
		ptr->vaddr = mod0 + ba;
		ptr->srwx = R_BIN_SCN_READABLE; // rw-
		ptr->add = false;
		r_list_append (ret, ptr);
	} else {
		eprintf ("Invalid MOD0 address\n");
	}

	ut32 sig0 = readLE32 (bf->buf, 0x18);
	if (sig0 && sig0 + 8 < bufsz) {
		if (!(ptr = R_NEW0 (RBinSection))) {
			return ret;
		}
		ut32 sig0sz = readLE32 (bf->buf, sig0 + 4);
		strncpy (ptr->name, "sig0", R_BIN_SIZEOF_STRINGS);
		ptr->size = sig0sz;
		ptr->vsize = sig0sz;
		ptr->paddr = sig0;
		ptr->vaddr = sig0 + ba;
		ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_MAP; // r--
		ptr->add = true;
		r_list_append (ret, ptr);
	} else {
		eprintf ("Invalid SIG0 address\n");
	}

	// add text segment
	if (!(ptr = R_NEW0 (RBinSection))) {
		return ret;
	}
	strncpy (ptr->name, "text", R_BIN_SIZEOF_STRINGS);
	ptr->vsize = readLE32 (b, NRO_OFF (text_size));
	ptr->size = ptr->vsize;
	ptr->paddr = readLE32 (b, NRO_OFF (text_memoffset));
	ptr->vaddr = ptr->paddr + ba;
	ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x
	ptr->add = true;
	r_list_append (ret, ptr);

	// add ro segment
	if (!(ptr = R_NEW0 (RBinSection))) {
		return ret;
	}
	strncpy (ptr->name, "ro", R_BIN_SIZEOF_STRINGS);
	ptr->vsize = readLE32 (b, NRO_OFF (ro_size));
	ptr->size = ptr->vsize;
	ptr->paddr = readLE32 (b, NRO_OFF (ro_memoffset));
	ptr->vaddr = ptr->paddr + ba;
	ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_MAP; // r-x
	ptr->add = true;
	r_list_append (ret, ptr);

	// add data segment
	if (!(ptr = R_NEW0 (RBinSection))) {
		return ret;
	}
	strncpy (ptr->name, "data", R_BIN_SIZEOF_STRINGS);
	ptr->vsize = readLE32 (b, NRO_OFF (data_size));
	ptr->size = ptr->vsize;
	ptr->paddr = readLE32 (b, NRO_OFF (data_memoffset));
	ptr->vaddr = ptr->paddr + ba;
	ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_WRITABLE | R_BIN_SCN_MAP; // rw-
	ptr->add = true;
	eprintf ("Base Address 0x%08"PFMT64x "\n", ba);
	eprintf ("BSS Size 0x%08"PFMT64x "\n", (ut64)
			readLE32 (bf->buf, NRO_OFF (bss_size)));
	r_list_append (ret, ptr);
	return ret;
}
示例#9
0
static void walkSymbols (RBinFile *bf, RBinNROObj *bin, ut64 symtab, ut64 strtab, ut64 strtab_size, ut64 relplt, ut64 baddr) {
	int i, import = 0;
	RBinSymbol *sym;
	RBinImport *imp;
	for (i = 8; i < 99999; i++) {
		ut64 addr = readLE64 (bf->buf, symtab + i);
		ut64 size = readLE64 (bf->buf, symtab + i + 8);
		i += 16; // NULL, NULL
		ut64 name = readLE32 (bf->buf, symtab + i);
		//ut64 type = readLE32 (bf->buf, symtab + i + 4);
		const char *symName = readString (bf->buf, strtab + name);
		if (!symName) {
			break;
		}
		sym = R_NEW0 (RBinSymbol);
		if (!sym) {
			break;
		}
		sym->type = r_str_const ("FUNC");
		sym->bind = r_str_const ("NONE");
		sym->size = size;

		if (addr == 0) {
			import ++;
			ut64 pltSym = readLE64 (bf->buf, relplt + (import * 24));
			imp = R_NEW0 (RBinImport);
			if (!imp) {
				R_FREE (sym);
				break;
			}
			imp->name  = strdup (symName);
			if (!imp->name) {
				goto out_walk_symbol;
			}
			imp->type = r_str_const ("FUNC");
			if (!imp->type) {
				goto out_walk_symbol;
			}
			imp->bind = r_str_const ("NONE");
			if (!imp->bind) {
				goto out_walk_symbol;
			}
			imp->ordinal = bin->imports_list->length;
			r_list_append (bin->imports_list, imp);
			sym->name = r_str_newf ("imp.%s", symName);
			if (!sym->name) {
				goto out_walk_symbol;
			}
			sym->paddr = pltSym - 8;
			sym->vaddr = sym->paddr + baddr;
			//eprintf ("f sym.imp.%s = 0x%"PFMT64x"\n", symName, pltSym - 8);
		} else {
			sym->name = strdup (symName);
			if (!sym->name) {
				R_FREE (sym);
				break;
			}
			sym->paddr = addr;
			sym->vaddr = sym->paddr + baddr;
			//eprintf ("f sym.%s %"PFMT64u "0x%"PFMT64x"\n", symName, size, addr);
		}
		r_list_append (bin->methods_list, sym);
		i += 8 - 1;
	}
    return;

out_walk_symbol:
	R_FREE (sym);
	R_FREE (imp);
	return;
}
示例#10
0
static ut64 baddr(RBinFile *bf) {
	return bf? readLE32 (bf->buf, NRO_OFFSET_MODMEMOFF): 0;
}
示例#11
0
static ut64 baddr(RBinFile *bf) {
	ut64 vaddr = (ut64)readLE32(bf->buf, 0x80);
	return vaddr;
}
示例#12
0
static void decode_fnt2(fnt_decoder *decoder) {
    ok_fnt *fnt = decoder->fnt;

    uint8_t header[4];
    if (!ok_read(decoder, header, sizeof(header))) {
        return;
    }
    if (memcmp("BMF", header, 3) != 0) {
        ok_fnt_error(fnt, "Not an AngelCode binary FNT file.");
        return;
    }
    if (header[3] != 3) {
        ok_fnt_error(fnt, "Version %i of AngelCode binary FNT file not supported (only version 3 supported).",
                     header[3]);
        return;
    }

    uint32_t block_types_found = 0;
    while (true) {

        uint8_t block_header[5];
        if (decoder->input_func(decoder->input_data, block_header, sizeof(block_header)) != sizeof(block_header)) {
            // Don't give an error if all required blocks have been found.
            const bool all_required_blocks_found = (block_types_found & 0x1E) == 0x1E;
            if (!all_required_blocks_found) {
                ok_fnt_error(decoder->fnt, "Read error: error calling input function.");
            }
            return;
        }

        block_type block_type = block_header[0];
        uint32_t block_length = readLE32(block_header + 1);

        block_types_found |= (1 << block_type);
        switch (block_type) {

        case BLOCK_TYPE_INFO: {
            uint8_t info_header[14];
            const int name_buffer_length = block_length - sizeof(info_header);
            if (name_buffer_length <= 0) {
                ok_fnt_error(fnt, "Invalid info block");
                return;
            }
            if (!ok_read(decoder, info_header, sizeof(info_header))) {
                return;
            }
            // Get the fnt size, ignore the rest
            fnt->size = readLE16(info_header);

            // Get the fnt name
            fnt->name = malloc(name_buffer_length);
            if (!fnt->name) {
                ok_fnt_error(fnt, "Couldn't allocate font name");
                return;
            }
            if (!ok_read(decoder, (uint8_t*)fnt->name, name_buffer_length)) {
                return;
            }
            // Sanity check - make sure the string has a null-terminator
            fnt->name[name_buffer_length - 1] = 0;
            break;
        }

        case BLOCK_TYPE_COMMON: {
            uint8_t common[15];
            if (block_length != sizeof(common)) {
                ok_fnt_error(fnt, "Invalid common block");
                return;
            }
            if (!ok_read(decoder, common, sizeof(common))) {
                return;
            }
            // Get the line height, base, and page count; ignore the rest
            fnt->line_height = readLE16(common);
            fnt->base = readLE16(common + 2);
            fnt->num_pages = readLE16(common + 8);
            break;
        }

        case BLOCK_TYPE_PAGES: {
            if (fnt->num_pages <= 0 || block_length == 0) {
                ok_fnt_error(fnt, "Couldn't get page names");
                return;
            }
            else {
                fnt->page_names = calloc(fnt->num_pages, sizeof(char *));
                if (!fnt->page_names) {
                    fnt->num_pages = 0;
                    ok_fnt_error(fnt, "Couldn't allocate memory for page name array");
                    return;
                }
                // Load everything into the first item; setup pointers below.
                fnt->page_names[0] = malloc(block_length);
                if (!fnt->page_names[0]) {
                    fnt->num_pages = 0;
                    ok_fnt_error(fnt, "Couldn't allocate memory for page names");
                    return;
                }
                if (!ok_read(decoder, (uint8_t*)fnt->page_names[0], block_length)) {
                    return;
                }
                char *pos = fnt->page_names[0];
                char * const end_pos = pos + block_length;
                // Sanity check - make sure there is a null terminator
                *(end_pos - 1) = 0;

                // Set up pointers for each page name
                int next_index = 1;
                while (pos + 1 < end_pos && next_index < fnt->num_pages) {
                    if (*pos == 0) {
                        fnt->page_names[next_index] = pos + 1;
                        next_index++;
                    }
                    pos++;
                }
                // Sanity check - make sure the remaining page names, if any, point somewhere
                for (int i = next_index; i < fnt->num_pages; i++) {
                    fnt->page_names[i] = end_pos - 1;
                }
            }
            break;
        }

        case BLOCK_TYPE_CHARS: {
            uint8_t data[20];
            fnt->num_glyphs = block_length / sizeof(data);
            fnt->glyphs = malloc(fnt->num_glyphs * sizeof(ok_fnt_glyph));
            if (!fnt->glyphs) {
                fnt->num_glyphs = 0;
                ok_fnt_error(fnt, "Couldn't allocate memory for glyphs");
                return;
            }
            // On little-endian systems we could just load the entire block into memory, but we'll assume
            // the byte order is unknown here.
            for (int i = 0; i < fnt->num_glyphs; i++) {
                if (!ok_read(decoder, data, sizeof(data))) {
                    return;
                }
                ok_fnt_glyph *glyph = &fnt->glyphs[i];
                glyph->ch = readLE32(data);
                glyph->x = readLE16(data + 4);
                glyph->y = readLE16(data + 6);
                glyph->width = readLE16(data + 8);
                glyph->height = readLE16(data + 10);
                glyph->offset_x = readLE16(data + 12);
                glyph->offset_y = readLE16(data + 14);
                glyph->advance_x = readLE16(data + 16);
                glyph->page = data[18];
                glyph->channel = data[19];
            }
            break;
        }

        case BLOCK_TYPE_KERNING: {
            uint8_t data[10];
            fnt->num_kerning_pairs = block_length / sizeof(data);
            fnt->kerning_pairs = malloc(fnt->num_kerning_pairs * sizeof(ok_fnt_kerning));
            if (!fnt->kerning_pairs) {
                fnt->num_kerning_pairs = 0;
                ok_fnt_error(fnt, "Couldn't allocate memory for kerning");
                return;
            }
            // On little-endian systems we could just load the entire block into memory, but we'll assume
            // the byte order is unknown here.
            for (int i = 0; i < fnt->num_kerning_pairs; i++) {
                if (!ok_read(decoder, data, sizeof(data))) {
                    return;
                }
                ok_fnt_kerning *kerning = &fnt->kerning_pairs[i];
                kerning->first_char = readLE32(data);
                kerning->second_char = readLE32(data + 4);
                kerning->amount = readLE16(data + 8);
            }
            break;
        }

        default:
            ok_fnt_error(fnt, "Unknown block type: %i", block_type);
            return;
        }
    }
}