Changeset 48 for trunk/src


Ignore:
Timestamp:
Jun 20, 2006, 10:24:47 PM (18 years ago)
Author:
rainer
Message:

Fix compile problem with sstrip.c

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sstrip.c

    r1 r48  
    33 */
    44
    5 /* #include "config_xor.h" */
     5/* Modified for portability and 64bit/32bit elf executables, Rainer Wichmann */
     6 
     7#include "config.h"
    68
    79#include        <stdio.h>
     
    1416#if !defined(__ia64)  && !defined(__ia64__)  && !defined(__itanium__) &&  \
    1517    !defined(__alpha) && !defined(__alpha__) && \
    16     (defined(__linux__) || defined(__FreeBSD__)) && \
    17     (defined(__i386__)  || defined(__i386) || defined(i386))
     18    (defined(HAVE_ELF_H) || defined(HAVE_LINUX_ELF_H)) && \
     19    (defined(__linux__)  || defined(__FreeBSD__)) && \
     20    (defined(__i386__)   || defined(__i386) || defined(i386))
    1821
    1922/* || defined(__sun) || defined(__sun__) || defined(sun) */
    2023
    21 #if defined(__linux__)
     24
     25#if defined(HAVE_ELF_H)
     26#include        <elf.h>
     27#else
    2228#include        <linux/elf.h>
    23 #else
    24 #include        <elf.h>
    2529#endif
    2630
     
    3034#endif
    3135
    32 #if ELF_CLASS == ELFCLASS32
    33 #define Elf_Ehdr        Elf32_Ehdr
    34 #define Elf_Phdr        Elf32_Phdr
    35 #else
    36 #define Elf_Ehdr        Elf64_Ehdr
    37 #define Elf_Phdr        Elf64_Phdr
    38 #endif
     36#ifndef ELFCLASS32
     37#define ELFCLASS32      1               /* 32-bit objects */
     38#endif
     39#ifndef ELFCLASS64
     40#define ELFCLASS64      2               /* 64-bit objects */
     41#endif
     42
     43
    3944
    4045/* The name of the program.
     
    6570 * munging.
    6671 */
    67 static int readelfheader(int fd, Elf_Ehdr *ehdr)
     72static int readelfheader_32(int fd, Elf32_Ehdr *ehdr)
    6873{
    6974    errno = 0;
     
    8186    /* Compare the file's class and endianness with the program's.
    8287     */
     88#ifdef ELF_DATA
    8389    if (ehdr->e_ident[EI_DATA] != ELF_DATA)
    8490        return err("ELF file has different endianness.");
    85     if (ehdr->e_ident[EI_CLASS] != ELF_CLASS)
    86         return err("ELF file has different word size.");
     91#endif
     92
     93    if (ehdr->e_ident[EI_CLASS] != ELFCLASS32)
     94        return FALSE;
    8795
    8896    /* Check the target architecture.
    8997     */
     98#ifdef ELF_ARCH
    9099    if (ehdr->e_machine != ELF_ARCH)
    91100        return err("ELF file created for different architecture.");
     101#endif
    92102
    93103    /* Verify the sizes of the ELF header and the program segment
    94104     * header table entries.
    95105     */
    96     if (ehdr->e_ehsize != sizeof(Elf_Ehdr))
     106    if (ehdr->e_ehsize != sizeof(Elf32_Ehdr))
    97107        return err("unrecognized ELF header size.");
    98     if (ehdr->e_phentsize != sizeof(Elf_Phdr))
     108    if (ehdr->e_phentsize != sizeof(Elf32_Phdr))
    99109        return err("unrecognized program segment header size.");
    100110
     
    107117}
    108118
     119static int readelfheader_64(int fd, Elf64_Ehdr *ehdr)
     120{
     121    errno = 0;
     122
     123    if (lseek(fd, 0, SEEK_SET))
     124        return ferr("could not rewind file");
     125
     126    if (read(fd, ehdr, sizeof *ehdr) != sizeof *ehdr)
     127        return ferr("missing or incomplete ELF header.");
     128
     129    /* Check the ELF signature.
     130     */
     131    if (!(ehdr->e_ident[EI_MAG0] == ELFMAG0 &&
     132          ehdr->e_ident[EI_MAG1] == ELFMAG1 &&
     133          ehdr->e_ident[EI_MAG2] == ELFMAG2 &&
     134          ehdr->e_ident[EI_MAG3] == ELFMAG3))
     135        return err("missing ELF signature.");
     136
     137    /* Compare the file's class and endianness with the program's.
     138     */
     139#ifdef ELF_DATA
     140    if (ehdr->e_ident[EI_DATA] != ELF_DATA)
     141        return err("ELF file has different endianness.");
     142#endif
     143
     144    if (ehdr->e_ident[EI_CLASS] != ELFCLASS64)
     145        return err("ELF file has different word size.");
     146
     147    /* Check the target architecture.
     148     */
     149#ifdef ELF_ARCH
     150    if (ehdr->e_machine != ELF_ARCH)
     151        return err("ELF file created for different architecture.");
     152#endif
     153
     154    /* Verify the sizes of the ELF header and the program segment
     155     * header table entries.
     156     */
     157    if (ehdr->e_ehsize != sizeof(Elf64_Ehdr))
     158        return err("unrecognized ELF header size.");
     159    if (ehdr->e_phentsize != sizeof(Elf64_Phdr))
     160        return err("unrecognized program segment header size.");
     161
     162    /* Finally, check the file type.
     163     */
     164    if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
     165        return err("not an executable or shared-object library.");
     166
     167    return TRUE;
     168}
     169
    109170/* readphdrtable() loads the program segment header table into memory.
    110171 */
    111 static int readphdrtable(int fd, Elf_Ehdr const *ehdr, Elf_Phdr **phdrs)
     172static int readphdrtable_32(int fd, Elf32_Ehdr const *ehdr, Elf32_Phdr **phdrs)
     173{
     174    size_t      size;
     175
     176    if (!ehdr->e_phoff || !ehdr->e_phnum)
     177        return err("ELF file has no program header table.");
     178
     179    size = ehdr->e_phnum * sizeof **phdrs;
     180    if (!(*phdrs = malloc(size)))
     181        return err("Out of memory!");
     182
     183    errno = 0;
     184    if (read(fd, *phdrs, size) != (ssize_t)size)
     185        return ferr("missing or incomplete program segment header table.");
     186
     187    return TRUE;
     188}
     189
     190static int readphdrtable_64(int fd, Elf64_Ehdr const *ehdr, Elf64_Phdr **phdrs)
    112191{
    113192    size_t      size;
     
    132211 * is executing, and thus can be safely discarded.)
    133212 */
    134 static int getmemorysize(Elf_Ehdr const *ehdr, Elf_Phdr const *phdrs,
    135                          unsigned long *newsize)
    136 {
    137     Elf_Phdr   const   *phdr;
     213static int getmemorysize_32(Elf32_Ehdr const *ehdr, Elf32_Phdr const *phdrs,
     214                            unsigned long *newsize)
     215{
     216    Elf32_Phdr   const   *phdr;
    138217    unsigned long       size, n;
    139218    int                 i;
     219
     220    /* Start by setting the size to include the ELF header and the
     221     * complete program segment header table.
     222     */
     223    size = ehdr->e_phoff + ehdr->e_phnum * sizeof *phdrs;
     224    if (size < sizeof *ehdr)
     225        size = sizeof *ehdr;
     226
     227    /* Then keep extending the size to include whatever data the
     228     * program segment header table references.
     229     */
     230    for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) {
     231        if (phdr->p_type != PT_NULL) {
     232            n = phdr->p_offset + phdr->p_filesz;
     233            if (n > size)
     234                size = n;
     235        }
     236    }
     237
     238    *newsize = size;
     239    return TRUE;
     240}
     241
     242static int getmemorysize_64(Elf64_Ehdr const *ehdr, Elf64_Phdr const *phdrs,
     243                            unsigned long *newsize)
     244{
     245    Elf64_Phdr   const   *phdr;
     246    unsigned long         size, n;
     247    int                   i;
    140248
    141249    /* Start by setting the size to include the ELF header and the
     
    196304 * included truncated bytes at the end of the file.
    197305 */
    198 static int modifyheaders(Elf_Ehdr *ehdr, Elf_Phdr *phdrs,
    199                          unsigned long newsize)
    200 {
    201     Elf_Phdr   *phdr;
    202     int         i;
     306static int modifyheaders_32(Elf32_Ehdr *ehdr, Elf32_Phdr *phdrs,
     307                            unsigned long newsize)
     308{
     309    Elf32_Phdr   *phdr;
     310    int           i;
    203311
    204312    /* If the section header table is gone, then remove all references
     
    228336}
    229337
     338static int modifyheaders_64(Elf64_Ehdr *ehdr, Elf64_Phdr *phdrs,
     339                            unsigned long newsize)
     340{
     341    Elf64_Phdr   *phdr;
     342    int           i;
     343
     344    /* If the section header table is gone, then remove all references
     345     * to it in the ELF header.
     346     */
     347    if (ehdr->e_shoff >= newsize) {
     348        ehdr->e_shoff = 0;
     349        ehdr->e_shnum = 0;
     350        ehdr->e_shentsize = 0;
     351        ehdr->e_shstrndx = 0;
     352    }
     353
     354    /* The program adjusts the file size of any segment that was
     355     * truncated. The case of a segment being completely stripped out
     356     * is handled separately.
     357     */
     358    for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) {
     359        if (phdr->p_offset >= newsize) {
     360            phdr->p_offset = newsize;
     361            phdr->p_filesz = 0;
     362        } else if (phdr->p_offset + phdr->p_filesz > newsize) {
     363            phdr->p_filesz = newsize - phdr->p_offset;
     364        }
     365    }
     366
     367    return TRUE;
     368}
     369
    230370/* commitchanges() writes the new headers back to the original file
    231371 * and sets the file to its new size.
    232372 */
    233 static int commitchanges(int fd, Elf_Ehdr const *ehdr, Elf_Phdr *phdrs,
    234                          unsigned long newsize)
     373static int commitchanges_32(int fd, Elf32_Ehdr const *ehdr, Elf32_Phdr *phdrs,
     374                            unsigned long newsize)
    235375{
    236376    size_t      n;
     
    275415}
    276416
     417static int commitchanges_64(int fd, Elf64_Ehdr const *ehdr, Elf64_Phdr *phdrs,
     418                            unsigned long newsize)
     419{
     420    size_t      n;
     421
     422    /* Save the changes to the ELF header, if any.
     423     */
     424    if (lseek(fd, 0, SEEK_SET))
     425        return ferr("could not rewind file");
     426    errno = 0;
     427    if (write(fd, ehdr, sizeof *ehdr) != sizeof *ehdr)
     428        return err("could not modify file");
     429
     430    /* Save the changes to the program segment header table, if any.
     431     */
     432    if (lseek(fd, ehdr->e_phoff, SEEK_SET) == (off_t)-1) {
     433        err("could not seek in file.");
     434        goto warning;
     435    }
     436    n = ehdr->e_phnum * sizeof *phdrs;
     437    if (write(fd, phdrs, n) != (ssize_t)n) {
     438        err("could not write to file");
     439        goto warning;
     440    }
     441
     442    /* Eleventh-hour sanity check: don't truncate before the end of
     443     * the program segment header table.
     444     */
     445    if (newsize < ehdr->e_phoff + n)
     446        newsize = ehdr->e_phoff + n;
     447
     448    /* Chop off the end of the file.
     449     */
     450    if (ftruncate(fd, newsize)) {
     451        err("could not resize file");
     452        goto warning;
     453    }
     454
     455    return TRUE;
     456
     457  warning:
     458    return err("ELF file may have been corrupted!");
     459}
     460
    277461/* main() loops over the cmdline arguments, leaving all the real work
    278462 * to the other functions.
     
    281465{
    282466    int                 fd;
    283     Elf_Ehdr            ehdr;
    284     Elf_Phdr           *phdrs = NULL;
     467    int                 is_32bit_elf;
     468    Elf32_Ehdr          ehdr32;
     469    Elf32_Phdr         *phdrs32 = NULL;
     470    Elf64_Ehdr          ehdr64;
     471    Elf64_Phdr         *phdrs64 = NULL;
    285472    unsigned long       newsize;
    286473    char              **arg;
     
    308495        }
    309496
    310         if (!(readelfheader(fd, &ehdr)                  &&
    311               readphdrtable(fd, &ehdr, &phdrs)          &&
    312               getmemorysize(&ehdr, phdrs, &newsize)     &&
    313               truncatezeros(fd, &newsize)               &&
    314               modifyheaders(&ehdr, phdrs, newsize)      &&
    315               commitchanges(fd, &ehdr, phdrs, newsize)))
     497        if (readelfheader_32(fd, &ehdr32)) {
     498          is_32bit_elf = TRUE;
     499        }
     500        else if (readelfheader_64(fd, &ehdr64)) {
     501          is_32bit_elf = FALSE;
     502        }
     503        else {
     504          close(fd);
     505          return EXIT_FAILURE;
     506        }
     507
     508        if (is_32bit_elf) {
     509          if (!(readphdrtable_32(fd, &ehdr32, &phdrs32)         &&
     510              getmemorysize_32(&ehdr32, phdrs32, &newsize)      &&
     511              truncatezeros(fd, &newsize)                       &&
     512              modifyheaders_32(&ehdr32, phdrs32, newsize)       &&
     513              commitchanges_32(fd, &ehdr32, phdrs32, newsize)))
    316514            ++failures;
     515        }
     516        else {
     517          if (!(readphdrtable_64(fd, &ehdr64, &phdrs64)         &&
     518              getmemorysize_64(&ehdr64, phdrs64, &newsize)      &&
     519              truncatezeros(fd, &newsize)                       &&
     520              modifyheaders_64(&ehdr64, phdrs64, newsize)       &&
     521              commitchanges_64(fd, &ehdr64, phdrs64, newsize)))
     522            ++failures;
     523        }
    317524
    318525        close(fd);
Note: See TracChangeset for help on using the changeset viewer.