Esempio n. 1
0
static struct mem_sym elf_sym(struct mem_ehdr *ehdr, const unsigned char *ptr)
{
	struct mem_sym sym = { };
	if (ehdr->ei_class == ELFCLASS32) {
		Elf32_Sym lsym;
		memcpy(&lsym, ptr, sizeof(lsym));
		sym.st_name  = elf32_to_cpu(ehdr, lsym.st_name);
		sym.st_value = elf32_to_cpu(ehdr, lsym.st_value);
		sym.st_size  = elf32_to_cpu(ehdr, lsym.st_size);
		sym.st_info  = lsym.st_info;
		sym.st_other = lsym.st_other;
		sym.st_shndx = elf16_to_cpu(ehdr, lsym.st_shndx);
	}
	else if (ehdr->ei_class == ELFCLASS64) {
		Elf64_Sym lsym;
		memcpy(&lsym, ptr, sizeof(lsym));
		sym.st_name  = elf32_to_cpu(ehdr, lsym.st_name);
		sym.st_value = elf64_to_cpu(ehdr, lsym.st_value);
		sym.st_size  = elf64_to_cpu(ehdr, lsym.st_size);
		sym.st_info  = lsym.st_info;
		sym.st_other = lsym.st_other;
		sym.st_shndx = elf16_to_cpu(ehdr, lsym.st_shndx);
	}
	else {
		die("Bad elf class");
	}
	return sym;
}
Esempio n. 2
0
static int elf_read_ehdr(const char *buf, size_t len, struct elfhdr *ehdr)
{
	struct elfhdr *buf_ehdr;

	if (len < sizeof(*buf_ehdr)) {
		pr_debug("Buffer is too small to hold ELF header.\n");
		return -ENOEXEC;
	}

	memset(ehdr, 0, sizeof(*ehdr));
	memcpy(ehdr->e_ident, buf, sizeof(ehdr->e_ident));
	if (!elf_is_elf_file(ehdr)) {
		pr_debug("No ELF header magic.\n");
		return -ENOEXEC;
	}

	if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) {
		pr_debug("Not a supported ELF class.\n");
		return -1;
	} else  if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB &&
		ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
		pr_debug("Not a supported ELF data format.\n");
		return -ENOEXEC;
	}

	buf_ehdr = (struct elfhdr *) buf;
	if (elf16_to_cpu(ehdr, buf_ehdr->e_ehsize) != sizeof(*buf_ehdr)) {
		pr_debug("Bad ELF header size.\n");
		return -ENOEXEC;
	}

	ehdr->e_type      = elf16_to_cpu(ehdr, buf_ehdr->e_type);
	ehdr->e_machine   = elf16_to_cpu(ehdr, buf_ehdr->e_machine);
	ehdr->e_version   = elf32_to_cpu(ehdr, buf_ehdr->e_version);
	ehdr->e_entry     = elf_addr_to_cpu(ehdr, buf_ehdr->e_entry);
	ehdr->e_phoff     = elf_addr_to_cpu(ehdr, buf_ehdr->e_phoff);
	ehdr->e_shoff     = elf_addr_to_cpu(ehdr, buf_ehdr->e_shoff);
	ehdr->e_flags     = elf32_to_cpu(ehdr, buf_ehdr->e_flags);
	ehdr->e_phentsize = elf16_to_cpu(ehdr, buf_ehdr->e_phentsize);
	ehdr->e_phnum     = elf16_to_cpu(ehdr, buf_ehdr->e_phnum);
	ehdr->e_shentsize = elf16_to_cpu(ehdr, buf_ehdr->e_shentsize);
	ehdr->e_shnum     = elf16_to_cpu(ehdr, buf_ehdr->e_shnum);
	ehdr->e_shstrndx  = elf16_to_cpu(ehdr, buf_ehdr->e_shstrndx);

	return elf_is_ehdr_sane(ehdr, len) ? 0 : -ENOEXEC;
}
static int build_mem_elf32_ehdr(const char *buf, off_t len, struct mem_ehdr *ehdr)
{
	Elf32_Ehdr lehdr;
	if (len < sizeof(lehdr)) {
		/* Buffer is to small to be an elf executable */
		if (probe_debug) {
			fprintf(stderr, "Buffer is to small to hold ELF header\n");
		}
		return -1;
	}
	memcpy(&lehdr, buf, sizeof(lehdr));
	if (elf16_to_cpu(ehdr, lehdr.e_ehsize) != sizeof(Elf32_Ehdr)) {
		/* Invalid Elf header size */
		if (probe_debug) {
			fprintf(stderr, "Bad ELF header size\n");
		}
		return -1;
	}
	if (elf32_to_cpu(ehdr, lehdr.e_entry) > UINT32_MAX) {
		/* entry is to large */
		if (probe_debug) {
			fprintf(stderr, "ELF e_entry to large\n");
		}
		return -1;
	}
	if (elf32_to_cpu(ehdr, lehdr.e_phoff) > UINT32_MAX) {
		/* phoff is to large */
		if (probe_debug) {
			fprintf(stderr, "ELF e_phoff to large\n");
		}
		return -1;
	}
	if (elf32_to_cpu(ehdr, lehdr.e_shoff) > UINT32_MAX) {
		/* shoff is to large */
		if (probe_debug) {
			fprintf(stderr, "ELF e_shoff to large\n");
		}
		return -1;
	}
	ehdr->e_type      = elf16_to_cpu(ehdr, lehdr.e_type);
	ehdr->e_machine   = elf16_to_cpu(ehdr, lehdr.e_machine);
	ehdr->e_version   = elf32_to_cpu(ehdr, lehdr.e_version);
	ehdr->e_entry     = elf32_to_cpu(ehdr, lehdr.e_entry);
	ehdr->e_phoff     = elf32_to_cpu(ehdr, lehdr.e_phoff);
	ehdr->e_shoff     = elf32_to_cpu(ehdr, lehdr.e_shoff);
	ehdr->e_flags     = elf32_to_cpu(ehdr, lehdr.e_flags);
	ehdr->e_phnum     = elf16_to_cpu(ehdr, lehdr.e_phnum);
	ehdr->e_shnum     = elf16_to_cpu(ehdr, lehdr.e_shnum);
	ehdr->e_shstrndx  = elf16_to_cpu(ehdr, lehdr.e_shstrndx);

	if ((ehdr->e_phnum > 0) &&
		(elf16_to_cpu(ehdr, lehdr.e_phentsize) != sizeof(Elf32_Phdr)))
	{
		/* Invalid program header size */
		if (probe_debug) {
			fprintf(stderr, "ELF bad program header size\n");
		}
		return -1;
	}
	if ((ehdr->e_shnum > 0) &&
		(elf16_to_cpu(ehdr, lehdr.e_shentsize) != sizeof(Elf32_Shdr)))
	{
		/* Invalid section header size */
		if (probe_debug) {
			fprintf(stderr, "ELF bad section header size\n");
		}
		return -1;
	}

	return 0;
}