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

📄 elfls.c

📁 ELFkickers是一组elf工具
💻 C
📖 第 1 页 / 共 2 页
字号:
 * string table) and looking up symbols of type STT_FILE. */static int getsrcfiles(textline **plines){    Elf32_Sym  *syms;    char       *nmstr;    textline   *lines;    char       *str;    unsigned	strtab, count, i;    int		j, n;    if (!secthdrs)	return 0;    for (i = 0 ; i < elffhdr.e_shnum ; ++i)	if (secthdr[i].sh_type == SHT_SYMTAB)	    break;    if (i == elffhdr.e_shnum)	return 0;    if (!(syms = getarea(secthdr[i].sh_offset, secthdr[i].sh_size)))	return 0;    strtab = secthdr[i].sh_link;    if (!(nmstr = getarea(secthdr[strtab].sh_offset, secthdr[strtab].sh_size)))	return 0;    count = secthdr[i].sh_size / sizeof *syms;    lines = gettextlines(count);    n = 0;    for (i = 0 ; i < count ; ++i) {	if (ELF32_ST_TYPE(syms[i].st_info) != STT_FILE)	    continue;	str = nmstr + syms[i].st_name;	for (j = 0 ; j < n ; ++j)	    if (!strcmp(lines[j].str, str))		break;	if (j == n)	    append(lines + n++, "%s", str);    }    free(syms);    free(nmstr);    if (n)	*plines = lines;    else	free(lines);    return n;}/* Extract the list of dependencies, if present. The program header * table entry of type PT_DYNAMIC contains the dynamic info, which * includes the dependent files, and the string table that contains * the file names. However, the string table is referenced by its * location in memory, as opposed to its location in the file, so * the program header table needs to be searched again to find the * part that will be loaded at that location. */static int getlibraries(textline **plines){    Elf32_Dyn  *dyns;    char       *nmstr;    textline   *lines;    char       *str;    unsigned	strtab = 0, strsz = 0, count, i, j, n;    if (!proghdrs)	return 0;    for (i = 0 ; i < elffhdr.e_phnum ; ++i)	if (proghdr[i].p_type == PT_DYNAMIC)	    break;    if (i == elffhdr.e_phnum)	return 0;    if (!(dyns = getarea(proghdr[i].p_offset, proghdr[i].p_filesz)))	return 0;    count = proghdr[i].p_filesz / sizeof *dyns;    n = 0;    for (i = 0 ; i < count ; ++i) {	if (dyns[i].d_tag == DT_STRTAB)	    strtab = dyns[i].d_un.d_ptr;	else if (dyns[i].d_tag == DT_STRSZ)	    strsz = dyns[i].d_un.d_val;	else if (dyns[i].d_tag == DT_NEEDED)	    ++n;    }    if (!strtab || !strsz)	return 0;    for (i = 0 ; i < elffhdr.e_phnum ; ++i)	if (strtab >= proghdr[i].p_vaddr		&& strtab < proghdr[i].p_vaddr + proghdr[i].p_filesz)	    break;    if (i == elffhdr.e_phnum)	return 0;    if (!(nmstr = getarea(proghdr[i].p_offset + (strtab - proghdr[i].p_vaddr),			  strsz)))	return 0;    lines = gettextlines(n);    n = 0;    for (i = 0 ; i < count ; ++i) {	if (dyns[i].d_tag != DT_NEEDED)	    continue;	str = nmstr + dyns[i].d_un.d_val;	for (j = 0 ; j < n ; ++j)	    if (!strcmp(lines[j].str, str))		break;	if (j == n)	    append(lines + n++, "%s", str);    }    free(dyns);    free(nmstr);    if (n)	*plines = lines;    else	free(lines);    return n;}/* * Output-generating functions. */static void describeehdr(FILE *fp){    fprintf(fp, "%s", thefilename);    switch (elffhdr.e_type) {      case ET_REL:						break;      case ET_EXEC:	fputc('*', fp);				break;      case ET_DYN:	fputc('&', fp);				break;      default:		fprintf(fp, "?(%u)", elffhdr.e_type);	break;    }    switch (elffhdr.e_machine) {      case EM_M32:	fprintf(fp, " (AT&T M32)");		break;      case EM_386:	fprintf(fp, " (Intel 386)");		break;      case EM_860:	fprintf(fp, " (Intel 860)");		break;      case EM_MIPS:	fprintf(fp, " (MIPS)");			break;      case EM_68K:	fprintf(fp, " (Motorola 68k)");		break;      case EM_88K:	fprintf(fp, " (Motorola 88k)");		break;      case EM_SPARC:	fprintf(fp, " (SPARC)");		break;      default:		fprintf(fp, " (?%u)", elffhdr.e_machine); break;    }    fputc('\n', fp);}/* Fill the given string with the terse description of the given * program header table entry. The description includes a character * that identifies the entry type, the segment permission flags, the * offset and size within the file, and the virtual address at which * to load the contents. */static void describephdr(textline *line, Elf32_Phdr *phdr){    char const *str;    int		n;    switch (phdr->p_type) {      case PT_NULL:	append(line, "(null)");	return;      case PT_INTERP:	append(line, "I ");	break;      case PT_NOTE:	append(line, "N ");	break;      case PT_LOAD:	append(line, "P ");	break;      case PT_PHDR:	append(line, "T ");	break;      case PT_DYNAMIC:	append(line, "L ");	break;      default:		append(line, "? ");	break;    }    if (dostrs) {	switch (phdr->p_type) {	  case PT_INTERP:	    str = getstring(phdr->p_offset, phdr->p_filesz, FALSE);	    if (str && *str) {		n = strlen(str);		if (n > 30)		    append(line, "\"%.27s...\"", str);		else		    append(line, "\"%s\"", str);		return;	    }	    break;	  case PT_NOTE:	    str = getstring(phdr->p_offset + 12,			    phdr->p_filesz - 12, FALSE);	    if (str && *str) {		n = strlen(str);		if (n > 30)		    append(line, "\"%.27s...\"", str);		else		    append(line, "\"%s\"", str);		return;	    }	    break;	}    }    append(line, "%c%c%c",		 (phdr->p_flags & PF_R ? 'r' : '-'),		 (phdr->p_flags & PF_W ? 'w' : '-'),		 (phdr->p_flags & PF_X ? phdr == phentry ? 's' : 'x' : '-'));    if (dooffs)	append(line, "%6lX", phdr->p_offset);    append(line, "%6lX %08lX",		 phdr->p_filesz,		 phdr->p_vaddr);    if (phdr->p_filesz != phdr->p_memsz)	append(line, " +%lX", phdr->p_memsz - phdr->p_filesz);}/* Fill the given string with the terse description of the given * section header table entry. The description includes a character * that identifies the entry type, the flags, the offset and size * within the file, and the section name and the indices of any * related sections. */static void describeshdr(textline *line, Elf32_Shdr *shdr){    char const *str;    int		n;    switch (shdr->sh_type) {      case SHT_NULL:	append(line, "(null)");	return;      case SHT_PROGBITS:	if (sectstr) {	    str = sectstr + shdr->sh_name;	    if (!strcmp(str, ".comment")) {		append(line, "C ");		if (dostrs) {		    str = getstring(shdr->sh_offset, shdr->sh_size, TRUE);		    if (str && *str) {			n = strlen(str);			if (n > 30)			    append(line, "\"%.27s...\"", str);			else			    append(line, "\"%s\"", str);			return;		    }		}		break;	    } else if (!strcmp(str, ".interp")) {		append(line, "I ");		if (dostrs) {		    str = getstring(shdr->sh_offset, shdr->sh_size, FALSE);		    if (str && *str) {			n = strlen(str);			if (n > 30)			    append(line, "\"%.27s...\"", str);			else			    append(line, "\"%s\"", str);			return;		    }		}		break;	    }	}	append(line, "P ");	break;      case SHT_NOTE:		append(line, "N ");	break;      case SHT_STRTAB:		append(line, "$ ");	break;      case SHT_SYMTAB:		append(line, "S ");	break;      case SHT_DYNSYM:		append(line, "D ");	break;      case SHT_DYNAMIC:		append(line, "L ");	break;      case SHT_REL:		append(line, "R ");	break;      case SHT_RELA:		append(line, "A ");	break;      case SHT_HASH:		append(line, "H ");	break;      case SHT_NOBITS:		append(line, "0 ");	break;#ifdef SHT_GNU_verdef      case SHT_GNU_verdef:	append(line, "U ");	break;#endif#ifdef SHT_GNU_verneed      case SHT_GNU_verneed:	append(line, "V ");	break;#endif#ifdef SHT_GNU_versym      case SHT_GNU_versym:	append(line, "W ");	break;#endif      default:			append(line, "? ");	break;    }    if (dostrs) {	if (shdr->sh_type == SHT_NOTE) {	    str = getstring(shdr->sh_offset + 12, shdr->sh_size - 12, FALSE);	    if (str && *str) {		n = strlen(str);		if (n > 30)		    append(line, "\"%.27s...\"", str);		else		    append(line, "\"%s\"", str);		return;	    }	}    }    append(line, "%c%c%c",		 (shdr->sh_flags & SHF_ALLOC ? 'r' : '-'),		 (shdr->sh_flags & SHF_WRITE ? 'w' : '-'),		 (shdr->sh_flags & SHF_EXECINSTR ? 'x' : '-'));    if (dooffs)	append(line, "%6lX", shdr->sh_offset);    append(line, "%6lX %s", shdr->sh_size,			    sectstr ? sectstr + shdr->sh_name : "(n/a)");    if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)	append(line, ":%lu", shdr->sh_info);    if (shdr->sh_link)	append(line, " [%lu]", shdr->sh_link);    if (shdr->sh_type == SHT_STRTAB && shdr == shshstr)	append(line, " [S]");}/* * Top-level functions. *//* Parse the command-line options. */static void readoptions(int argc, char *argv[]){    char const *str;    int		n;    if (!(str = getenv("COLUMNS")) || (outwidth = atoi(str)) <= 0)	outwidth = 80;    while ((n = getopt(argc, argv, "cdEhiPpSvw:")) != EOF) {	switch (n) {	  case 'h':	fputs(yowzitch, stdout);	exit(EXIT_SUCCESS);	  case 'v':	fputs(vourzhon, stdout);	exit(EXIT_SUCCESS);	  case 'E':	skipID = TRUE;			break;	  case 'c':	srcfls = TRUE;			break;	  case 'd':	ldepls = TRUE;			break;	  case 'P':	phdrls = FALSE;			break;	  case 'S':	shdrls = FALSE;			break;	  case 'i':	dostrs = FALSE;			break;	  case 'p':	dooffs = FALSE;			break;	  case 'w':	    if ((outwidth = atoi(optarg)) < 0) {		fputs(yowzitch, stderr);		exit(EXIT_FAILURE);	    }	    break;	  default:	    fputs(yowzitch, stderr);	    exit(EXIT_FAILURE);	}    }}/* main(). */int main(int argc, char *argv[]){    textline   *lines;    char      **arg;    int		ret = 0;    int		count, i;    thisprog = argv[0];    readoptions(argc, argv);    for (arg = argv + optind ; (thefilename = *arg) != NULL ; ++arg) {	if (!(thefile = fopen(thefilename, "rb"))) {	    perror(thefilename);	    ++ret;	    continue;	}	if (!readelfhdr() || !readproghdrs() || !readsecthdrs()) {	    fclose(thefile);	    ++ret;	    continue;	}	describeehdr(stdout);	if (ldepls && proghdrs) {	    if ((count = getlibraries(&lines))) {		outputlist(stdout, lines, count, "Dependencies: ");		free(lines);	    }	}	if (srcfls && secthdrs) {	    if ((count = getsrcfiles(&lines))) {		qsort(lines, count, sizeof *lines, linesorter);		outputlist(stdout, lines, count, "Source files: ");		free(lines);	    }	}	if (phdrls && proghdrs) {	    printf("Program header table entries: %d", elffhdr.e_phnum);	    if (dooffs)		printf(" (%lX - %lX)",		       (unsigned long)elffhdr.e_phoff,		       (unsigned long)elffhdr.e_phoff +				elffhdr.e_phnum * elffhdr.e_phentsize);	    putchar('\n');	    lines = gettextlines(elffhdr.e_phnum);	    for (i = 0 ; i < elffhdr.e_phnum ; ++i) {		append(lines + i, "%2d ", i);		describephdr(lines + i, proghdr + i);	    }	    formatlist(stdout, lines, elffhdr.e_phnum);	    free(lines);	}	if (shdrls && secthdrs) {	    printf("Section header table entries: %d", elffhdr.e_shnum);	    if (dooffs)		printf(" (%lX - %lX)",		       (unsigned long)elffhdr.e_shoff,		       (unsigned long)elffhdr.e_shoff +					elffhdr.e_shnum * elffhdr.e_shentsize);	    putchar('\n');	    lines = gettextlines(elffhdr.e_shnum);	    for (i = 0 ; i < elffhdr.e_shnum ; ++i) {		append(lines + i, "%2d ", i);		describeshdr(lines + i, secthdr + i);	    }	    formatlist(stdout, lines, elffhdr.e_shnum);	    free(lines);	}	fclose(thefile);	free(proghdr);	free(secthdr);	free(sectstr);    }    return ret;}

⌨️ 快捷键说明

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