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

📄 rebind.c

📁 ELFkickers是一组elf工具
💻 C
字号:
/* rebind: Copyright (C) 2001 by Brian Raiter, under the GNU General * Public License. No warranty. See COPYING for details. */#include	<stdio.h>#include	<stdlib.h>#include	<string.h>#include	<errno.h>#include	<unistd.h>#include	<linux/elf.h>#ifndef TRUE#define	TRUE		1#define	FALSE		0#endif#ifndef ELF32_ST_INFO#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xF))#endif/* The memory-allocation macro. */#define	alloc(p, n)	(((p) = realloc(p, n))				\			    || (fputs("Out of memory.\n", stderr),	\				exit(EXIT_FAILURE), 0))/* The online help text. */static char const *yowzitch =	"Usage: rebind [-sw] OBJFILE [SYMBOL...]\n\n"	"   -h  Display this help\n"	"   -v  Display version information\n"	"   -s  Change weak symbols into global symbols\n"	"   -w  Change global symbols into weak symbols (the default)\n"	"If no symbol names are given on the command line, the program\n"	"reads the symbols from standard input.\n";/* The version text. */static char const *vourzhon =	"rebind, version 0.9: Copyright (C) 2001 Brian Raiter\n";static unsigned char	fromstrength;	/* the binding to change from */static unsigned char	tostrength;	/* the binding to change to */static char const      *tostrengthtext;	/* what to tell the user is going on */static char	      **namelist;	/* the list of symbol names to seek */static int		namecount;	/* the number of symbols in namelist */static char const      *thefilename;	/* the current file name */static FILE	       *thefile;	/* the current file handle */static Elf32_Ehdr	ehdr;		/* the file's ELF header *//* Standard qsort/bsearch string comparison function. */static int qstrcmp(void const *a, void const *b){    return strcmp(*(char const**)a, *(char const**)b);}/* An error-handling function. The given error message is used only * when errno is not set. */static int err(char const *errmsg){    if (errno)	perror(thefilename);    else	fprintf(stderr, "%s: %s\n", thefilename, errmsg);    return FALSE;}/* Reads and returns an area of the input file. */static void *getarea(int off, int size){    void       *buf = NULL;    alloc(buf, size);    if (fseek(thefile, off, SEEK_SET) || fread(buf, size, 1, thefile) != 1) {	free(buf);	return NULL;    }    return buf;}/* namelistfromfile() builds an array of all the non-whitespace strings * in the given file. */static int namelistfromfile(FILE *fp){    char	word[256];    int		allocated = 0;    int		n;    while (fscanf(fp, "%255s", word) > 0) {	if (namecount >= allocated) {	    allocated = allocated ? allocated * 2 : 16;	    alloc(namelist, allocated * sizeof *namelist);	}	namelist[namecount] = NULL;	n = strlen(word) + 1;	alloc(namelist[namecount], n);	memcpy(namelist[namecount], word, n);	++namecount;    }    return TRUE;}/* readheader() checks to make sure that this is in fact a proper ELF * object file that we're proposing to munge. */static int readheader(void){    int	endianness;    /*     * First, load the ELF header and do some sanity-checking.     */    errno = 0;    if (fread(&ehdr, sizeof ehdr, 1, thefile) != 1)	return err("not an ELF file.");    if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1					 || ehdr.e_ident[EI_MAG2] != ELFMAG2					 || ehdr.e_ident[EI_MAG3] != ELFMAG3)	return err("not an ELF file.");    endianness = 1;    *(unsigned char*)&endianness = 0;    if (ehdr.e_ident[EI_DATA] != (endianness ? ELFDATA2MSB : ELFDATA2LSB)) {	fprintf(stderr, "%s: not %s-endian.\n",			thefilename, endianness ? "big" : "little");	return FALSE;    }    if (ehdr.e_ehsize != sizeof(Elf32_Ehdr))	return err("unrecognized ELF header size");    if (!ehdr.e_shoff)	return err("no section header table.");    if (ehdr.e_shentsize != sizeof(Elf32_Shdr))	return err("unrecognized section header size");    return TRUE;}/* changesymbols() finds all symbols in a given symbol table that * appear in the namelist with the specified binding and alters their * binding strength. */static int changesymbols(Elf32_Sym *symtab, char const *strtab, int count){    Elf32_Sym  *sym;    char const *name;    int		touched;    int		i;    touched = FALSE;    for (i = 0, sym = symtab ; i < count ; ++i, ++sym) {	if (ELF32_ST_BIND(sym->st_info) != fromstrength)	    continue;	name = strtab + sym->st_name;	if (!bsearch(&name, namelist, namecount, sizeof *namelist, qstrcmp))	    continue;	sym->st_info = ELF32_ST_INFO(tostrength, ELF32_ST_TYPE(sym->st_info));	printf("%s \"%s\".\n", tostrengthtext, name);	touched = TRUE;    }    return touched;}/* rebind() does most of the grunt work. After checking over the ELF * headers, the function iterates through the sections, looking for * symbol tables containing non-local symbol. When it finds one, it * loads the non-local part of the table and the associated string * table into memory, and calls changesymbols(). If changesymbols() * actually changes anything, the altered symbol table is written back * out to the object file. */static int rebind(void){    Elf32_Shdr *shdrs;    Elf32_Sym  *symtab;    char       *strtab;    unsigned	offset, count;    int		i;    if (!readheader())	return FALSE;    if (!(shdrs = getarea(ehdr.e_shoff, ehdr.e_shnum * sizeof(Elf32_Shdr))))	return err("invalid section header table.");    for (i = 0 ; i < ehdr.e_shnum ; ++i) {	if (shdrs[i].sh_type != SHT_SYMTAB && shdrs[i].sh_type != SHT_DYNSYM)	    continue;	if (shdrs[i].sh_entsize != sizeof *symtab) {	    err("symbol table of unrecognized structure ignored.");	    continue;	}	offset = shdrs[i].sh_offset + shdrs[i].sh_info * sizeof *symtab;	count = shdrs[i].sh_size / sizeof *symtab - shdrs[i].sh_info;	if (!count)	    continue;	if (!(symtab = getarea(offset, count * sizeof *symtab)))	    return err("invalid symbol table");	if (!(strtab = getarea(shdrs[shdrs[i].sh_link].sh_offset,			       shdrs[shdrs[i].sh_link].sh_size)))	    return err("invalid associated string table");	if (changesymbols(symtab, strtab, count)) {	    if (fseek(thefile, offset, SEEK_SET)		    || fwrite(symtab, sizeof *symtab, count, thefile) != count)		return err("unable to write to the object file");	}	free(symtab);	free(strtab);    }    free(shdrs);    return TRUE;}/* main() interprets the command-line arguments, builds the array of * symbol names, opens the object file, and calls rebind(). */int main(int argc, char *argv[]){    int	n;    fromstrength = STB_GLOBAL;    tostrength = STB_WEAK;    tostrengthtext = "Weakening";    while ((n = getopt(argc, argv, "hsvw")) != EOF) {	switch (n) {	  case 's':	    fromstrength = STB_WEAK;	    tostrength = STB_GLOBAL;	    tostrengthtext = "Strengthening";	    break;	  case 'w':	    fromstrength = STB_GLOBAL;	    tostrength = STB_WEAK;	    tostrengthtext = "Weakening";	    break;	  case 'h':	    fputs(yowzitch, stdout);	    return EXIT_SUCCESS;	  case 'v':	    fputs(vourzhon, stdout);	    return EXIT_SUCCESS;	  default:	    fputs(yowzitch, stderr);	    return EXIT_FAILURE;	}    }    if (optind == argc) {	fputs(yowzitch, stderr);	return EXIT_FAILURE;    }    thefilename = argv[optind];    if (!(thefile = fopen(thefilename, "rb+"))) {	err("unable to open.");	return EXIT_FAILURE;    }    ++optind;    if (optind == argc) {	if (!namelistfromfile(stdin))	    return EXIT_FAILURE;    } else {	namelist = argv + optind;	namecount = argc - optind;    }    qsort(namelist, namecount, sizeof *namelist, qstrcmp);    n = rebind() ? EXIT_SUCCESS : EXIT_FAILURE;    fclose(thefile);    return n;}

⌨️ 快捷键说明

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