diff options
author | emaste <emaste@FreeBSD.org> | 2014-11-27 20:12:13 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2014-11-27 20:12:13 +0000 |
commit | b09a2340ee89cb9c8c414aaf7b8b267bfc5653ae (patch) | |
tree | 49421ff690e54a53267da358fb3f85c8e1600eb5 /contrib/elftoolchain/strings | |
parent | 50fd85b21cc1520575b04bfc8a5671fe07072c53 (diff) | |
parent | 9ee78763690833f42af4a97b77baf30edbca5314 (diff) | |
download | FreeBSD-src-b09a2340ee89cb9c8c414aaf7b8b267bfc5653ae.zip FreeBSD-src-b09a2340ee89cb9c8c414aaf7b8b267bfc5653ae.tar.gz |
Copy elftoolchain binutils replacements from vendor branch
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'contrib/elftoolchain/strings')
-rw-r--r-- | contrib/elftoolchain/strings/Makefile | 11 | ||||
-rw-r--r-- | contrib/elftoolchain/strings/strings.1 | 162 | ||||
-rw-r--r-- | contrib/elftoolchain/strings/strings.c | 454 |
3 files changed, 627 insertions, 0 deletions
diff --git a/contrib/elftoolchain/strings/Makefile b/contrib/elftoolchain/strings/Makefile new file mode 100644 index 0000000..0bc4cd5 --- /dev/null +++ b/contrib/elftoolchain/strings/Makefile @@ -0,0 +1,11 @@ +# $Id: Makefile 2044 2011-10-23 14:52:59Z jkoshy $ + +TOP= .. + +PROG= strings +WARNS?= 6 +DPADD= ${LIBELFTC} ${LIBELF} +LDADD= -lelftc -lelf + +.include "${TOP}/mk/elftoolchain.prog.mk" + diff --git a/contrib/elftoolchain/strings/strings.1 b/contrib/elftoolchain/strings/strings.1 new file mode 100644 index 0000000..d6816494 --- /dev/null +++ b/contrib/elftoolchain/strings/strings.1 @@ -0,0 +1,162 @@ +.\" Copyright (c) 2007 S.Sam Arun Raj +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: strings.1 2352 2011-12-19 11:21:10Z jkoshy $ +.\" +.Dd December 19, 2011 +.Dt STRINGS 1 +.Os +.Sh NAME +.Nm strings +.Nd "print the strings of printable characters in files" +.Sh SYNOPSIS +.Nm +.Op Fl a | Fl -all +.Op Fl e Ar encoding | Fl -encoding= Ns Ar encoding +.Op Fl f | Fl -print-file-name +.Op Fl h | Fl -help +.Op Fl n Ar number | Fl -bytes= Ns Ar number | Fl Ar number +.Op Fl o +.Op Fl t Ar radix | Fl -radix= Ns Ar radix +.Op Fl v | Fl -version +.Op Ar +.Sh DESCRIPTION +For each +.Ar file +specified, the +.Nm +utility prints contiguous sequences of printable +characters that are at least +.Va n +characters long and are followed by an unprintable character. +The default value of +.Va n +is 4. +By default, the +.Nm +utility only scans the initialized and loaded sections of ELF objects; +for other file types, the entire file is scanned. +The +.Nm +utility is mainly used for determining the contents of non-text files. +.Pp +If no file name is specified as an argument, standard input is read. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl a | Fl -all +For ELF objects, scan the entire file for printable strings. +.It Fl e Ar encoding | Fl -encoding= Ns Ar encoding +Select the character encoding to be used while searching for strings. +Valid values for argument +.Ar encoding +are: +.Bl -tag -width indent -compact +.It Ar s +for single 7-bit-byte characters (ASCII, ISO 8859). +.It Ar S +for single 8-bit-byte characters. +.It Ar l +for 16-bit little-endian. +.It Ar b +for 16-bit big-endian. +.It Ar L +for 32-bit little-endian. +.It Ar B +for 32-bit big-endian. +.El +The default is to assume that characters are encoded using a single +7-bit byte. +.It Fl f | Fl -print-file-name +Print the name of the file before each string. +.It Fl h | Fl -help +Print a usage summary and exit. +.It Xo +.Fl n Ar number | +.Fl -bytes= Ns Ar number | +.Fl Ar number +.Xc +Print the contiguous character sequence of at least +.Ar number +characters long, instead of the default of 4 characters. +.It Fl o +Equivalent to specifying +.Fl t Ar o . +.It Fl t Ar radix | Fl -radix= Ns Ar radix +Print the offset from the start of the file before each string +using the specified radix. +Valid values for argument +.Ar radix +are: +.Bl -tag -width indent -compact +.It Ar d +for decimal +.It Ar o +for octal +.It Ar x +for hexadecimal +.El +.It Fl v | Fl -version +Display a version identifier and exit. +.El +.Sh EXIT STATUS +.Ex -std +.Sh EXAMPLES +To display strings in +.Pa /bin/ls +use: +.Dl "$ strings /bin/ls" +.Pp +To display strings in all sections of +.Pa /bin/ln +use: +.Dl "$ strings -a /bin/ln" +.Pp +To display strings in all sections of +.Pa /bin/cat +prefixed with the filename and the offset within the file use: +.Dl "$ strings -a -f -t x /bin/cat" +.Sh SEE ALSO +.Xr ar 1 , +.Xr nm 1 , +.Xr objdump 1 , +.Xr ranlib , +.Xr readelf 1 , +.Xr size 1 +.Sh HISTORY +The first FreeBSD +.Nm +utility appeared in +.Fx v3. +It was later discontinued in +.Fx v5 , +when i386-only a.out format was dropped in favor of ELF. +.Sh AUTHORS +.An -nosplit +The +.Nm +utility was re-written by +.An S.Sam Arun Raj Aq samarunraj@gmail.com . +This manual page was written by +.An S.Sam Arun Raj Aq samarunraj@gmail.com . diff --git a/contrib/elftoolchain/strings/strings.c b/contrib/elftoolchain/strings/strings.c new file mode 100644 index 0000000..c936d5c --- /dev/null +++ b/contrib/elftoolchain/strings/strings.c @@ -0,0 +1,454 @@ +/*- + * Copyright (c) 2007 S.Sam Arun Raj + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <inttypes.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <libelf.h> +#include <libelftc.h> +#include <gelf.h> + +#include "_elftc.h" + +ELFTC_VCSID("$Id: strings.c 2351 2011-12-19 11:20:37Z jkoshy $"); + +enum return_code { + RETURN_OK, + RETURN_NOINPUT, + RETURN_SOFTWARE +}; + +enum radix_style { + RADIX_DECIMAL, + RADIX_HEX, + RADIX_OCTAL +}; + +enum encoding_style { + ENCODING_7BIT, + ENCODING_8BIT, + ENCODING_16BIT_BIG, + ENCODING_16BIT_LITTLE, + ENCODING_32BIT_BIG, + ENCODING_32BIT_LITTLE +}; + +#define PRINTABLE(c) \ + ((c) >= 0 && (c) <= 255 && \ + ((c) == '\t' || isprint((c)) || \ + (encoding == ENCODING_8BIT && (c) > 127))) + + +int encoding_size, entire_file, min_len, show_filename, show_loc; +enum encoding_style encoding; +enum radix_style radix; + +static struct option strings_longopts[] = { + { "all", no_argument, NULL, 'a'}, + { "bytes", required_argument, NULL, 'n'}, + { "encoding", required_argument, NULL, 'e'}, + { "help", no_argument, NULL, 'h'}, + { "print-file-name", no_argument, NULL, 'f'}, + { "radix", required_argument, NULL, 't'}, + { "version", no_argument, NULL, 'v'}, + { NULL, 0, NULL, 0 } +}; + +long getcharacter(void); +int handle_file(const char *); +int handle_elf(const char *, int); +int handle_binary(const char *, int); +int find_strings(const char *, off_t, off_t); +void show_version(void); +void usage(void); + +/* + * strings(1) extracts text(contiguous printable characters) + * from elf and binary files. + */ +int +main(int argc, char **argv) +{ + int ch, rc; + + rc = RETURN_OK; + min_len = 0; + encoding_size = 1; + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EXIT_FAILURE, "ELF library initialization failed: %s", + elf_errmsg(-1)); + + while ((ch = getopt_long(argc, argv, "1234567890ae:fhn:ot:Vv", + strings_longopts, NULL)) != -1) + switch((char)ch) { + case 'a': + entire_file = 1; + break; + case 'e': + if (*optarg == 's') { + encoding = ENCODING_7BIT; + } else if (*optarg == 'S') { + encoding = ENCODING_8BIT; + } else if (*optarg == 'b') { + encoding = ENCODING_16BIT_BIG; + encoding_size = 2; + } else if (*optarg == 'B') { + encoding = ENCODING_32BIT_BIG; + encoding_size = 4; + } else if (*optarg == 'l') { + encoding = ENCODING_16BIT_LITTLE; + encoding_size = 2; + } else if (*optarg == 'L') { + encoding = ENCODING_32BIT_LITTLE; + encoding_size = 4; + } else + usage(); + /* NOTREACHED */ + break; + case 'f': + show_filename = 1; + break; + case 'n': + min_len = (int)strtoimax(optarg, (char**)NULL, 10); + break; + case 'o': + show_loc = 1; + radix = RADIX_OCTAL; + break; + case 't': + show_loc = 1; + if (*optarg == 'd') + radix = RADIX_DECIMAL; + else if (*optarg == 'o') + radix = RADIX_OCTAL; + else if (*optarg == 'x') + radix = RADIX_HEX; + else + usage(); + /* NOTREACHED */ + break; + case 'v': + case 'V': + show_version(); + /* NOTREACHED */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + min_len *= 10; + min_len += ch - '0'; + break; + case 'h': + case '?': + default: + usage(); + /* NOTREACHED */ + } + argc -= optind; + argv += optind; + + if (!min_len) + min_len = 4; + if (!*argv) + rc = handle_file("{standard input}"); + else while (*argv) { + rc = handle_file(*argv); + argv++; + } + return (rc); +} + +int +handle_file(const char *name) +{ + int fd, rt; + + if (name == NULL) + return (RETURN_NOINPUT); + if (strcmp("{standard input}", name) != 0) { + if (freopen(name, "rb", stdin) == NULL) { + warnx("'%s': %s", name, strerror(errno)); + return (RETURN_NOINPUT); + } + } else { + return (find_strings(name, (off_t)0, (off_t)0)); + } + + fd = fileno(stdin); + if (fd < 0) + return (RETURN_NOINPUT); + rt = handle_elf(name, fd); + return (rt); +} + +/* + * Files not understood by handle_elf, will be passed off here and will + * treated as a binary file. This would include text file, core dumps ... + */ +int +handle_binary(const char *name, int fd) +{ + struct stat buf; + + memset(&buf, 0, sizeof(struct stat)); + (void) lseek(fd, (off_t)0, SEEK_SET); + if (!fstat(fd, &buf)) + return (find_strings(name, (off_t)0, buf.st_size)); + return (RETURN_SOFTWARE); +} + +/* + * Will analyse a file to see if it ELF, other files including ar(1), + * core dumps are passed off and treated as flat binary files. Unlike + * GNU size in FreeBSD this routine will not treat ELF object from + * different archs as flat binary files(has to overridden using -a). + */ +int +handle_elf(const char *name, int fd) +{ + GElf_Ehdr elfhdr; + GElf_Shdr shdr; + Elf *elf; + Elf_Scn *scn; + int rc; + + rc = RETURN_OK; + /* If entire file is choosen, treat it as a binary file */ + if (entire_file) + return (handle_binary(name, fd)); + + (void) lseek(fd, (off_t)0, SEEK_SET); + elf = elf_begin(fd, ELF_C_READ, NULL); + if (elf_kind(elf) != ELF_K_ELF) { + (void) elf_end(elf); + return (handle_binary(name, fd)); + } + + if (gelf_getehdr(elf, &elfhdr) == NULL) { + (void) elf_end(elf); + warnx("%s: ELF file could not be processed", name); + return (RETURN_SOFTWARE); + } + + if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { + (void) elf_end(elf); + return (handle_binary(name, fd)); + } else { + scn = NULL; + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) == NULL) + continue; + if (shdr.sh_type != SHT_NOBITS && + (shdr.sh_flags & SHF_ALLOC) != 0) { + rc = find_strings(name, shdr.sh_offset, + shdr.sh_size); + } + } + } + (void) elf_end(elf); + return (rc); +} + +/* + * Retrieves a character from input stream based on the encoding + * type requested. + */ +long +getcharacter(void) +{ + long rt; + int i; + char buf[4], c; + + rt = EOF; + for(i = 0; i < encoding_size; i++) { + c = getc(stdin); + if (feof(stdin)) + return (EOF); + buf[i] = c; + } + + switch(encoding) { + case ENCODING_7BIT: + case ENCODING_8BIT: + rt = buf[0]; + break; + case ENCODING_16BIT_BIG: + rt = (buf[0] << 8) | buf[1]; + break; + case ENCODING_16BIT_LITTLE: + rt = buf[0] | (buf[1] << 8); + break; + case ENCODING_32BIT_BIG: + rt = ((long) buf[0] << 24) | ((long) buf[1] << 16) | + ((long) buf[2] << 8) | buf[3]; + break; + case ENCODING_32BIT_LITTLE: + rt = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) | + ((long) buf[3] << 24); + break; + } + return (rt); +} + +/* + * Input stream stdin is read until the end of file is reached or until + * the section size is reached in case of ELF files. Contiguous + * characters of >= min_size(default 4) will be displayed. + */ +int +find_strings(const char *name, off_t offset, off_t size) +{ + off_t cur_off, start_off; + char *obuf; + long c; + int i; + + if ((obuf = (char*)calloc(1, min_len + 1)) == NULL) { + (void) fprintf(stderr, "Unable to allocate memory: %s\n", + strerror(errno)); + return (RETURN_SOFTWARE); + } + + (void) fseeko(stdin, offset, SEEK_SET); + cur_off = offset; + start_off = 0; + while(1) { + if ((offset + size) && (cur_off >= offset + size)) + break; + start_off = cur_off; + memset(obuf, 0, min_len+1); + for(i = 0; i < min_len; i++) { + c = getcharacter(); + if (c == EOF && feof(stdin)) + goto _exit1; + if (PRINTABLE(c)) { + obuf[i] = c; + obuf[i+1] = 0; + cur_off += encoding_size; + } else { + if (encoding == ENCODING_8BIT && + (uint8_t)c > 127) { + obuf[i] = c; + obuf[i+1] = 0; + cur_off += encoding_size; + continue; + } + cur_off += encoding_size; + break; + } + } + + if (i >= min_len && ((cur_off <= offset + size) || + !(offset + size))) { + if (show_filename) + printf ("%s: ", name); + if (show_loc) { + switch(radix) { + case RADIX_DECIMAL: + (void) printf("%7ju ", + (uintmax_t)start_off); + break; + case RADIX_HEX: + (void) printf("%7jx ", + (uintmax_t)start_off); + break; + case RADIX_OCTAL: + (void) printf("%7jo ", + (uintmax_t)start_off); + break; + } + } + printf("%s", obuf); + + while(1) { + if ((offset + size) && + (cur_off >= offset + size)) + break; + c = getcharacter(); + cur_off += encoding_size; + if (encoding == ENCODING_8BIT && + (uint8_t)c > 127) { + putchar(c); + continue; + } + if (!PRINTABLE(c) || c == EOF) + break; + putchar(c); + } + putchar('\n'); + } + } +_exit1: + free(obuf); + return (RETURN_OK); +} + +#define USAGE_MESSAGE "\ +Usage: %s [options] [file...]\n\ + Print contiguous sequences of printable characters.\n\n\ + Options:\n\ + -a | --all Scan the entire file for strings.\n\ + -e ENC | --encoding=ENC Select the character encoding to use.\n\ + -f | --print-file-name Print the file name before each string.\n\ + -h | --help Print a help message and exit.\n\ + -n N | --bytes=N | -N Print sequences with 'N' or more characters.\n\ + -o Print offsets in octal.\n\ + -t R | --radix=R Print offsets using the radix named by 'R'.\n\ + -v | --version Print a version identifier and exit.\n" + +void +usage(void) +{ + (void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); + exit(EXIT_FAILURE); +} + +void +show_version(void) +{ + (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); + exit(EXIT_SUCCESS); +} |