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

📄 elfls.c

📁 ELFkickers是一组elf工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* elfls: Copyright (C) 1999-2001 by Brian Raiter, under the GNU * General Public License. No warranty. See COPYING for details. */#include	<stdio.h>#include	<stdlib.h>#include	<errno.h>#include	<stdarg.h>#include	<unistd.h>#include	<getopt.h>#include	<elf.h>#ifndef TRUE#define	TRUE		1#define	FALSE		0#endif/* Memory allocation error message. */#define	nomem()		(fputs("Out of memory!\n", stderr), exit(EXIT_FAILURE))/* Structure used to organize strings to be displayed in a list. */typedef	struct textline {    char       *str;		/* the string to display		*/    int		size;		/* the current length of the string	*/    int		left;		/* how much more the string can grow	*/} textline;/* The online help text. */static char const      *yowzitch = 	"Usage: elfls [-hvEcdPSip] [-w N] FILE...\n"	"   -h  Display this help\n"	"   -v  Display version information\n"	"   -c  Include source file display\n"	"   -d  Include dependencies display\n"	"   -P  Suppress program header table display\n"	"   -S  Suppress section header table display\n"	"   -E  Skip ELF identifier verification\n"	"   -i  Don't display some contents\n"	"   -p  Don't display file positions\n"	"   -w  Set maximum width of output\n";/* The version text. */static char const      *vourzhon =	"elfls, v1.0.0.0.0.0.0.0.0.0: Copyright (C) 1999 by Brian Raiter.\n";/* * Global variables */static Elf32_Ehdr	elffhdr;	/* ELF header of current file	*/static Elf32_Phdr      *proghdr = NULL;	/* program header table		*/static Elf32_Shdr      *secthdr = NULL;	/* section header table		*/static char	       *sectstr = NULL;	/* sh string table		*/static int		proghdrs;	/* FALSE if no ph table		*/static int		secthdrs;	/* FALSE if no sh table		*/static Elf32_Phdr      *phentry = NULL;	/* ph with the entry point	*/static Elf32_Shdr      *shshstr = NULL;	/* sh with the sh string table	*/static char const      *thisprog;	/* name of this program		*/static char const      *thefilename;	/* name of current file		*/static FILE	       *thefile;	/* handle to current file	*/static int		skipID = FALSE;	/* TRUE = skip ID check		*/static int		phdrls = TRUE;	/* TRUE = show ph table		*/static int		shdrls = TRUE;	/* TRUE = show sh table		*/static int		srcfls = FALSE;	/* TRUE = show source files	*/static int		ldepls = FALSE;	/* TRUE = show libraries	*/static int		dostrs = TRUE;	/* TRUE = show entry strings	*/static int		dooffs = TRUE;	/* TRUE = show file offsets	*/static int		outwidth;	/* maximum width of output	*//* * List output formatting functions. *//* Allocate a textline array, including one initialized string for * each element. */static textline *gettextlines(int count){    char       *text;    textline   *lines;    int		width;    int		i;    width = outwidth ? outwidth : 256;    if (!(lines = malloc(count * (sizeof *lines + width))))	nomem();    text = (char*)(lines + count);    for (i = 0 ; i < count ; ++i) {	lines[i].str = text;	lines[i].str[0] = '\0';	lines[i].size = 0;	lines[i].left = width - 1;	text += width;    }    return lines;}/* Concatenate formatted text to the given textline string. */static int append(textline *line, char const *fmt, ...){    va_list	args;    int		n;    if (line->left <= 0)	return 0;    va_start(args, fmt);    n = vsnprintf(line->str + line->size, line->left, fmt, args);    va_end(args);    if (n < 0) {	line->size += line->left;	line->left = 0;    } else {	line->size += n;	line->left -= n;    }    return line->left;}/* Function to pass to qsort(). */static int linesorter(const void *i1, const void *i2){    return strcmp(((textline*)i1)->str, ((textline*)i2)->str);}/* Output the given textline array strings to a stream, nicely * formatted in columns, somewhat in the style of ls. */static void formatlist(FILE *fp, textline *lines, int count){    textline   *line;    int		colx, dy;    int		i, j;    colx = 0;    for (i = 0, line = lines ; i < count ; ++i, ++line) {	if (line->size > colx)	    colx = line->size;    }    if (outwidth) {	i = (outwidth - 1) / colx;	dy = (count + i - 1) / i;	colx = -(colx + 1);    } else {	dy = count;	colx = 0;    }    for (j = 0 ; j < dy ; ++j) {	for (i = j ; i < count - dy ; i += dy)	    fprintf(fp, "%*s", colx, lines[i].str);	fprintf(fp, "%s\n", lines[i].str);    }}/* Output the given list and its header text on one line. If it * won't fit on one line, then use formatlist() instead. */static void outputlist(FILE *fp, textline *lines, int count,		       char const *header){    int maxwidth;    int	i, n;    if (!count)	return;    fputs(header, fp);    if (outwidth) {	maxwidth = outwidth - strlen(header);	for (i = n = 0 ; i < count ; ++i) {	    if ((n += lines[i].size + 1) >= maxwidth) {		fputc('\n', fp);		formatlist(fp, lines, count);		return;	    }	}    }    fputs(lines[0].str, fp);    for (i = 1 ; i < count ; ++i) {	fputc(' ', fp);	fputs(lines[i].str, fp);    }    fputc('\n', fp);}/* * Generic file-reading functions. *//* Read a piece of the current file into a freshly allocated buffer. */static void *getarea(long offset, unsigned long size){    void       *buf;    if (fseek(thefile, offset, SEEK_SET))	return NULL;    if (!(buf = malloc(size)))	nomem();    if (fread(buf, size, 1, thefile) != 1) {	free(buf);	return NULL;    }    return buf;}/* Read a null-terminated string from the current file, up to a given * size, into a static buffer. If skip is nonzero, then skip over NULs * at the beginning of the string. */static char const *getstring(unsigned long offset, unsigned long size,			     int skip){    static char	       *buf = NULL;    static size_t	buflen = 0;    char	       *str;    int			n;    if (!size)	return "";    if (size > buflen) {	if (!(buf = realloc(buf, size + 1)))	    nomem();	buflen = size;    }    if (fseek(thefile, offset, SEEK_SET))	return "";    if (skip) {	if ((n = fread(buf, 1, size, thefile)) <= 0)	    return "";	for (str = buf ; !*str && n ; ++str, --n) ;    } else {	if (!fgets(buf, size, thefile))	    return "";	n = size;	str = buf;    }    if (!n)	return "";    str[n] = '\0';    for (n = 0 ; str[n] ; ++n)	if (str[n] < ' ' || str[n] > '~')	    str[n] = '.';    return str;}/* * Functions for examining ELF structures. *//* Verify that the given ELF identifier is appropriate to our * expectations. */static int checkelfident(char const id[EI_NIDENT]){    int	bigendian;    if (id[EI_MAG0] != ELFMAG0 || id[EI_MAG1] != ELFMAG1			       || id[EI_MAG2] != ELFMAG2			       || id[EI_MAG3] != ELFMAG3) {	fprintf(stderr, "%s: not an ELF file.\n", thefilename);	return FALSE;    }    if (skipID)	return TRUE;    if (id[EI_CLASS] != ELFCLASS32) {	fprintf(stderr, "%s: not a 32-bit ELF file "			"(class = %d instead of %d).\n",			thefilename, (int)(unsigned char)id[EI_CLASS],			ELFCLASS32);	return FALSE;    }    bigendian = TRUE;    *(char*)&bigendian = 0;    if (id[EI_DATA] != (bigendian ? ELFDATA2MSB : ELFDATA2LSB)) {	fprintf(stderr, "%s: not %s-endian "			"(data = %d instead of %d).\n",			thefilename, (bigendian ? "big" : "little"),			(int)(unsigned char)id[EI_DATA],			(bigendian ? ELFDATA2MSB : ELFDATA2LSB));	return FALSE;    }    if (id[EI_VERSION] != EV_CURRENT) {	fprintf(stderr, "%s: unknown ELF version "			"(version = %d instead of %d).\n",			thefilename, (int)(unsigned char)id[EI_VERSION],			EV_CURRENT);	return FALSE;    }    return TRUE;}/* Read in the ELF header proper, and verify that its contents conform * to what the program can decipher. */static int readelfhdr(void){    errno = 0;    if (fread(&elffhdr, sizeof elffhdr, 1, thefile) != 1) {	if (errno)	    perror(thefilename);	else	    fprintf(stderr, "%s: not an ELF file.\n", thefilename);	return FALSE;    }    if (!checkelfident(elffhdr.e_ident))	return FALSE;    switch (elffhdr.e_type) {      case ET_REL:      case ET_EXEC:      case ET_DYN:	return TRUE;      default:	fprintf(stderr, "%s: unknown ELF file type (type = %u).\n",			thefilename, elffhdr.e_type);	return FALSE;    }    if (elffhdr.e_version != EV_CURRENT) {	fprintf(stderr, "%s: unknown ELF header version "			"(version = %u instead of %u).\n",			thefilename, (unsigned int)elffhdr.e_version,			(unsigned int)EV_CURRENT);	return FALSE;    }    if (elffhdr.e_ehsize != sizeof elffhdr)	fprintf(stderr, "%s: warning: unrecognized ELF header size "			"(size = %u instead of %u).\n",			thefilename, elffhdr.e_ehsize, sizeof elffhdr);    return TRUE;}/* Read in the program header table, if it is present. If the ELF * header lists an entry point, then compare the entry point with the * load address of the program header entries to determine which one * contains said point. */static int readproghdrs(void){    char       *buf;    size_t	n;    if (!(proghdrs = elffhdr.e_phoff != 0))	return TRUE;    n = elffhdr.e_phnum * elffhdr.e_phentsize;    if (!(buf = getarea(elffhdr.e_phoff, n))) {	fprintf(stderr, "%s: warning: invalid program header table offset.\n",			thefilename);	proghdrs = FALSE;	return TRUE;    }    if (elffhdr.e_phentsize == sizeof *proghdr)	proghdr = (Elf32_Phdr*)buf;    else {	fprintf(stderr, "%s: warning: unrecognized program header entry size "			"(size = %u instead of %u).\n",			thefilename, elffhdr.e_phentsize, sizeof *proghdr);	if (!(proghdr = calloc(elffhdr.e_phnum, sizeof *proghdr)))	    nomem();	for (n = 0 ; n < elffhdr.e_phnum ; ++n) 	    memcpy(proghdr + n, buf + n * elffhdr.e_phentsize,				sizeof *proghdr);	free(buf);    }    if (elffhdr.e_entry) {	for (n = 0 ; n < elffhdr.e_phnum ; ++n) {	    if (proghdr[n].p_type == PT_LOAD			&& elffhdr.e_entry >= proghdr[n].p_vaddr			&& elffhdr.e_entry < proghdr[n].p_vaddr						 + proghdr[n].p_memsz) {		phentry = proghdr + n;		break;	    }	}    }    return TRUE;}/* Read in the section header table, if it is present. If a section * header string table is given in the ELF header, then also load the * string table contents. */static int readsecthdrs(void){    char       *buf;    size_t	n;    if (!(secthdrs = elffhdr.e_shoff != 0))	return TRUE;    n = elffhdr.e_shnum * elffhdr.e_shentsize;    if (!(buf = getarea(elffhdr.e_shoff, n))) {	fprintf(stderr, "%s: warning: invalid section header table offset.\n",			thefilename);	secthdrs = FALSE;	return TRUE;    }    if (elffhdr.e_shentsize == sizeof *secthdr)	secthdr = (Elf32_Shdr*)buf;    else {	fprintf(stderr, "%s: warning: unrecognized section header entry size "			"(size = %u instead of %u).\n",			thefilename, elffhdr.e_shentsize, sizeof *secthdr);	if (!(secthdr = calloc(elffhdr.e_shnum, sizeof *secthdr)))	    nomem();	for (n = 0 ; n < elffhdr.e_shnum ; ++n) 	    memcpy(secthdr + n, buf + n * elffhdr.e_shentsize,				sizeof *secthdr);    }    if (elffhdr.e_shstrndx != SHN_UNDEF) {	shshstr = secthdr + elffhdr.e_shstrndx;	if (!(sectstr = getarea(shshstr->sh_offset, shshstr->sh_size))) {	    fprintf(stderr, "%s: warning: invalid string table location.\n",			    thefilename);	    free(sectstr);	    sectstr = NULL;	}    }    return TRUE;}/* Extract the list of source files, if present. The source files are * determined by loading the symbol table section (and its associated

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -