From b46fe1c707bc971ac7c06b7545b21c666349f7f9 Mon Sep 17 00:00:00 2001 From: mbm Date: Tue, 17 Aug 2004 23:00:52 +0000 Subject: sstrip, nas support, mppe support, mac os x patches, syslogd on bootup, inittab correction git-svn-id: svn://svn.openwrt.org/openwrt/trunk@136 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../sources/openwrt/tools/addpattern.c | 2 +- obsolete-buildroot/sources/openwrt/tools/sstrip.c | 327 +++++++++++++++++++++ obsolete-buildroot/sources/openwrt/tools/trx.c | 44 ++- 3 files changed, 359 insertions(+), 14 deletions(-) create mode 100644 obsolete-buildroot/sources/openwrt/tools/sstrip.c (limited to 'obsolete-buildroot/sources/openwrt/tools') diff --git a/obsolete-buildroot/sources/openwrt/tools/addpattern.c b/obsolete-buildroot/sources/openwrt/tools/addpattern.c index dbf8ed690..b32ab9f49 100644 --- a/obsolete-buildroot/sources/openwrt/tools/addpattern.c +++ b/obsolete-buildroot/sources/openwrt/tools/addpattern.c @@ -84,7 +84,7 @@ int main(int argc, char **argv) time_t t; struct tm *ptm; - fprintf(stderr, "mjn3's addpattern replacement - v0.80\n"); + fprintf(stderr, "mjn3's addpattern replacement - v0.81\n"); hdr = (struct code_header *) buf; diff --git a/obsolete-buildroot/sources/openwrt/tools/sstrip.c b/obsolete-buildroot/sources/openwrt/tools/sstrip.c new file mode 100644 index 000000000..32769fff6 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/tools/sstrip.c @@ -0,0 +1,327 @@ +/* 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. + */ + +#define __MIPSEL__ 1 +#define _MIPS_SZLONG 32 + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#include + +#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; + +/* The name of the current file. + */ +static char const *filename; + + +/* A simple error-handling function. FALSE is always returned for the + * convenience of the caller. + */ +static int err(char const *errmsg) +{ + 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. + */ +#define ferr(msg) (err(errno ? strerror(errno) : (msg))) + +/* 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(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."); + + return TRUE; +} + +/* readphdrtable() loads the program segment header table into memory. + */ +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."); + + 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; +} + +/* 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. + */ +static int truncatezeros(int fd, unsigned long *newsize) +{ + unsigned char contents[1024]; + unsigned long size, n; + + 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!"); + + *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(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; + } + } + + return TRUE; +} + +/* commitchanges() writes the new headers back to the original file + * and sets the file to its new size. + */ +static int commitchanges(int fd, Elf_Ehdr const *ehdr, Elf_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, 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; + } + + return TRUE; + + warning: + return err("ELF file may have been corrupted!"); +} + +/* main() loops over the cmdline arguments, leaving all the real work + * to the other functions. + */ +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; + } + + 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; + + close(fd); + } + + return failures ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/obsolete-buildroot/sources/openwrt/tools/trx.c b/obsolete-buildroot/sources/openwrt/tools/trx.c index 5ec53fdcb..f029dc5fb 100644 --- a/obsolete-buildroot/sources/openwrt/tools/trx.c +++ b/obsolete-buildroot/sources/openwrt/tools/trx.c @@ -26,6 +26,10 @@ * .trx file using '-m'. It will be rounded up to be a multiple of 4K. * NOTE: This space will be malloc()'d. * + * August 16, 2004 + * + * Sigh... Make it endian-neutral. + * * TODO: Support '-b' option to specify offsets for each file. */ @@ -36,6 +40,16 @@ #include #include #include +#include +#include + +#if __BYTE_ORDER == __BIG_ENDIAN +#define STORE32_LE(X) bswap_32(X) +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define STORE32_LE(X) (X) +#else +#error unkown endianness! +#endif uint32_t crc32buf(char *buf, size_t len); @@ -74,10 +88,11 @@ int main(int argc, char **argv) char *e; int c, i; size_t n; + uint32_t cur_len; unsigned long maxlen = TRX_MAX_LEN; struct trx_header *p; - fprintf(stderr, "mjn3's trx replacement - v0.80\n"); + fprintf(stderr, "mjn3's trx replacement - v0.81\n"); while ((c = getopt(argc, argv, "o:m:")) != -1) { switch (c) { @@ -132,21 +147,21 @@ int main(int argc, char **argv) p = (struct trx_header *) buf; - p->magic = TRX_MAGIC; - p->len = sizeof(struct trx_header); - p->flag_version = (TRX_VERSION << 16); + p->magic = STORE32_LE(TRX_MAGIC); + cur_len = sizeof(struct trx_header); + p->flag_version = STORE32_LE((TRX_VERSION << 16)); i = 0; while (optind < argc) { - p->offsets[i++] = p->len; + p->offsets[i++] = STORE32_LE(cur_len); if (!(in = fopen(argv[optind], "r"))) { fprintf(stderr, "can not open \"%s\" for reading\n", argv[optind]); usage(); } - n = fread(buf + p->len, 1, maxlen - p->len, in); + n = fread(buf + cur_len, 1, maxlen - cur_len, in); if (!feof(in)) { fprintf(stderr, "fread failure or file \"%s\" too large\n", argv[optind]); @@ -162,26 +177,29 @@ int main(int argc, char **argv) #undef ROUND #define ROUND 4 if (n & (ROUND-1)) { - memset(buf + p->len + n, 0, ROUND - (n & (ROUND-1))); + memset(buf + cur_len + n, 0, ROUND - (n & (ROUND-1))); n += ROUND - (n & (ROUND-1)); } } - p->len += n; + cur_len += n; } #undef ROUND #define ROUND 0x1000 - n = p->len & (ROUND-1); + n = cur_len & (ROUND-1); if (n) { - memset(buf + p->len, 0, ROUND - n); - p->len += ROUND - n; + memset(buf + cur_len, 0, ROUND - n); + cur_len += ROUND - n; } p->crc32 = crc32buf((char *) &p->flag_version, - p->len - offsetof(struct trx_header, flag_version)); + cur_len - offsetof(struct trx_header, flag_version)); + p->crc32 = STORE32_LE(p->crc32); + + p->len = STORE32_LE(cur_len); - if (!fwrite(buf, p->len, 1, out) || fflush(out)) { + if (!fwrite(buf, cur_len, 1, out) || fflush(out)) { fprintf(stderr, "fwrite failed\n"); return EXIT_FAILURE; } -- cgit v1.2.3