Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 251805 Details for
Bug 337108
dev-util/elfkickers does not respect LDFLAGS
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Consolidated patch
elfkickers-2.0a-r5.patch (text/plain), 33.11 KB, created by
Anthony Basile
on 2010-10-24 15:25:20 UTC
(
hide
)
Description:
Consolidated patch
Filename:
MIME Type:
Creator:
Anthony Basile
Created:
2010-10-24 15:25:20 UTC
Size:
33.11 KB
patch
obsolete
>diff -Naur ELFkickers.orig/ebfc/Makefile ELFkickers/ebfc/Makefile >--- ELFkickers.orig/ebfc/Makefile 2001-01-17 08:23:56.000000000 -0500 >+++ ELFkickers/ebfc/Makefile 2010-10-24 11:14:18.000000000 -0400 >@@ -1,8 +1,5 @@ > # Makefile for ebfc > >-CC = gcc >-CFLAGS = -ggdb -Wall >- > ebfc: ebfc.o brainfuck.o libelfparts.a > > ebfc.o: ebfc.c elfparts.h ebfc.h >diff -Naur ELFkickers.orig/ebfc/rel.c ELFkickers/ebfc/rel.c >--- ELFkickers.orig/ebfc/rel.c 2001-03-19 10:50:18.000000000 -0500 >+++ ELFkickers/ebfc/rel.c 2010-10-24 11:14:18.000000000 -0400 >@@ -5,6 +5,7 @@ > */ > > #include <stdlib.h> >+#include <string.h> > #include <linux/elf.h> > #include "elfparts.h" > #include "gen.h" >diff -Naur ELFkickers.orig/elfls/elfls.c ELFkickers/elfls/elfls.c >--- ELFkickers.orig/elfls/elfls.c 2001-03-28 08:23:57.000000000 -0500 >+++ ELFkickers/elfls/elfls.c 2010-10-24 11:14:18.000000000 -0400 >@@ -4,6 +4,7 @@ > > #include <stdio.h> > #include <stdlib.h> >+#include <string.h> > #include <errno.h> > #include <stdarg.h> > #include <unistd.h> >@@ -15,6 +16,21 @@ > #define FALSE 0 > #endif > >+#if ELF_CLASS == ELFCLASS32 >+ #define Elf_Ehdr Elf32_Ehdr >+ #define Elf_Phdr Elf32_Phdr >+ #define Elf_Shdr Elf32_Shdr >+ #define Elf_Sym Elf32_Sym >+ #define Elf_Dyn Elf32_Dyn >+#else >+ #define Elf_Ehdr Elf64_Ehdr >+ #define Elf_Phdr Elf64_Phdr >+ #define Elf_Shdr Elf64_Shdr >+ #define Elf_Sym Elf64_Sym >+ #define Elf_Dyn Elf64_Dyn >+#endif >+ >+ > /* Memory allocation error message. > */ > #define nomem() (fputs("Out of memory!\n", stderr), exit(EXIT_FAILURE)) >@@ -51,15 +67,15 @@ > * 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 Elf_Ehdr elffhdr; /* ELF header of current file */ >+static Elf_Phdr *proghdr = NULL; /* program header table */ >+static Elf_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 Elf_Phdr *phentry = NULL; /* ph with the entry point */ >+static Elf_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 */ >@@ -272,6 +288,7 @@ > } > if (skipID) > return TRUE; >+#if ELF_CLASS == ELFCLASS32 > if (id[EI_CLASS] != ELFCLASS32) { > fprintf(stderr, "%s: not a 32-bit ELF file " > "(class = %d instead of %d).\n", >@@ -279,6 +296,15 @@ > ELFCLASS32); > return FALSE; > } >+#else >+ if (id[EI_CLASS] != ELFCLASS64) { >+ fprintf(stderr, "%s: not a 64-bit ELF file " >+ "(class = %d instead of %d).\n", >+ thefilename, (int)(unsigned char)id[EI_CLASS], >+ ELFCLASS64); >+ return FALSE; >+ } >+#endif > bigendian = TRUE; > *(char*)&bigendian = 0; > if (id[EI_DATA] != (bigendian ? ELFDATA2MSB : ELFDATA2LSB)) { >@@ -316,6 +342,7 @@ > return FALSE; > switch (elffhdr.e_type) { > case ET_REL: >+ case ET_CORE: > case ET_EXEC: > case ET_DYN: > return TRUE; >@@ -333,7 +360,7 @@ > } > if (elffhdr.e_ehsize != sizeof elffhdr) > fprintf(stderr, "%s: warning: unrecognized ELF header size " >- "(size = %u instead of %u).\n", >+ "(size = %u instead of %lu).\n", > thefilename, elffhdr.e_ehsize, sizeof elffhdr); > return TRUE; > } >@@ -358,10 +385,10 @@ > return TRUE; > } > if (elffhdr.e_phentsize == sizeof *proghdr) >- proghdr = (Elf32_Phdr*)buf; >+ proghdr = (Elf_Phdr*)buf; > else { > fprintf(stderr, "%s: warning: unrecognized program header entry size " >- "(size = %u instead of %u).\n", >+ "(size = %u instead of %lu).\n", > thefilename, elffhdr.e_phentsize, sizeof *proghdr); > if (!(proghdr = calloc(elffhdr.e_phnum, sizeof *proghdr))) > nomem(); >@@ -405,10 +432,10 @@ > return TRUE; > } > if (elffhdr.e_shentsize == sizeof *secthdr) >- secthdr = (Elf32_Shdr*)buf; >+ secthdr = (Elf_Shdr*)buf; > else { > fprintf(stderr, "%s: warning: unrecognized section header entry size " >- "(size = %u instead of %u).\n", >+ "(size = %u instead of %lu).\n", > thefilename, elffhdr.e_shentsize, sizeof *secthdr); > if (!(secthdr = calloc(elffhdr.e_shnum, sizeof *secthdr))) > nomem(); >@@ -436,7 +463,7 @@ > */ > static int getsrcfiles(textline **plines) > { >- Elf32_Sym *syms; >+ Elf_Sym *syms; > char *nmstr; > textline *lines; > char *str; >@@ -460,7 +487,11 @@ > lines = gettextlines(count); > n = 0; > for (i = 0 ; i < count ; ++i) { >+#if ELF_CLASS == ELFCLASS32 > if (ELF32_ST_TYPE(syms[i].st_info) != STT_FILE) >+#else >+ if (ELF64_ST_TYPE(syms[i].st_info) != STT_FILE) >+#endif > continue; > str = nmstr + syms[i].st_name; > for (j = 0 ; j < n ; ++j) >@@ -488,7 +519,7 @@ > */ > static int getlibraries(textline **plines) > { >- Elf32_Dyn *dyns; >+ Elf_Dyn *dyns; > char *nmstr; > textline *lines; > char *str; >@@ -581,7 +612,7 @@ > * offset and size within the file, and the virtual address at which > * to load the contents. > */ >-static void describephdr(textline *line, Elf32_Phdr *phdr) >+static void describephdr(textline *line, Elf_Phdr *phdr) > { > char const *str; > int n; >@@ -646,7 +677,7 @@ > * within the file, and the section name and the indices of any > * related sections. > */ >-static void describeshdr(textline *line, Elf32_Shdr *shdr) >+static void describeshdr(textline *line, Elf_Shdr *shdr) > { > char const *str; > int n; >diff -Naur ELFkickers.orig/elfls/Makefile ELFkickers/elfls/Makefile >--- ELFkickers.orig/elfls/Makefile 1999-07-07 23:57:55.000000000 -0400 >+++ ELFkickers/elfls/Makefile 2010-10-24 11:14:18.000000000 -0400 >@@ -1,7 +1,7 @@ > # Makefile for elfls > > elfls: elfls.c >- gcc -ggdb -Wall -W -o elfls elfls.c >+ $(CC) $(CFLAGS) $(LDFLAGS) -W -o elfls elfls.c > > clean: > rm -f elfls >diff -Naur ELFkickers.orig/elftoc/Makefile ELFkickers/elftoc/Makefile >--- ELFkickers.orig/elftoc/Makefile 2001-03-26 05:48:59.000000000 -0500 >+++ ELFkickers/elftoc/Makefile 2010-10-24 11:14:18.000000000 -0400 >@@ -1,9 +1,5 @@ > # Makefile for elftoc > >-CC = gcc >-CFLAGS = -ggdb -Wall >-LDFLAGS = $(CFLAGS) >- > OBJS = pieces.o addr.o shdrtab.o dynamic.o outbasic.o outtools.o out.o elftoc.o > > elftoc: $(OBJS) >diff -Naur ELFkickers.orig/elftoc/shdrtab.c ELFkickers/elftoc/shdrtab.c >--- ELFkickers.orig/elftoc/shdrtab.c 2001-03-25 08:09:09.000000000 -0500 >+++ ELFkickers/elftoc/shdrtab.c 2010-10-24 11:14:18.000000000 -0400 >@@ -5,6 +5,7 @@ > */ > > #include <stdlib.h> >+#include <string.h> > #include <ctype.h> > #include "gen.h" > #include "elf.h" >diff -Naur ELFkickers.orig/Makefile ELFkickers/Makefile >--- ELFkickers.orig/Makefile 1969-12-31 19:00:00.000000000 -0500 >+++ ELFkickers/Makefile 2010-10-24 11:14:44.000000000 -0400 >@@ -0,0 +1,6 @@ >+SUBDIRS = ebfc elfls elftoc rebind sstrip >+ >+all: >+ for d in $(SUBDIRS); do cd $$d ; CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" CC=$(CC) $(MAKE) ; cd - ; done >+clean: >+ for d in $(SUBDIRS); do cd $$d ; $(MAKE) clean; cd - ; done >diff -Naur ELFkickers.orig/rebind/Makefile ELFkickers/rebind/Makefile >--- ELFkickers.orig/rebind/Makefile 2001-03-19 10:08:56.000000000 -0500 >+++ ELFkickers/rebind/Makefile 2010-10-24 11:14:18.000000000 -0400 >@@ -1,7 +1,7 @@ > # Makefile for rebind > > rebind: rebind.c >- gcc -ggdb -Wall -W -o rebind rebind.c >+ $(CC) $(CFLAGS) $(LDFLAGS) -W -o rebind rebind.c > > clean: > rm -f rebind >diff -Naur ELFkickers.orig/rebind/rebind.c ELFkickers/rebind/rebind.c >--- ELFkickers.orig/rebind/rebind.c 2001-04-17 13:45:46.000000000 -0400 >+++ ELFkickers/rebind/rebind.c 2010-10-24 11:14:18.000000000 -0400 >@@ -7,17 +7,35 @@ > #include <string.h> > #include <errno.h> > #include <unistd.h> >-#include <linux/elf.h> >+#include <elf.h> > > #ifndef TRUE > #define TRUE 1 > #define FALSE 0 > #endif > >+#if ELF_CLASS == ELFCLASS32 >+ #define Elf_Ehdr Elf32_Ehdr >+ #define Elf_Phdr Elf32_Phdr >+ #define Elf_Shdr Elf32_Shdr >+ #define Elf_Sym Elf32_Sym >+ #define Elf_Dyn Elf32_Dyn >+#else >+ #define Elf_Ehdr Elf64_Ehdr >+ #define Elf_Phdr Elf64_Phdr >+ #define Elf_Shdr Elf64_Shdr >+ #define Elf_Sym Elf64_Sym >+ #define Elf_Dyn Elf64_Dyn >+#endif >+ > #ifndef ELF32_ST_INFO > #define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xF)) > #endif > >+#ifndef ELF64_ST_INFO >+#define ELF64_ST_INFO ELF32_ST_INFO /* does not really matter however as they are the same. */ >+#endif >+ > /* The memory-allocation macro. > */ > #define alloc(p, n) (((p) = realloc(p, n)) \ >@@ -50,7 +68,7 @@ > static char const *thefilename; /* the current file name */ > static FILE *thefile; /* the current file handle */ > >-static Elf32_Ehdr ehdr; /* the file's ELF header */ >+static Elf_Ehdr ehdr; /* the file's ELF header */ > > > /* Standard qsort/bsearch string comparison function. >@@ -136,11 +154,11 @@ > thefilename, endianness ? "big" : "little"); > return FALSE; > } >- if (ehdr.e_ehsize != sizeof(Elf32_Ehdr)) >+ if (ehdr.e_ehsize != sizeof(Elf_Ehdr)) > return err("unrecognized ELF header size"); > if (!ehdr.e_shoff) > return err("no section header table."); >- if (ehdr.e_shentsize != sizeof(Elf32_Shdr)) >+ if (ehdr.e_shentsize != sizeof(Elf_Shdr)) > return err("unrecognized section header size"); > > return TRUE; >@@ -150,9 +168,9 @@ > * appear in the namelist with the specified binding and alters their > * binding strength. > */ >-static int changesymbols(Elf32_Sym *symtab, char const *strtab, int count) >+static int changesymbols(Elf_Sym *symtab, char const *strtab, int count) > { >- Elf32_Sym *sym; >+ Elf_Sym *sym; > char const *name; > int touched; > int i; >@@ -164,7 +182,11 @@ > name = strtab + sym->st_name; > if (!bsearch(&name, namelist, namecount, sizeof *namelist, qstrcmp)) > continue; >+#if ELF_CLASS == ELFCLASS32 > sym->st_info = ELF32_ST_INFO(tostrength, ELF32_ST_TYPE(sym->st_info)); >+#else >+ sym->st_info = ELF32_ST_INFO(tostrength, ELF64_ST_TYPE(sym->st_info)); >+#endif > printf("%s \"%s\".\n", tostrengthtext, name); > touched = TRUE; > } >@@ -181,15 +203,15 @@ > */ > static int rebind(void) > { >- Elf32_Shdr *shdrs; >- Elf32_Sym *symtab; >+ Elf_Shdr *shdrs; >+ Elf_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)))) >+ if (!(shdrs = getarea(ehdr.e_shoff, ehdr.e_shnum * sizeof(Elf_Shdr)))) > return err("invalid section header table."); > > for (i = 0 ; i < ehdr.e_shnum ; ++i) { >diff -Naur ELFkickers.orig/sstrip/Makefile ELFkickers/sstrip/Makefile >--- ELFkickers.orig/sstrip/Makefile 2001-03-24 06:58:27.000000000 -0500 >+++ ELFkickers/sstrip/Makefile 2010-10-24 11:14:18.000000000 -0400 >@@ -1,7 +1,7 @@ > # Makefile for sstrip > > sstrip: sstrip.c >- gcc -ggdb -Wall -W -o sstrip sstrip.c >+ $(CC) $(CFLAGS) $(LDFLAGS) -W -o sstrip sstrip.c > > clean: > rm -f sstrip >diff -Naur ELFkickers.orig/sstrip/sstrip.c ELFkickers/sstrip/sstrip.c >--- ELFkickers.orig/sstrip/sstrip.c 2001-03-24 07:18:52.000000000 -0500 >+++ ELFkickers/sstrip/sstrip.c 2010-10-24 11:14:18.000000000 -0400 >@@ -1,5 +1,55 @@ >+/* http://www.muppetlabs.com/~breadbox/software/elfkickers.html */ >+ > /* sstrip: Copyright (C) 1999-2001 by Brian Raiter, under the GNU > * General Public License. No warranty. See COPYING for details. >+ * >+ * Aug 23, 2004 Hacked by Manuel Novoa III <mjn3@codepoet.org> to >+ * handle targets of different endianness and/or elf class, making >+ * it more useful in a cross-devel environment. >+ */ >+ >+/* ============== original README =================== >+ * >+ * sstrip is a small utility that removes the contents at the end of an >+ * ELF file that are not part of the program's memory image. >+ * >+ * Most ELF executables are built with both a program header table and a >+ * section header table. However, only the former is required in order >+ * for the OS to load, link and execute a program. sstrip attempts to >+ * extract the ELF header, the program header table, and its contents, >+ * leaving everything else in the bit bucket. It can only remove parts of >+ * the file that occur at the end, after the parts to be saved. However, >+ * this almost always includes the section header table, and occasionally >+ * a few random sections that are not used when running a program. >+ * >+ * It should be noted that the GNU bfd library is (understandably) >+ * dependent on the section header table as an index to the file's >+ * contents. Thus, an executable file that has no section header table >+ * cannot be used with gdb, objdump, or any other program based upon the >+ * bfd library, at all. In fact, the program will not even recognize the >+ * file as a valid executable. (This limitation is noted in the source >+ * code comments for bfd, and is marked "FIXME", so this may change at >+ * some future date. However, I would imagine that it is a pretty >+ * low-priority item, as executables without a section header table are >+ * rare in the extreme.) This probably also explains why strip doesn't >+ * offer the option to do this. >+ * >+ * Shared library files may also have their section header table removed. >+ * Such a library will still function; however, it will no longer be >+ * possible for a compiler to link a new program against it. >+ * >+ * As an added bonus, sstrip also tries to removes trailing zero bytes >+ * from the end of the file. (This normally cannot be done with an >+ * executable that has a section header table.) >+ * >+ * sstrip is a very simplistic program. It depends upon the common >+ * practice of putting the parts of the file that contribute to the >+ * memory image at the front, and the remaining material at the end. This >+ * permits it to discard the latter material without affecting file >+ * offsets and memory addresses in what remains. Of course, the ELF >+ * standard permits files to be organized in almost any order, so if a >+ * pathological linker decided to put its section headers at the top, >+ * sstrip would be useless on such executables. > */ > > #include <stdio.h> >@@ -9,28 +59,36 @@ > #include <unistd.h> > #include <fcntl.h> > #include <elf.h> >-#include <asm/elf.h> >+#ifdef __FreeBSD__ >+/** >+ * This seems to work on FreeBSD 5.3, should >+ * work on all newer versions as well. I have >+ * no idea if it will work on versions < 5.3 >+ * >+ * Joe Estock (guru) <jestock at nutextonline.com> >+ */ >+#include <sys/endian.h> >+#define bswap_64 __bswap64 >+#define bswap_32 __bswap32 >+#define bswap_16 __bswap16 >+#else >+#include <endian.h> >+#include <byteswap.h> >+#endif /* defined(__FreeBSD__) */ >+ > > #ifndef TRUE > #define TRUE 1 > #define FALSE 0 > #endif > >-#if ELF_CLASS == ELFCLASS32 >-#define Elf_Ehdr Elf32_Ehdr >-#define Elf_Phdr Elf32_Phdr >-#else >-#define Elf_Ehdr Elf64_Ehdr >-#define Elf_Phdr Elf64_Phdr >-#endif >- > /* The name of the program. > */ >-static char const *progname; >+static char const *progname; > > /* The name of the current file. > */ >-static char const *filename; >+static char const *filename; > > > /* A simple error-handling function. FALSE is always returned for the >@@ -38,227 +96,321 @@ > */ > static int err(char const *errmsg) > { >- fprintf(stderr, "%s: %s: %s\n", progname, filename, errmsg); >- return FALSE; >+ fprintf(stderr, "%s: %s: %s\n", progname, filename, errmsg); >+ return FALSE; > } > >-/* A macro for I/O errors: The given error message is used only when >- * errno is not set. >+/* A flag to signal the need for endian reversal. > */ >-#define ferr(msg) (err(errno ? strerror(errno) : (msg))) >+static int do_reverse_endian; > >-/* readelfheader() reads the ELF header into our global variable, and >- * checks to make sure that this is in fact a file that we should be >- * munging. >+/* Get a value from the elf header, compensating for endianness. > */ >-static int readelfheader(int fd, Elf_Ehdr *ehdr) >-{ >- errno = 0; >- if (read(fd, ehdr, sizeof *ehdr) != sizeof *ehdr) >- return ferr("missing or incomplete ELF header."); >- >- /* Check the ELF signature. >- */ >- 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("missing ELF signature."); >- >- /* Compare the file's class and endianness with the program's. >- */ >- if (ehdr->e_ident[EI_DATA] != ELF_DATA) >- return err("ELF file has different endianness."); >- if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) >- return err("ELF file has different word size."); >- >- /* Check the target architecture. >- */ >- if (ehdr->e_machine != ELF_ARCH) >- return err("ELF file created for different architecture."); >- >- /* Verify the sizes of the ELF header and the program segment >- * header table entries. >- */ >- if (ehdr->e_ehsize != sizeof(Elf_Ehdr)) >- return err("unrecognized ELF header size."); >- if (ehdr->e_phentsize != sizeof(Elf_Phdr)) >- return err("unrecognized program segment header size."); >- >- /* Finally, check the file type. >- */ >- if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) >- return err("not an executable or shared-object library."); >+#define EGET(X) \ >+ (__extension__ ({ \ >+ uint64_t __res; \ >+ if (!do_reverse_endian) { \ >+ __res = (X); \ >+ } else if (sizeof(X) == 1) { \ >+ __res = (X); \ >+ } else if (sizeof(X) == 2) { \ >+ __res = bswap_16((X)); \ >+ } else if (sizeof(X) == 4) { \ >+ __res = bswap_32((X)); \ >+ } else if (sizeof(X) == 8) { \ >+ __res = bswap_64((X)); \ >+ } else { \ >+ fprintf(stderr, "%s: %s: EGET failed for size %ld\n", \ >+ progname, filename, sizeof(X)); \ >+ exit(EXIT_FAILURE); \ >+ } \ >+ __res; \ >+ })) >+ >+/* Set a value 'Y' in the elf header to 'X', compensating for endianness. >+ */ >+#define ESET(Y,X) \ >+ do if (!do_reverse_endian) { \ >+ Y = (X); \ >+ } else if (sizeof(Y) == 1) { \ >+ Y = (X); \ >+ } else if (sizeof(Y) == 2) { \ >+ Y = bswap_16((uint16_t)(X)); \ >+ } else if (sizeof(Y) == 4) { \ >+ Y = bswap_32((uint32_t)(X)); \ >+ } else if (sizeof(Y) == 8) { \ >+ Y = bswap_64((uint64_t)(X)); \ >+ } else { \ >+ fprintf(stderr, "%s: %s: ESET failed for size %ld\n", \ >+ progname, filename, sizeof(Y)); \ >+ exit(EXIT_FAILURE); \ >+ } while (0) > >- return TRUE; >-} > >-/* readphdrtable() loads the program segment header table into memory. >+/* A macro for I/O errors: The given error message is used only when >+ * errno is not set. > */ >-static int readphdrtable(int fd, Elf_Ehdr const *ehdr, Elf_Phdr **phdrs) >-{ >- size_t size; >- >- if (!ehdr->e_phoff || !ehdr->e_phnum) >- return err("ELF file has no program header table."); >+#define ferr(msg) (err(errno ? strerror(errno) : (msg))) > >- size = ehdr->e_phnum * sizeof **phdrs; >- if (!(*phdrs = malloc(size))) >- return err("Out of memory!"); > >- errno = 0; >- if (read(fd, *phdrs, size) != (ssize_t)size) >- return ferr("missing or incomplete program segment header table."); > >- return TRUE; >+#define HEADER_FUNCTIONS(CLASS) \ >+ \ >+/* readelfheader() reads the ELF header into our global variable, and \ >+ * checks to make sure that this is in fact a file that we should be \ >+ * munging. \ >+ */ \ >+static int readelfheader ## CLASS (int fd, Elf ## CLASS ## _Ehdr *ehdr) \ >+{ \ >+ if (read(fd, ((char *)ehdr)+EI_NIDENT, sizeof(*ehdr) - EI_NIDENT) \ >+ != sizeof(*ehdr) - EI_NIDENT) \ >+ return ferr("missing or incomplete ELF header."); \ >+ \ >+ /* Verify the sizes of the ELF header and the program segment \ >+ * header table entries. \ >+ */ \ >+ if (EGET(ehdr->e_ehsize) != sizeof(Elf ## CLASS ## _Ehdr)) \ >+ return err("unrecognized ELF header size."); \ >+ if (EGET(ehdr->e_phentsize) != sizeof(Elf ## CLASS ## _Phdr)) \ >+ return err("unrecognized program segment header size."); \ >+ \ >+ /* Finally, check the file type. \ >+ */ \ >+ if (EGET(ehdr->e_type) != ET_EXEC && EGET(ehdr->e_type) != ET_DYN) \ >+ return err("not an executable or shared-object library."); \ >+ \ >+ return TRUE; \ >+} \ >+ \ >+/* readphdrtable() loads the program segment header table into memory. \ >+ */ \ >+static int readphdrtable ## CLASS (int fd, Elf ## CLASS ## _Ehdr const *ehdr, \ >+ Elf ## CLASS ## _Phdr **phdrs) \ >+{ \ >+ size_t size; \ >+ \ >+ if (!EGET(ehdr->e_phoff) || !EGET(ehdr->e_phnum) \ >+) return err("ELF file has no program header table."); \ >+ \ >+ size = EGET(ehdr->e_phnum) * sizeof **phdrs; \ >+ if (!(*phdrs = malloc(size))) \ >+ return err("Out of memory!"); \ >+ \ >+ errno = 0; \ >+ if (read(fd, *phdrs, size) != (ssize_t)size) \ >+ return ferr("missing or incomplete program segment header table."); \ >+ \ >+ return TRUE; \ >+} \ >+ \ >+/* getmemorysize() determines the offset of the last byte of the file \ >+ * that is referenced by an entry in the program segment header table. \ >+ * (Anything in the file after that point is not used when the program \ >+ * is executing, and thus can be safely discarded.) \ >+ */ \ >+static int getmemorysize ## CLASS (Elf ## CLASS ## _Ehdr const *ehdr, \ >+ Elf ## CLASS ## _Phdr const *phdrs, \ >+ unsigned long *newsize) \ >+{ \ >+ Elf ## CLASS ## _Phdr const *phdr; \ >+ unsigned long size, n; \ >+ int i; \ >+ \ >+ /* Start by setting the size to include the ELF header and the \ >+ * complete program segment header table. \ >+ */ \ >+ size = EGET(ehdr->e_phoff) + EGET(ehdr->e_phnum) * sizeof *phdrs; \ >+ if (size < sizeof *ehdr) \ >+ size = sizeof *ehdr; \ >+ \ >+ /* Then keep extending the size to include whatever data the \ >+ * program segment header table references. \ >+ */ \ >+ for (i = 0, phdr = phdrs ; i < EGET(ehdr->e_phnum) ; ++i, ++phdr) { \ >+ if (EGET(phdr->p_type) != PT_NULL) { \ >+ n = EGET(phdr->p_offset) + EGET(phdr->p_filesz); \ >+ if (n > size) \ >+ size = n; \ >+ } \ >+ } \ >+ \ >+ *newsize = size; \ >+ return TRUE; \ >+} \ >+ \ >+/* modifyheaders() removes references to the section header table if \ >+ * it was stripped, and reduces program header table entries that \ >+ * included truncated bytes at the end of the file. \ >+ */ \ >+static int modifyheaders ## CLASS (Elf ## CLASS ## _Ehdr *ehdr, \ >+ Elf ## CLASS ## _Phdr *phdrs, \ >+ unsigned long newsize) \ >+{ \ >+ Elf ## CLASS ## _Phdr *phdr; \ >+ int i; \ >+ \ >+ /* If the section header table is gone, then remove all references \ >+ * to it in the ELF header. \ >+ */ \ >+ if (EGET(ehdr->e_shoff) >= newsize) { \ >+ ESET(ehdr->e_shoff,0); \ >+ ESET(ehdr->e_shnum,0); \ >+ ESET(ehdr->e_shentsize,0); \ >+ ESET(ehdr->e_shstrndx,0); \ >+ } \ >+ \ >+ /* The program adjusts the file size of any segment that was \ >+ * truncated. The case of a segment being completely stripped out \ >+ * is handled separately. \ >+ */ \ >+ for (i = 0, phdr = phdrs ; i < EGET(ehdr->e_phnum) ; ++i, ++phdr) { \ >+ if (EGET(phdr->p_offset) >= newsize) { \ >+ ESET(phdr->p_offset,newsize); \ >+ ESET(phdr->p_filesz,0); \ >+ } else if (EGET(phdr->p_offset) + EGET(phdr->p_filesz) > newsize) { \ >+ newsize -= EGET(phdr->p_offset); \ >+ ESET(phdr->p_filesz, newsize); \ >+ } \ >+ } \ >+ \ >+ return TRUE; \ >+} \ >+ \ >+/* commitchanges() writes the new headers back to the original file \ >+ * and sets the file to its new size. \ >+ */ \ >+static int commitchanges ## CLASS (int fd, Elf ## CLASS ## _Ehdr const *ehdr, \ >+ Elf ## CLASS ## _Phdr *phdrs, \ >+ unsigned long newsize) \ >+{ \ >+ size_t n; \ >+ \ >+ /* Save the changes to the ELF header, if any. \ >+ */ \ >+ if (lseek(fd, 0, SEEK_SET)) \ >+ return ferr("could not rewind file"); \ >+ errno = 0; \ >+ if (write(fd, ehdr, sizeof *ehdr) != sizeof *ehdr) \ >+ return err("could not modify file"); \ >+ \ >+ /* Save the changes to the program segment header table, if any. \ >+ */ \ >+ if (lseek(fd, EGET(ehdr->e_phoff), SEEK_SET) == (off_t)-1) { \ >+ err("could not seek in file."); \ >+ goto warning; \ >+ } \ >+ n = EGET(ehdr->e_phnum) * sizeof *phdrs; \ >+ if (write(fd, phdrs, n) != (ssize_t)n) { \ >+ err("could not write to file"); \ >+ goto warning; \ >+ } \ >+ \ >+ /* Eleventh-hour sanity check: don't truncate before the end of \ >+ * the program segment header table. \ >+ */ \ >+ if (newsize < EGET(ehdr->e_phoff) + n) \ >+ newsize = EGET(ehdr->e_phoff) + n; \ >+ \ >+ /* Chop off the end of the file. \ >+ */ \ >+ if (ftruncate(fd, newsize)) { \ >+ err("could not resize file"); \ >+ goto warning; \ >+ } \ >+ \ >+ return TRUE; \ >+ \ >+ warning: \ >+ return err("ELF file may have been corrupted!"); \ > } > >-/* getmemorysize() determines the offset of the last byte of the file >- * that is referenced by an entry in the program segment header table. >- * (Anything in the file after that point is not used when the program >- * is executing, and thus can be safely discarded.) >- */ >-static int getmemorysize(Elf_Ehdr const *ehdr, Elf_Phdr const *phdrs, >- unsigned long *newsize) >-{ >- Elf32_Phdr const *phdr; >- unsigned long size, n; >- int i; >- >- /* Start by setting the size to include the ELF header and the >- * complete program segment header table. >- */ >- size = ehdr->e_phoff + ehdr->e_phnum * sizeof *phdrs; >- if (size < sizeof *ehdr) >- size = sizeof *ehdr; >- >- /* Then keep extending the size to include whatever data the >- * program segment header table references. >- */ >- for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) { >- if (phdr->p_type != PT_NULL) { >- n = phdr->p_offset + phdr->p_filesz; >- if (n > size) >- size = n; >- } >- } >- >- *newsize = size; >- return TRUE; >-} > >-/* truncatezeros() examines the bytes at the end of the file's >- * size-to-be, and reduces the size to exclude any trailing zero >- * bytes. >+/* First elements of Elf32_Ehdr and Elf64_Ehdr are common. > */ >-static int truncatezeros(int fd, unsigned long *newsize) >+static int readelfheaderident(int fd, Elf32_Ehdr *ehdr) > { >- unsigned char contents[1024]; >- unsigned long size, n; >+ errno = 0; >+ if (read(fd, ehdr, EI_NIDENT) != EI_NIDENT) >+ return ferr("missing or incomplete ELF header."); >+ >+ /* Check the ELF signature. >+ */ >+ 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)) >+ { >+ err("missing ELF signature."); >+ return -1; >+ } > >- size = *newsize; >- do { >- n = sizeof contents; >- if (n > size) >- n = size; >- if (lseek(fd, size - n, SEEK_SET) == (off_t)-1) >- return ferr("cannot seek in file."); >- if (read(fd, contents, n) != (ssize_t)n) >- return ferr("cannot read file contents"); >- while (n && !contents[--n]) >- --size; >- } while (size && !n); >- >- /* Sanity check. >- */ >- if (!size) >- return err("ELF file is completely blank!"); >+ /* Compare the file's class and endianness with the program's. >+ */ >+#if __BYTE_ORDER == __LITTLE_ENDIAN >+ if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) { >+ do_reverse_endian = 0; >+ } else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) { >+/* fprintf(stderr, "ELF file has different endianness.\n"); */ >+ do_reverse_endian = 1; >+ } >+#elif __BYTE_ORDER == __BIG_ENDIAN >+ if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) { >+/* fprintf(stderr, "ELF file has different endianness.\n"); */ >+ do_reverse_endian = 1; >+ } else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) { >+ do_reverse_endian = 0; >+ } >+#else >+#error unkown endianness >+#endif >+ else { >+ err("Unsupported endianness"); >+ return -1; >+ } > >- *newsize = size; >- return TRUE; >+ /* Check the target architecture. >+ */ >+/* if (EGET(ehdr->e_machine) != ELF_ARCH) { */ >+/* /\* return err("ELF file created for different architecture."); *\/ */ >+/* fprintf(stderr, "ELF file created for different architecture.\n"); */ >+/* } */ >+ return ehdr->e_ident[EI_CLASS]; > } > >-/* modifyheaders() removes references to the section header table if >- * it was stripped, and reduces program header table entries that >- * included truncated bytes at the end of the file. >- */ >-static int modifyheaders(Elf_Ehdr *ehdr, Elf_Phdr *phdrs, >- unsigned long newsize) >-{ >- Elf32_Phdr *phdr; >- int i; > >- /* If the section header table is gone, then remove all references >- * to it in the ELF header. >- */ >- if (ehdr->e_shoff >= newsize) { >- ehdr->e_shoff = 0; >- ehdr->e_shnum = 0; >- ehdr->e_shentsize = 0; >- ehdr->e_shstrndx = 0; >- } >- >- /* The program adjusts the file size of any segment that was >- * truncated. The case of a segment being completely stripped out >- * is handled separately. >- */ >- for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) { >- if (phdr->p_offset >= newsize) { >- phdr->p_offset = newsize; >- phdr->p_filesz = 0; >- } else if (phdr->p_offset + phdr->p_filesz > newsize) { >- phdr->p_filesz = newsize - phdr->p_offset; >- } >- } >+HEADER_FUNCTIONS(32) > >- return TRUE; >-} >+HEADER_FUNCTIONS(64) > >-/* commitchanges() writes the new headers back to the original file >- * and sets the file to its new size. >+/* truncatezeros() examines the bytes at the end of the file's >+ * size-to-be, and reduces the size to exclude any trailing zero >+ * bytes. > */ >-static int commitchanges(int fd, Elf_Ehdr const *ehdr, Elf_Phdr *phdrs, >- unsigned long newsize) >+static int truncatezeros(int fd, unsigned long *newsize) > { >- size_t n; >- >- /* Save the changes to the ELF header, if any. >- */ >- if (lseek(fd, 0, SEEK_SET)) >- return ferr("could not rewind file"); >- errno = 0; >- if (write(fd, ehdr, sizeof *ehdr) != sizeof *ehdr) >- return err("could not modify file"); >- >- /* Save the changes to the program segment header table, if any. >- */ >- if (lseek(fd, ehdr->e_phoff, SEEK_SET) == (off_t)-1) { >- err("could not seek in file."); >- goto warning; >- } >- n = ehdr->e_phnum * sizeof *phdrs; >- if (write(fd, phdrs, n) != (ssize_t)n) { >- err("could not write to file"); >- goto warning; >- } >- >- /* Eleventh-hour sanity check: don't truncate before the end of >- * the program segment header table. >- */ >- if (newsize < ehdr->e_phoff + n) >- newsize = ehdr->e_phoff + n; >- >- /* Chop off the end of the file. >- */ >- if (ftruncate(fd, newsize)) { >- err("could not resize file"); >- goto warning; >- } >+ unsigned char contents[1024]; >+ unsigned long size, n; > >- return TRUE; >+ size = *newsize; >+ do { >+ n = sizeof contents; >+ if (n > size) >+ n = size; >+ if (lseek(fd, size - n, SEEK_SET) == (off_t)-1) >+ return ferr("cannot seek in file."); >+ if (read(fd, contents, n) != (ssize_t)n) >+ return ferr("cannot read file contents"); >+ while (n && !contents[--n]) >+ --size; >+ } while (size && !n); >+ >+ /* Sanity check. >+ */ >+ if (!size) >+ return err("ELF file is completely blank!"); > >- warning: >- return err("ELF file may have been corrupted!"); >+ *newsize = size; >+ return TRUE; > } > > /* main() loops over the cmdline arguments, leaving all the real work >@@ -266,44 +418,66 @@ > */ > int main(int argc, char *argv[]) > { >- int fd; >- Elf_Ehdr ehdr; >- Elf_Phdr *phdrs; >- unsigned long newsize; >- char **arg; >- int failures = 0; >- >- if (argc < 2 || argv[1][0] == '-') { >- printf("Usage: sstrip FILE...\n" >- "sstrip discards all nonessential bytes from an executable.\n\n" >- "Version 2.0 Copyright (C) 2000,2001 Brian Raiter.\n" >- "This program is free software, licensed under the GNU\n" >- "General Public License. There is absolutely no warranty.\n"); >- return EXIT_SUCCESS; >- } >- >- progname = argv[0]; >- >- for (arg = argv + 1 ; *arg != NULL ; ++arg) { >- filename = *arg; >- >- fd = open(*arg, O_RDWR); >- if (fd < 0) { >- ferr("can't open"); >- ++failures; >- continue; >+ int fd; >+ union { >+ Elf32_Ehdr ehdr32; >+ Elf64_Ehdr ehdr64; >+ } e; >+ union { >+ Elf32_Phdr *phdrs32; >+ Elf64_Phdr *phdrs64; >+ } p; >+ unsigned long newsize; >+ char **arg; >+ int failures = 0; >+ >+ if (argc < 2 || argv[1][0] == '-') { >+ printf("Usage: sstrip FILE...\n" >+ "sstrip discards all nonessential bytes from an executable.\n\n" >+ "Version 2.0-X Copyright (C) 2000,2001 Brian Raiter.\n" >+ "Cross-devel hacks Copyright (C) 2004 Manuel Novoa III.\n" >+ "This program is free software, licensed under the GNU\n" >+ "General Public License. There is absolutely no warranty.\n"); >+ return EXIT_SUCCESS; > } > >- if (!(readelfheader(fd, &ehdr) && >- readphdrtable(fd, &ehdr, &phdrs) && >- getmemorysize(&ehdr, phdrs, &newsize) && >- truncatezeros(fd, &newsize) && >- modifyheaders(&ehdr, phdrs, newsize) && >- commitchanges(fd, &ehdr, phdrs, newsize))) >- ++failures; >+ progname = argv[0]; > >- close(fd); >- } >+ for (arg = argv + 1 ; *arg != NULL ; ++arg) { >+ filename = *arg; >+ >+ fd = open(*arg, O_RDWR); >+ if (fd < 0) { >+ ferr("can't open"); >+ ++failures; >+ continue; >+ } >+ >+ switch (readelfheaderident(fd, &e.ehdr32)) { >+ case ELFCLASS32: >+ if (!(readelfheader32(fd, &e.ehdr32) && >+ readphdrtable32(fd, &e.ehdr32, &p.phdrs32) && >+ getmemorysize32(&e.ehdr32, p.phdrs32, &newsize) && >+ truncatezeros(fd, &newsize) && >+ modifyheaders32(&e.ehdr32, p.phdrs32, newsize) && >+ commitchanges32(fd, &e.ehdr32, p.phdrs32, newsize))) >+ ++failures; >+ break; >+ case ELFCLASS64: >+ if (!(readelfheader64(fd, &e.ehdr64) && >+ readphdrtable64(fd, &e.ehdr64, &p.phdrs64) && >+ getmemorysize64(&e.ehdr64, p.phdrs64, &newsize) && >+ truncatezeros(fd, &newsize) && >+ modifyheaders64(&e.ehdr64, p.phdrs64, newsize) && >+ commitchanges64(fd, &e.ehdr64, p.phdrs64, newsize))) >+ ++failures; >+ break; >+ default: >+ ++failures; >+ break; >+ } >+ close(fd); >+ } > >- return failures ? EXIT_FAILURE : EXIT_SUCCESS; >+ return failures ? EXIT_FAILURE : EXIT_SUCCESS; > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 337108
:
247155
|
247243
| 251805