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; }
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; }