Exemplo n.º 1
0
static int _decode64_symtab(AsmFormatPlugin * format, Elf64_Ehdr * ehdr,
		Elf64_Shdr * shdr, size_t shdr_cnt, uint16_t ndx)
{
	AsmFormatPluginHelper * helper = format->helper;
	char * strtab = NULL;
	size_t strtab_cnt = 0;
	Elf64_Sym sym;
	size_t i;
	off_t offset;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
	if(ndx >= shdr_cnt || shdr[ndx].sh_entsize != sizeof(sym))
		return -1;
	if(_decode64_strtab(format, shdr, shdr_cnt, shdr[ndx].sh_link, &strtab,
				&strtab_cnt) != 0)
		return -1;
	/* read and process symbols */
	if((offset = helper->seek(helper->format, shdr[ndx].sh_offset,
					SEEK_SET)) < 0
			|| (unsigned long)offset != shdr[ndx].sh_offset)
	{
		free(strtab);
		return -1;
	}
	for(i = 0; i * sizeof(sym) < shdr[ndx].sh_size; i++)
		if(helper->read(helper->format, &sym, sizeof(sym))
				!= sizeof(sym))
			break;
		else if(sym.st_name >= strtab_cnt)
			break;
		else if(ELF64_ST_TYPE(sym.st_info) == STT_FUNC)
		{
			offset = -1;
			if(ehdr->e_type == ET_REL || ehdr->e_type == ET_EXEC
					|| ehdr->e_type == ET_DYN)
				offset = sym.st_value;
			/* record the function */
			helper->set_function(helper->format, i,
					&strtab[sym.st_name], offset,
					sym.st_size);
		}
	if(i * sizeof(sym) != shdr[ndx].sh_size)
	{
		free(strtab);
		return -1;
	}
	return 0;
}
Exemplo n.º 2
0
static int _decode_map_method_id(AsmFormatPlugin * format, off_t offset,
		size_t size)
{
	AsmFormatPluginHelper * helper = format->helper;
	Dex * dex = format;
	ssize_t s;
	size_t i;
	AsmString * string;
	char const * name;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(%ld, %lu)\n", __func__, offset, size);
#endif
	if(dex->dmii != NULL)
		return 0; /* already parsed */
	if(helper->seek(helper->format, offset, SEEK_SET) != offset)
		return -1;
	s = sizeof(*dex->dmii) * size;
	if((dex->dmii = malloc(s)) == NULL)
		return -error_set_code(1, "%s", strerror(errno));
	if(helper->read(helper->format, dex->dmii, s) != s)
		return -1;
	for(i = 0; i < size; i++)
	{
		dex->dmii[i].class_idx = _htol16(dex->dmii[i].class_idx);
		dex->dmii[i].proto_idx = _htol16(dex->dmii[i].proto_idx);
		dex->dmii[i].name_idx = _htol32(dex->dmii[i].name_idx);
		if((string = helper->get_string_by_id(helper->format,
						dex->dmii[i].name_idx)) != NULL)
			name = string->name;
		else
			/* XXX report error? */
			name = NULL;
		helper->set_function(helper->format, i, name, -1, -1);
	}
	dex->dmii_cnt = size;
	return 0;
}
Exemplo n.º 3
0
/* dex_decode_section */
static int _dex_decode_section(AsmFormatPlugin * format, AsmSection * section,
		AsmArchInstructionCall ** calls, size_t * calls_cnt)
{
	AsmFormatPluginHelper * helper = format->helper;
	DexMapCodeItem dmci;
	size_t i;
	off_t seek;
	AsmFunction * f;
	size_t j;
	DexMapTryItem dmti;
	ssize_t s;
	uint32_t u32;
	int32_t s32;
	uint32_t v32;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
	if(helper->seek(helper->format, section->offset, SEEK_SET)
			!= section->offset)
		return -1;
	for(i = 0; i < section->size; i++)
	{
		s = sizeof(dmci);
		if(helper->read(helper->format, &dmci, s) != s)
			return -1;
		dmci.registers_size = _htol16(dmci.registers_size);
		dmci.ins_size = _htol16(dmci.ins_size);
		dmci.outs_size = _htol16(dmci.outs_size);
		dmci.tries_size = _htol16(dmci.tries_size);
		dmci.debug_info_off = _htol32(dmci.debug_info_off);
		dmci.insns_size = _htol32(dmci.insns_size);
		seek = helper->seek(helper->format, 0, SEEK_CUR);
		if(helper->decode(helper->format, seek, dmci.insns_size * 2,
					seek, calls, calls_cnt) != 0)
			return -1;
		/* update the corresponding function offset */
		if((f = helper->get_function_by_id(helper->format, i)) != NULL)
			/* XXX not very optimal */
			helper->set_function(helper->format, i, f->name, seek,
					dmci.insns_size * 2);
		/* skip padding and try_items */
		seek = (dmci.insns_size & 0x1) == 0x1 ? 2 : 0;
#ifdef DEBUG
		fprintf(stderr, "DEBUG: code item %lu/%lu, offset 0x%lx"
				", registers 0x%x, size 0x%x, debug @0x%x"
				", tries 0x%x, seek 0x%lx\n", i, section->size,
				helper->seek(helper->format, 0, SEEK_CUR),
				dmci.registers_size, dmci.insns_size,
				dmci.debug_info_off, dmci.tries_size, seek);
#endif
		if(seek != 0 && helper->seek(helper->format, seek, SEEK_CUR)
				< 0)
			return -1;
		if(dmci.tries_size > 0)
		{
			for(j = 0; j < dmci.tries_size; j++)
			{
				s = sizeof(dmti);
				if(helper->read(helper->format, &dmti, s) != s)
					return -1;
				dmti.start_addr = _htol32(dmti.start_addr);
				dmti.insn_count = _htol16(dmti.insn_count);
				dmti.handler_off = _htol16(dmti.handler_off);
#ifdef DEBUG
				fprintf(stderr, "DEBUG: start 0x%x,"
						" insn_count 0x%x,"
						" handler_off 0x%x\n",
						dmti.start_addr,
						dmti.insn_count,
						dmti.handler_off);
#endif
			}
			/* encoded catch handler */
			/* list size */
			if(_dex_decode_uleb128(format, &u32) != 0)
				return -1;
			for(; u32 > 0; u32--)
			{
				/* handler size */
				if(_dex_decode_sleb128(format, &s32) != 0)
					return -1;
				/* address pairs */
				for(j = abs(s32); j > 0; j--)
				{
					if(_dex_decode_uleb128(format, &v32)
							!= 0)
						return -1;
					if(_dex_decode_uleb128(format, &v32)
							!= 0)
						return -1;
				}
				/* catch-all address */
				if(s32 <= 0 && _dex_decode_uleb128(format, &v32)
						!= 0)
					return -1;
			}
			/* ensure alignment on 4 bytes */
			seek = helper->seek(helper->format, 0, SEEK_CUR);
			if((seek = (4 - (seek & 0x3)) & 0x3) != 0)
				helper->seek(helper->format, seek, SEEK_CUR);
		}
	}
	return 0;
}