1 /* strings -- print the strings of printable characters in files
2 Copyright (C) 1993-2016 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19 /* Usage: strings [options] file...
24 - Scan each file in its entirety.
27 -d Scan only the initialized data section(s) of object files.
30 -f Print the name of the file before each string.
34 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
35 that are followed by a NUL or a newline. Default is 4.
38 -t {o,x,d} Print the offset within the file before each string,
41 --include-all-whitespace
42 -w By default tab and space are the only whitepace included in graphic
43 char sequences. This option considers all of isspace() valid.
45 -o Like -to. (Some other implementations have -o like -to,
46 others like -td. We chose one arbitrarily.)
48 --encoding={s,S,b,l,B,L}
50 Select character encoding: 7-bit-character, 8-bit-character,
51 bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
56 Specify a non-default object file format.
58 --output-separator=sep_string
59 -s sep_string String used to separate parsed strings in output.
63 -h Print the usage message on the standard output.
67 -v Print the program version number.
69 Written by Richard Stallman <rms@gnu.ai.mit.edu>
70 and David MacKenzie <djm@gnu.ai.mit.edu>. */
75 #include "libiberty.h"
76 #include "safe-ctype.h"
79 #define STRING_ISGRAPHIC(c) \
82 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127) \
83 || (include_all_whitespace == TRUE && ISSPACE (c))) \
90 /* The BFD section flags that identify an initialized data section. */
91 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
93 /* Radix for printing addresses (must be 8, 10 or 16). */
94 static int address_radix;
96 /* Minimum length of sequence of graphic chars to trigger output. */
97 static int string_min;
99 /* Whether or not we include all whitespace as a graphic char. */
100 static bfd_boolean include_all_whitespace;
102 /* TRUE means print address within file for each string. */
103 static bfd_boolean print_addresses;
105 /* TRUE means print filename for each string. */
106 static bfd_boolean print_filenames;
108 /* TRUE means for object files scan only the data section. */
109 static bfd_boolean datasection_only;
111 /* TRUE if we found an initialized data section in the current file. */
112 static bfd_boolean got_a_section;
114 /* The BFD object file format. */
117 /* The character encoding format. */
118 static char encoding;
119 static int encoding_bytes;
121 /* Output string used to separate parsed strings */
122 static char *output_separator;
124 static struct option long_options[] =
126 {"all", no_argument, NULL, 'a'},
127 {"data", no_argument, NULL, 'd'},
128 {"print-file-name", no_argument, NULL, 'f'},
129 {"bytes", required_argument, NULL, 'n'},
130 {"radix", required_argument, NULL, 't'},
131 {"include-all-whitespace", required_argument, NULL, 'w'},
132 {"encoding", required_argument, NULL, 'e'},
133 {"target", required_argument, NULL, 'T'},
134 {"output-separator", required_argument, NULL, 's'},
135 {"help", no_argument, NULL, 'h'},
136 {"version", no_argument, NULL, 'v'},
140 /* Records the size of a named file so that we
141 do not repeatedly run bfd_stat() on it. */
145 const char * filename;
146 bfd_size_type filesize;
147 } filename_and_size_t;
149 static void strings_a_section (bfd *, asection *, void *);
150 static bfd_boolean strings_object_file (const char *);
151 static bfd_boolean strings_file (char *);
152 static void print_strings (const char *, FILE *, file_ptr, int, int, char *);
153 static void usage (FILE *, int);
154 static long get_char (FILE *, file_ptr *, int *, char **);
156 int main (int, char **);
159 main (int argc, char **argv)
163 bfd_boolean files_given = FALSE;
167 #if defined (HAVE_SETLOCALE)
168 setlocale (LC_ALL, "");
170 bindtextdomain (PACKAGE, LOCALEDIR);
171 textdomain (PACKAGE);
173 program_name = argv[0];
174 xmalloc_set_program_name (program_name);
175 bfd_set_error_program_name (program_name);
177 expandargv (&argc, &argv);
180 include_all_whitespace = FALSE;
181 print_addresses = FALSE;
182 print_filenames = FALSE;
183 if (DEFAULT_STRINGS_ALL)
184 datasection_only = FALSE;
186 datasection_only = TRUE;
189 output_separator = NULL;
191 while ((optc = getopt_long (argc, argv, "adfhHn:wot:e:T:s:Vv0123456789",
192 long_options, (int *) 0)) != EOF)
197 datasection_only = FALSE;
201 datasection_only = TRUE;
205 print_filenames = TRUE;
213 string_min = (int) strtoul (optarg, &s, 0);
214 if (s != NULL && *s != 0)
215 fatal (_("invalid integer argument %s"), optarg);
219 include_all_whitespace = TRUE;
223 print_addresses = TRUE;
228 print_addresses = TRUE;
229 if (optarg[1] != '\0')
255 if (optarg[1] != '\0')
257 encoding = optarg[0];
261 output_separator = optarg;
266 print_version ("strings");
273 numeric_opt = optind;
278 if (numeric_opt != 0)
280 string_min = (int) strtoul (argv[numeric_opt - 1] + 1, &s, 0);
281 if (s != NULL && *s != 0)
282 fatal (_("invalid integer argument %s"), argv[numeric_opt - 1] + 1);
285 fatal (_("invalid minimum string length %d"), string_min);
306 set_default_bfd_target ();
310 datasection_only = FALSE;
311 SET_BINARY (fileno (stdin));
312 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
317 for (; optind < argc; ++optind)
319 if (strcmp (argv[optind], "-") == 0)
320 datasection_only = FALSE;
324 exit_status |= strings_file (argv[optind]) == FALSE;
332 return (exit_status);
335 /* Scan section SECT of the file ABFD, whose printable name is in
336 ARG->filename and whose size might be in ARG->filesize. If it
337 contains initialized data set `got_a_section' and print the
340 FIXME: We ought to be able to return error codes/messages for
341 certain conditions. */
344 strings_a_section (bfd *abfd, asection *sect, void *arg)
346 filename_and_size_t * filename_and_sizep;
347 bfd_size_type *filesizep;
348 bfd_size_type sectsize;
351 if ((sect->flags & DATA_FLAGS) != DATA_FLAGS)
354 sectsize = bfd_get_section_size (sect);
359 /* Get the size of the file. This might have been cached for us. */
360 filename_and_sizep = (filename_and_size_t *) arg;
361 filesizep = & filename_and_sizep->filesize;
367 if (bfd_stat (abfd, &st))
370 /* Cache the result so that we do not repeatedly stat this file. */
371 *filesizep = st.st_size;
374 /* Compare the size of the section against the size of the file.
375 If the section is bigger then the file must be corrupt and
376 we should not try dumping it. */
377 if (sectsize >= *filesizep)
380 mem = xmalloc (sectsize);
382 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sectsize))
384 got_a_section = TRUE;
386 print_strings (filename_and_sizep->filename, NULL, sect->filepos,
387 0, sectsize, (char *) mem);
393 /* Scan all of the sections in FILE, and print the strings
394 in the initialized data section(s).
396 Return TRUE if successful,
397 FALSE if not (such as if FILE is not an object file). */
400 strings_object_file (const char *file)
402 filename_and_size_t filename_and_size;
405 abfd = bfd_openr (file, target);
408 /* Treat the file as a non-object file. */
411 /* This call is mainly for its side effect of reading in the sections.
412 We follow the traditional behavior of `strings' in that we don't
413 complain if we don't recognize a file to be an object file. */
414 if (!bfd_check_format (abfd, bfd_object))
420 got_a_section = FALSE;
421 filename_and_size.filename = file;
422 filename_and_size.filesize = 0;
423 bfd_map_over_sections (abfd, strings_a_section, & filename_and_size);
425 if (!bfd_close (abfd))
431 return got_a_section;
434 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
437 strings_file (char *file)
441 /* get_file_size does not support non-S_ISREG files. */
443 if (stat (file, &st) < 0)
446 non_fatal (_("'%s': No such file"), file);
448 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
449 file, strerror (errno));
453 /* If we weren't told to scan the whole file,
454 try to open it as an object file and only look at
455 initialized data sections. If that fails, fall back to the
457 if (!datasection_only || !strings_object_file (file))
461 stream = fopen (file, FOPEN_RB);
464 fprintf (stderr, "%s: ", program_name);
469 print_strings (file, stream, (file_ptr) 0, 0, 0, (char *) 0);
471 if (fclose (stream) == EOF)
473 fprintf (stderr, "%s: ", program_name);
482 /* Read the next character, return EOF if none available.
483 Assume that STREAM is positioned so that the next byte read
484 is at address ADDRESS in the file.
486 If STREAM is NULL, do not read from it.
487 The caller can supply a buffer of characters
488 to be processed before the data in STREAM.
489 MAGIC is the address of the buffer and
490 MAGICCOUNT is how many characters are in it. */
493 get_char (FILE *stream, file_ptr *address, int *magiccount, char **magic)
498 for (i = 0; i < encoding_bytes; i++)
510 /* Only use getc_unlocked if we found a declaration for it.
511 Otherwise, libc is not thread safe by default, and we
512 should not use it. */
514 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
515 c = getc_unlocked (stream);
524 r = (r << 8) | (c & 0xff);
532 r = ((r & 0xff) << 8) | ((r & 0xff00) >> 8);
535 r = (((r & 0xff) << 24) | ((r & 0xff00) << 8)
536 | ((r & 0xff0000) >> 8) | ((r & 0xff000000) >> 24));
543 /* Find the strings in file FILENAME, read from STREAM.
544 Assume that STREAM is positioned so that the next byte read
545 is at address ADDRESS in the file.
546 Stop reading at address STOP_POINT in the file, if nonzero.
548 If STREAM is NULL, do not read from it.
549 The caller can supply a buffer of characters
550 to be processed before the data in STREAM.
551 MAGIC is the address of the buffer and
552 MAGICCOUNT is how many characters are in it.
553 Those characters come at address ADDRESS and the data in STREAM follow. */
556 print_strings (const char *filename, FILE *stream, file_ptr address,
557 int stop_point, int magiccount, char *magic)
559 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
567 /* See if the next `string_min' chars are all graphic chars. */
569 if (stop_point && address >= stop_point)
572 for (i = 0; i < string_min; i++)
574 c = get_char (stream, &address, &magiccount, &magic);
580 if (! STRING_ISGRAPHIC (c))
581 /* Found a non-graphic. Try again starting with next char. */
586 /* We found a run of `string_min' graphic characters. Print up
587 to the next non-graphic character. */
590 printf ("%s: ", filename);
592 switch (address_radix)
595 #ifdef HAVE_LONG_LONG
596 if (sizeof (start) > sizeof (long))
599 printf ("%7llo ", (unsigned long long) start);
601 printf ("%7I64o ", (unsigned long long) start);
605 #elif !BFD_HOST_64BIT_LONG
606 if (start != (unsigned long) start)
607 printf ("++%7lo ", (unsigned long) start);
610 printf ("%7lo ", (unsigned long) start);
614 #ifdef HAVE_LONG_LONG
615 if (sizeof (start) > sizeof (long))
618 printf ("%7lld ", (unsigned long long) start);
620 printf ("%7I64d ", (unsigned long long) start);
624 #elif !BFD_HOST_64BIT_LONG
625 if (start != (unsigned long) start)
626 printf ("++%7ld ", (unsigned long) start);
629 printf ("%7ld ", (long) start);
633 #ifdef HAVE_LONG_LONG
634 if (sizeof (start) > sizeof (long))
637 printf ("%7llx ", (unsigned long long) start);
639 printf ("%7I64x ", (unsigned long long) start);
643 #elif !BFD_HOST_64BIT_LONG
644 if (start != (unsigned long) start)
645 printf ("%lx%8.8lx ", (unsigned long) (start >> 32),
646 (unsigned long) (start & 0xffffffff));
649 printf ("%7lx ", (unsigned long) start);
658 c = get_char (stream, &address, &magiccount, &magic);
661 if (! STRING_ISGRAPHIC (c))
666 if (output_separator)
667 fputs (output_separator, stdout);
675 usage (FILE *stream, int status)
677 fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
678 fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n"));
679 fprintf (stream, _(" The options are:\n"));
681 if (DEFAULT_STRINGS_ALL)
682 fprintf (stream, _("\
683 -a - --all Scan the entire file, not just the data section [default]\n\
684 -d --data Only scan the data sections in the file\n"));
686 fprintf (stream, _("\
687 -a - --all Scan the entire file, not just the data section\n\
688 -d --data Only scan the data sections in the file [default]\n"));
690 fprintf (stream, _("\
691 -f --print-file-name Print the name of the file before each string\n\
692 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
693 -<number> least [number] characters (default 4).\n\
694 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
695 -w --include-all-whitespace Include all whitespace as valid string characters\n\
696 -o An alias for --radix=o\n\
697 -T --target=<BFDNAME> Specify the binary file format\n\
698 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
699 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
700 -s --output-separator=<string> String used to separate strings in output.\n\
701 @<file> Read options from <file>\n\
702 -h --help Display this information\n\
703 -v -V --version Print the program's version number\n"));
704 list_supported_targets (program_name, stream);
705 if (REPORT_BUGS_TO[0] && status == 0)
706 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);