1 /* strings -- print the strings of printable characters in files
2 Copyright (C) 1993-2014 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 - Do not scan only the initialized data section of object files.
27 -f Print the name of the file before each string.
31 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
32 that are followed by a NUL or a newline. Default is 4.
35 -t {o,x,d} Print the offset within the file before each string,
38 -o Like -to. (Some other implementations have -o like -to,
39 others like -td. We chose one arbitrarily.)
41 --encoding={s,S,b,l,B,L}
43 Select character encoding: 7-bit-character, 8-bit-character,
44 bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
49 Specify a non-default object file format.
52 -h Print the usage message on the standard output.
56 -v Print the program version number.
64 #include "libiberty.h"
65 #include "safe-ctype.h"
68 #define STRING_ISGRAPHIC(c) \
71 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
77 /* The BFD section flags that identify an initialized data section. */
78 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
80 /* Radix for printing addresses (must be 8, 10 or 16). */
81 static int address_radix;
83 /* Minimum length of sequence of graphic chars to trigger output. */
84 static int string_min;
86 /* TRUE means print address within file for each string. */
87 static bfd_boolean print_addresses;
89 /* TRUE means print filename for each string. */
90 static bfd_boolean print_filenames;
92 /* TRUE means for object files scan only the data section. */
93 static bfd_boolean datasection_only;
95 /* TRUE if we found an initialized data section in the current file. */
96 static bfd_boolean got_a_section;
98 /* The BFD object file format. */
101 /* The character encoding format. */
102 static char encoding;
103 static int encoding_bytes;
105 static struct option long_options[] =
107 {"all", no_argument, NULL, 'a'},
108 {"print-file-name", no_argument, NULL, 'f'},
109 {"bytes", required_argument, NULL, 'n'},
110 {"radix", required_argument, NULL, 't'},
111 {"encoding", required_argument, NULL, 'e'},
112 {"target", required_argument, NULL, 'T'},
113 {"help", no_argument, NULL, 'h'},
114 {"version", no_argument, NULL, 'v'},
118 /* Records the size of a named file so that we
119 do not repeatedly run bfd_stat() on it. */
123 const char * filename;
124 bfd_size_type filesize;
125 } filename_and_size_t;
127 static void strings_a_section (bfd *, asection *, void *);
128 static bfd_boolean strings_object_file (const char *);
129 static bfd_boolean strings_file (char *file);
130 static void print_strings (const char *, FILE *, file_ptr, int, int, char *);
131 static void usage (FILE *, int);
132 static long get_char (FILE *, file_ptr *, int *, char **);
134 int main (int, char **);
137 main (int argc, char **argv)
141 bfd_boolean files_given = FALSE;
145 #if defined (HAVE_SETLOCALE)
146 setlocale (LC_ALL, "");
148 bindtextdomain (PACKAGE, LOCALEDIR);
149 textdomain (PACKAGE);
151 program_name = argv[0];
152 xmalloc_set_program_name (program_name);
154 expandargv (&argc, &argv);
157 print_addresses = FALSE;
158 print_filenames = FALSE;
159 datasection_only = TRUE;
163 while ((optc = getopt_long (argc, argv, "afhHn:ot:e:T:Vv0123456789",
164 long_options, (int *) 0)) != EOF)
169 datasection_only = FALSE;
173 print_filenames = TRUE;
181 string_min = (int) strtoul (optarg, &s, 0);
182 if (s != NULL && *s != 0)
183 fatal (_("invalid integer argument %s"), optarg);
187 print_addresses = TRUE;
192 print_addresses = TRUE;
193 if (optarg[1] != '\0')
219 if (optarg[1] != '\0')
221 encoding = optarg[0];
226 print_version ("strings");
233 numeric_opt = optind;
238 if (numeric_opt != 0)
240 string_min = (int) strtoul (argv[numeric_opt - 1] + 1, &s, 0);
241 if (s != NULL && *s != 0)
242 fatal (_("invalid integer argument %s"), argv[numeric_opt - 1] + 1);
245 fatal (_("invalid minimum string length %d"), string_min);
266 set_default_bfd_target ();
270 datasection_only = FALSE;
271 SET_BINARY (fileno (stdin));
272 print_strings ("{standard input}", stdin, 0, 0, 0, (char *) NULL);
277 for (; optind < argc; ++optind)
279 if (strcmp (argv[optind], "-") == 0)
280 datasection_only = FALSE;
284 exit_status |= strings_file (argv[optind]) == FALSE;
292 return (exit_status);
295 /* Scan section SECT of the file ABFD, whose printable name is in
296 ARG->filename and whose size might be in ARG->filesize. If it
297 contains initialized data set `got_a_section' and print the
300 FIXME: We ought to be able to return error codes/messages for
301 certain conditions. */
304 strings_a_section (bfd *abfd, asection *sect, void *arg)
306 filename_and_size_t * filename_and_sizep;
307 bfd_size_type *filesizep;
308 bfd_size_type sectsize;
311 if ((sect->flags & DATA_FLAGS) != DATA_FLAGS)
314 sectsize = bfd_get_section_size (sect);
319 /* Get the size of the file. This might have been cached for us. */
320 filename_and_sizep = (filename_and_size_t *) arg;
321 filesizep = & filename_and_sizep->filesize;
327 if (bfd_stat (abfd, &st))
330 /* Cache the result so that we do not repeatedly stat this file. */
331 *filesizep = st.st_size;
334 /* Compare the size of the section against the size of the file.
335 If the section is bigger then the file must be corrupt and
336 we should not try dumping it. */
337 if (sectsize >= *filesizep)
340 mem = xmalloc (sectsize);
342 if (bfd_get_section_contents (abfd, sect, mem, (file_ptr) 0, sectsize))
344 got_a_section = TRUE;
346 print_strings (filename_and_sizep->filename, NULL, sect->filepos,
347 0, sectsize, (char *) mem);
353 /* Scan all of the sections in FILE, and print the strings
354 in the initialized data section(s).
356 Return TRUE if successful,
357 FALSE if not (such as if FILE is not an object file). */
360 strings_object_file (const char *file)
362 filename_and_size_t filename_and_size;
365 abfd = bfd_openr (file, target);
368 /* Treat the file as a non-object file. */
371 /* This call is mainly for its side effect of reading in the sections.
372 We follow the traditional behavior of `strings' in that we don't
373 complain if we don't recognize a file to be an object file. */
374 if (!bfd_check_format (abfd, bfd_object))
380 got_a_section = FALSE;
381 filename_and_size.filename = file;
382 filename_and_size.filesize = 0;
383 bfd_map_over_sections (abfd, strings_a_section, & filename_and_size);
385 if (!bfd_close (abfd))
391 return got_a_section;
394 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
397 strings_file (char *file)
401 /* get_file_size does not support non-S_ISREG files. */
403 if (stat (file, &st) < 0)
406 non_fatal (_("'%s': No such file"), file);
408 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
409 file, strerror (errno));
413 /* If we weren't told to scan the whole file,
414 try to open it as an object file and only look at
415 initialized data sections. If that fails, fall back to the
417 if (!datasection_only || !strings_object_file (file))
421 stream = fopen (file, FOPEN_RB);
424 fprintf (stderr, "%s: ", program_name);
429 print_strings (file, stream, (file_ptr) 0, 0, 0, (char *) 0);
431 if (fclose (stream) == EOF)
433 fprintf (stderr, "%s: ", program_name);
442 /* Read the next character, return EOF if none available.
443 Assume that STREAM is positioned so that the next byte read
444 is at address ADDRESS in the file.
446 If STREAM is NULL, do not read from it.
447 The caller can supply a buffer of characters
448 to be processed before the data in STREAM.
449 MAGIC is the address of the buffer and
450 MAGICCOUNT is how many characters are in it. */
453 get_char (FILE *stream, file_ptr *address, int *magiccount, char **magic)
458 for (i = 0; i < encoding_bytes; i++)
470 /* Only use getc_unlocked if we found a declaration for it.
471 Otherwise, libc is not thread safe by default, and we
472 should not use it. */
474 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
475 c = getc_unlocked (stream);
484 r = (r << 8) | (c & 0xff);
492 r = ((r & 0xff) << 8) | ((r & 0xff00) >> 8);
495 r = (((r & 0xff) << 24) | ((r & 0xff00) << 8)
496 | ((r & 0xff0000) >> 8) | ((r & 0xff000000) >> 24));
503 /* Find the strings in file FILENAME, read from STREAM.
504 Assume that STREAM is positioned so that the next byte read
505 is at address ADDRESS in the file.
506 Stop reading at address STOP_POINT in the file, if nonzero.
508 If STREAM is NULL, do not read from it.
509 The caller can supply a buffer of characters
510 to be processed before the data in STREAM.
511 MAGIC is the address of the buffer and
512 MAGICCOUNT is how many characters are in it.
513 Those characters come at address ADDRESS and the data in STREAM follow. */
516 print_strings (const char *filename, FILE *stream, file_ptr address,
517 int stop_point, int magiccount, char *magic)
519 char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
527 /* See if the next `string_min' chars are all graphic chars. */
529 if (stop_point && address >= stop_point)
532 for (i = 0; i < string_min; i++)
534 c = get_char (stream, &address, &magiccount, &magic);
540 if (! STRING_ISGRAPHIC (c))
541 /* Found a non-graphic. Try again starting with next char. */
546 /* We found a run of `string_min' graphic characters. Print up
547 to the next non-graphic character. */
550 printf ("%s: ", filename);
552 switch (address_radix)
555 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
556 if (sizeof (start) > sizeof (long))
559 printf ("%7llo ", (unsigned long long) start);
561 printf ("%7I64o ", (unsigned long long) start);
565 #elif !BFD_HOST_64BIT_LONG
566 if (start != (unsigned long) start)
567 printf ("++%7lo ", (unsigned long) start);
570 printf ("%7lo ", (unsigned long) start);
574 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
575 if (sizeof (start) > sizeof (long))
578 printf ("%7lld ", (unsigned long long) start);
580 printf ("%7I64d ", (unsigned long long) start);
584 #elif !BFD_HOST_64BIT_LONG
585 if (start != (unsigned long) start)
586 printf ("++%7ld ", (unsigned long) start);
589 printf ("%7ld ", (long) start);
593 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
594 if (sizeof (start) > sizeof (long))
597 printf ("%7llx ", (unsigned long long) start);
599 printf ("%7I64x ", (unsigned long long) start);
603 #elif !BFD_HOST_64BIT_LONG
604 if (start != (unsigned long) start)
605 printf ("%lx%8.8lx ", (unsigned long) (start >> 32),
606 (unsigned long) (start & 0xffffffff));
609 printf ("%7lx ", (unsigned long) start);
618 c = get_char (stream, &address, &magiccount, &magic);
621 if (! STRING_ISGRAPHIC (c))
632 usage (FILE *stream, int status)
634 fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
635 fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n"));
636 fprintf (stream, _(" The options are:\n\
637 -a - --all Scan the entire file, not just the data section\n\
638 -f --print-file-name Print the name of the file before each string\n\
639 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
640 -<number> least [number] characters (default 4).\n\
641 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
642 -o An alias for --radix=o\n\
643 -T --target=<BFDNAME> Specify the binary file format\n\
644 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
645 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
646 @<file> Read options from <file>\n\
647 -h --help Display this information\n\
648 -v -V --version Print the program's version number\n"));
649 list_supported_targets (program_name, stream);
650 if (REPORT_BUGS_TO[0] && status == 0)
651 fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);