Ejemplo n.º 1
0
static int _exit_32_phdr(AsmFormatPlugin * format, Elf32_Off offset)
{
	AsmFormatPluginHelper * helper = format->helper;
	Elf * elf = format->priv;
	ElfArch * ea = elf->arch;
	Elf32_Ehdr hdr;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
	if(elf->es32_cnt == 0)
		return 0;
	if(helper->seek(helper->format, 0, SEEK_SET) != 0)
		return -1;
	if(helper->read(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
		return _elf_error(format);
	if(ea->endian == ELFDATA2MSB)
	{
		hdr.e_shoff = _htob32(offset);
		hdr.e_shnum = _htob16(elf->es32_cnt + 1);
		hdr.e_shstrndx = _htob16(elf->es32_cnt);
	}
	else
	{
		hdr.e_shoff = _htol32(offset);
		hdr.e_shnum = _htol16(elf->es32_cnt + 1);
		hdr.e_shstrndx = _htol16(elf->es32_cnt);
	}
	if(helper->seek(helper->format, 0, SEEK_SET) != 0)
		return -1;
	if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
		return -1;
	return 0;
}
Ejemplo n.º 2
0
static int _exit_64_phdr(AsmFormatPlugin * format, Elf64_Off offset)
{
	AsmFormatPluginHelper * helper = format->helper;
	Elf * elf = format->priv;
	ElfArch * ea = elf->arch;
	Elf64_Ehdr hdr;

	if(elf->es64_cnt == 0)
		return 0;
	if(helper->seek(helper->format, 0, SEEK_SET) != 0)
		return -1;
	if(helper->read(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
		return -1;
	if(ea->endian == ELFDATA2MSB)
	{
		hdr.e_shoff = _htob64(offset);
		hdr.e_shnum = _htob16(elf->es64_cnt);
		hdr.e_shstrndx = _htob16(elf->es64_cnt - 1);
	}
	else
	{
		hdr.e_shoff = _htol64(offset);
		hdr.e_shnum = _htol16(elf->es64_cnt);
		hdr.e_shstrndx = _htol16(elf->es64_cnt - 1);
	}
	if(helper->seek(helper->format, 0, SEEK_SET) != 0)
		return -1;
	if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
		return -1;
	return 0;
}
Ejemplo n.º 3
0
static int _decode_map(AsmFormatPlugin * format, DexHeader * dh, int raw)
{
	int ret = 0;
	AsmFormatPluginHelper * helper = format->helper;
	uint32_t size;
	uint32_t i;
	off_t offset;
	DexMapItem dmi;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
	if(helper->seek(helper->format, dh->map_off, SEEK_SET) != dh->map_off)
		return -1;
	if(helper->read(helper->format, &size, sizeof(size)) != sizeof(size))
		return -1;
	size = _htol32(size);
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s() %u items\n", __func__, size);
#endif
	for(i = 0; i < size; i++)
	{
		if(helper->read(helper->format, &dmi, sizeof(dmi))
				!= sizeof(dmi))
			return -1;
		offset = helper->seek(helper->format, 0, SEEK_CUR);
		dmi.type = _htol16(dmi.type);
		dmi.size = _htol32(dmi.size);
		dmi.offset = _htol32(dmi.offset);
#ifdef DEBUG
		fprintf(stderr, "DEBUG: item %u, type 0x%x, size 0x%x@0x%x\n",
				i, dmi.type, dmi.size, dmi.offset);
#endif
		switch(dmi.type)
		{
			case TYPE_CODE_ITEM:
				ret |= _decode_map_code(format, i, dmi.offset,
						dmi.size);
				break;
			case TYPE_METHOD_ID_ITEM:
				ret |= _decode_map_method_id(format, dmi.offset,
						dmi.size);
				break;
			case TYPE_STRING_ID_ITEM:
				ret |= _decode_map_string_id(format, dmi.offset,
						dmi.size);
				break;
		}
		if(helper->seek(helper->format, offset, SEEK_SET) != offset)
			return -1;
		if(ret != 0)
			break;
	}
	return ret;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
/* init_32 */
static int _init_32(AsmFormatPlugin * format)
{
	AsmFormatPluginHelper * helper = format->helper;
	Elf * elf = format->priv;
	ElfArch * ea = elf->arch;
	Elf32_Ehdr hdr;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
	memset(&hdr, 0, sizeof(hdr));
	memcpy(&hdr.e_ident, ELFMAG, SELFMAG);
	hdr.e_ident[EI_CLASS] = ELFCLASS32;
	hdr.e_ident[EI_DATA] = ea->endian;
	hdr.e_ident[EI_VERSION] = EV_CURRENT;
	if(ea->endian == ELFDATA2MSB)
	{
		hdr.e_type = _htob16(ET_REL);
		hdr.e_machine = _htob16(ea->machine);
		hdr.e_version = _htob32(EV_CURRENT);
		hdr.e_ehsize = _htob16(sizeof(hdr));
		hdr.e_shentsize = _htob16(sizeof(Elf32_Shdr));
		hdr.e_shstrndx = _htob16(SHN_UNDEF);
	}
	else
	{
		hdr.e_type = _htol16(ET_REL);
		hdr.e_machine = _htol16(ea->machine);
		hdr.e_version = _htol32(EV_CURRENT);
		hdr.e_ehsize = _htol16(sizeof(hdr));
		hdr.e_shentsize = _htol16(sizeof(Elf32_Shdr));
		hdr.e_shstrndx = _htol16(SHN_UNDEF);
	}
	if(helper->write(helper->format, &hdr, sizeof(hdr)) != sizeof(hdr))
		return _elf_error(format);
	return 0;
}
Ejemplo n.º 6
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;
}