📄 readelf.c
字号:
} else if (desc / 10 % 10 > 0) { if (file_printf(ms, ".%d", desc / 10 % 10) == -1) return size; } } else { if (file_printf(ms, " %d.%d", desc / 100000, desc / 1000 % 100) == -1) return size; if ((desc / 100 % 10 > 0) || (desc % 100000 / 100 == 0)) { if (file_printf(ms, " (%d)", desc) == -1) return size; } else if (desc / 10 % 10 > 0) { if (file_printf(ms, ".%d", desc / 10 % 10) == -1) return size; } } *flags |= FLAGS_DID_NOTE; return size; } if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 && xnh_type == NT_OPENBSD_VERSION && descsz == 4) { if (file_printf(ms, ", for OpenBSD") == -1) return size; /* Content of note is always 0 */ *flags |= FLAGS_DID_NOTE; return size; } if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 && xnh_type == NT_DRAGONFLY_VERSION && descsz == 4) { uint32_t desc; if (file_printf(ms, ", for DragonFly") == -1) return size; (void)memcpy(&desc, &nbuf[doff], sizeof(desc)); desc = getu32(swap, desc); if (file_printf(ms, " %d.%d.%d", desc / 100000, desc / 10000 % 10, desc % 10000) == -1) return size; *flags |= FLAGS_DID_NOTE; return size; }core: /* * Sigh. The 2.0.36 kernel in Debian 2.1, at * least, doesn't correctly implement name * sections, in core dumps, as specified by * the "Program Linking" section of "UNIX(R) System * V Release 4 Programmer's Guide: ANSI C and * Programming Support Tools", because my copy * clearly says "The first 'namesz' bytes in 'name' * contain a *null-terminated* [emphasis mine] * character representation of the entry's owner * or originator", but the 2.0.36 kernel code * doesn't include the terminating null in the * name.... */ if ((namesz == 4 && strncmp((char *)&nbuf[noff], "CORE", 4) == 0) || (namesz == 5 && strcmp((char *)&nbuf[noff], "CORE") == 0)) { os_style = OS_STYLE_SVR4; } if ((namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0)) { os_style = OS_STYLE_FREEBSD; } if ((namesz >= 11 && strncmp((char *)&nbuf[noff], "NetBSD-CORE", 11) == 0)) { os_style = OS_STYLE_NETBSD; }#ifdef ELFCORE if ((*flags & FLAGS_DID_CORE) != 0) return size; if (os_style != -1) { if (file_printf(ms, ", %s-style", os_style_names[os_style]) == -1) return size; } switch (os_style) { case OS_STYLE_NETBSD: if (xnh_type == NT_NETBSD_CORE_PROCINFO) { uint32_t signo; /* * Extract the program name. It is at * offset 0x7c, and is up to 32-bytes, * including the terminating NUL. */ if (file_printf(ms, ", from '%.31s'", &nbuf[doff + 0x7c]) == -1) return size; /* * Extract the signal number. It is at * offset 0x08. */ (void)memcpy(&signo, &nbuf[doff + 0x08], sizeof(signo)); if (file_printf(ms, " (signal %u)", getu32(swap, signo)) == -1) return size; return size; } break; default: if (xnh_type == NT_PRPSINFO) { size_t i, j; unsigned char c; /* * Extract the program name. We assume * it to be 16 characters (that's what it * is in SunOS 5.x and Linux). * * Unfortunately, it's at a different offset * in varous OSes, so try multiple offsets. * If the characters aren't all printable, * reject it. */ for (i = 0; i < NOFFSETS; i++) { size_t reloffset = prpsoffsets(i); size_t noffset = doff + reloffset; for (j = 0; j < 16; j++, noffset++, reloffset++) { /* * Make sure we're not past * the end of the buffer; if * we are, just give up. */ if (noffset >= size) goto tryanother; /* * Make sure we're not past * the end of the contents; * if we are, this obviously * isn't the right offset. */ if (reloffset >= descsz) goto tryanother; c = nbuf[noffset]; if (c == '\0') { /* * A '\0' at the * beginning is * obviously wrong. * Any other '\0' * means we're done. */ if (j == 0) goto tryanother; else break; } else { /* * A nonprintable * character is also * wrong. */ if (!isprint(c) || isquote(c)) goto tryanother; } } /* * Well, that worked. */ if (file_printf(ms, ", from '%.16s'", &nbuf[doff + prpsoffsets(i)]) == -1) return size; return size; tryanother: ; } } break; }#endif *flags |= FLAGS_DID_CORE; return offset;}private intdoshn(struct magic_set *ms, int class, int swap, int fd, off_t off, int num, size_t size, int *flags){ Elf32_Shdr sh32; Elf64_Shdr sh64; int stripped = 1; void *nbuf; off_t noff; if (size != xsh_sizeof) { if (file_printf(ms, ", corrupted section header size") == -1) return -1; return 0; } if (lseek(fd, off, SEEK_SET) == (off_t)-1) { file_badseek(ms); return -1; } for ( ; num; num--) { if (read(fd, xsh_addr, xsh_sizeof) == -1) { file_badread(ms); return -1; } switch (xsh_type) { case SHT_SYMTAB:#if 0 case SHT_DYNSYM:#endif stripped = 0; break; case SHT_NOTE: if ((off = lseek(fd, (off_t)0, SEEK_CUR)) == (off_t)-1) { file_badread(ms); return -1; } if ((nbuf = malloc((size_t)xsh_size)) == NULL) { file_error(ms, errno, "Cannot allocate memory" " for note"); return -1; } if ((noff = lseek(fd, (off_t)xsh_offset, SEEK_SET)) == (off_t)-1) { file_badread(ms); free(nbuf); return -1; } if (read(fd, nbuf, (size_t)xsh_size) != (ssize_t)xsh_size) { free(nbuf); file_badread(ms); return -1; } noff = 0; for (;;) { if (noff >= (size_t)xsh_size) break; noff = donote(ms, nbuf, (size_t)noff, (size_t)xsh_size, class, swap, 4, flags); if (noff == 0) break; } if ((lseek(fd, off, SEEK_SET)) == (off_t)-1) { free(nbuf); file_badread(ms); return -1; } free(nbuf); break; } } if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1) return -1; return 0;}/* * Look through the program headers of an executable image, searching * for a PT_INTERP section; if one is found, it's dynamically linked, * otherwise it's statically linked. */private intdophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off, int num, size_t size, off_t fsize, int *flags){ Elf32_Phdr ph32; Elf64_Phdr ph64; const char *linking_style = "statically"; const char *shared_libraries = ""; unsigned char nbuf[BUFSIZ]; int bufsize; size_t offset, align; off_t savedoffset = (off_t)-1; struct stat st; if (fstat(fd, &st) < 0) { file_badread(ms); return -1; } if (size != xph_sizeof) { if (file_printf(ms, ", corrupted program header size") == -1) return -1; return 0; } if (lseek(fd, off, SEEK_SET) == (off_t)-1) { file_badseek(ms); return -1; } for ( ; num; num--) { if (read(fd, xph_addr, xph_sizeof) == -1) { file_badread(ms); return -1; } if (xph_offset > st.st_size && savedoffset != (off_t)-1) { if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) { file_badseek(ms); return -1; } continue; } if ((savedoffset = lseek(fd, (off_t)0, SEEK_CUR)) == (off_t)-1) { file_badseek(ms); return -1; } if (xph_offset > fsize) { if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) { file_badseek(ms); return -1; } continue; } switch (xph_type) { case PT_DYNAMIC: linking_style = "dynamically"; break; case PT_INTERP: shared_libraries = " (uses shared libs)"; break; case PT_NOTE: if ((align = xph_align) & 0x80000000) { if (file_printf(ms, ", invalid note alignment 0x%lx", (unsigned long)align) == -1) return -1; align = 4; } /* * This is a PT_NOTE section; loop through all the notes * in the section. */ if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) { file_badseek(ms); return -1; } bufsize = read(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf))); if (bufsize == -1) { file_badread(ms); return -1; } offset = 0; for (;;) { if (offset >= (size_t)bufsize) break; offset = donote(ms, nbuf, offset, (size_t)bufsize, class, swap, align, flags); if (offset == 0) break; } if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) { file_badseek(ms); return -1; } break; } } if (file_printf(ms, ", %s linked%s", linking_style, shared_libraries) == -1) return -1; return 0;}protected intfile_tryelf(struct magic_set *ms, int fd, const unsigned char *buf, size_t nbytes){ union { int32_t l; char c[sizeof (int32_t)]; } u; int class; int swap; struct stat st; off_t fsize; int flags = 0; /* * If we cannot seek, it must be a pipe, socket or fifo. */ if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE)) fd = file_pipe2file(ms, fd, buf, nbytes); if (fstat(fd, &st) == -1) { file_badread(ms); return -1; } fsize = st.st_size; /* * ELF executables have multiple section headers in arbitrary * file locations and thus file(1) cannot determine it from easily. * Instead we traverse thru all section headers until a symbol table * one is found or else the binary is stripped. */ if (buf[EI_MAG0] != ELFMAG0 || (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1) || buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3) return 0; class = buf[EI_CLASS]; if (class == ELFCLASS32) { Elf32_Ehdr elfhdr; if (nbytes <= sizeof (Elf32_Ehdr)) return 0; u.l = 1; (void) memcpy(&elfhdr, buf, sizeof elfhdr); swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA]; if (getu16(swap, elfhdr.e_type) == ET_CORE) {#ifdef ELFCORE if (dophn_core(ms, class, swap, fd, (off_t)getu32(swap, elfhdr.e_phoff), getu16(swap, elfhdr.e_phnum), (size_t)getu16(swap, elfhdr.e_phentsize), fsize, &flags) == -1) return -1;#else ;#endif } else { if (getu16(swap, elfhdr.e_type) == ET_EXEC) { if (dophn_exec(ms, class, swap, fd, (off_t)getu32(swap, elfhdr.e_phoff), getu16(swap, elfhdr.e_phnum), (size_t)getu16(swap, elfhdr.e_phentsize), fsize, &flags) == -1) return -1; } if (doshn(ms, class, swap, fd, (off_t)getu32(swap, elfhdr.e_shoff), getu16(swap, elfhdr.e_shnum), (size_t)getu16(swap, elfhdr.e_shentsize), &flags) == -1) return -1; } return 1; } if (class == ELFCLASS64) { Elf64_Ehdr elfhdr; if (nbytes <= sizeof (Elf64_Ehdr)) return 0; u.l = 1; (void) memcpy(&elfhdr, buf, sizeof elfhdr); swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA]; if (getu16(swap, elfhdr.e_type) == ET_CORE) {#ifdef ELFCORE if (dophn_core(ms, class, swap, fd, (off_t)elf_getu64(swap, elfhdr.e_phoff), getu16(swap, elfhdr.e_phnum), (size_t)getu16(swap, elfhdr.e_phentsize), fsize, &flags) == -1) return -1;#else ;#endif } else { if (getu16(swap, elfhdr.e_type) == ET_EXEC) { if (dophn_exec(ms, class, swap, fd, (off_t)elf_getu64(swap, elfhdr.e_phoff), getu16(swap, elfhdr.e_phnum), (size_t)getu16(swap, elfhdr.e_phentsize), fsize, &flags) == -1) return -1; } if (doshn(ms, class, swap, fd, (off_t)elf_getu64(swap, elfhdr.e_shoff), getu16(swap, elfhdr.e_shnum), (size_t)getu16(swap, elfhdr.e_shentsize), &flags) == -1) return -1; } return 1; } return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -