⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readelf.c

📁 sleuthit-2.09 一个磁盘的工具集
💻 C
📖 第 1 页 / 共 2 页
字号:
			} 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 + -