1 /* strings -- print the strings of printable characters in files
2 Copyright (C) 1993-2018 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 && 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 /* The BFD object file format. */
114 /* The character encoding format. */
115 static char encoding
;
116 static int encoding_bytes
;
118 /* Output string used to separate parsed strings */
119 static char *output_separator
;
121 static struct option long_options
[] =
123 {"all", no_argument
, NULL
, 'a'},
124 {"data", no_argument
, NULL
, 'd'},
125 {"print-file-name", no_argument
, NULL
, 'f'},
126 {"bytes", required_argument
, NULL
, 'n'},
127 {"radix", required_argument
, NULL
, 't'},
128 {"include-all-whitespace", no_argument
, NULL
, 'w'},
129 {"encoding", required_argument
, NULL
, 'e'},
130 {"target", required_argument
, NULL
, 'T'},
131 {"output-separator", required_argument
, NULL
, 's'},
132 {"help", no_argument
, NULL
, 'h'},
133 {"version", no_argument
, NULL
, 'v'},
137 static bfd_boolean
strings_file (char *);
138 static void print_strings (const char *, FILE *, file_ptr
, int, int, char *);
139 static void usage (FILE *, int) ATTRIBUTE_NORETURN
;
141 int main (int, char **);
144 main (int argc
, char **argv
)
148 bfd_boolean files_given
= FALSE
;
152 #if defined (HAVE_SETLOCALE)
153 setlocale (LC_ALL
, "");
155 bindtextdomain (PACKAGE
, LOCALEDIR
);
156 textdomain (PACKAGE
);
158 program_name
= argv
[0];
159 xmalloc_set_program_name (program_name
);
160 bfd_set_error_program_name (program_name
);
162 expandargv (&argc
, &argv
);
165 include_all_whitespace
= FALSE
;
166 print_addresses
= FALSE
;
167 print_filenames
= FALSE
;
168 if (DEFAULT_STRINGS_ALL
)
169 datasection_only
= FALSE
;
171 datasection_only
= TRUE
;
174 output_separator
= NULL
;
176 while ((optc
= getopt_long (argc
, argv
, "adfhHn:wot:e:T:s:Vv0123456789",
177 long_options
, (int *) 0)) != EOF
)
182 datasection_only
= FALSE
;
186 datasection_only
= TRUE
;
190 print_filenames
= TRUE
;
198 string_min
= (int) strtoul (optarg
, &s
, 0);
199 if (s
!= NULL
&& *s
!= 0)
200 fatal (_("invalid integer argument %s"), optarg
);
204 include_all_whitespace
= TRUE
;
208 print_addresses
= TRUE
;
213 print_addresses
= TRUE
;
214 if (optarg
[1] != '\0')
240 if (optarg
[1] != '\0')
242 encoding
= optarg
[0];
246 output_separator
= optarg
;
251 print_version ("strings");
258 numeric_opt
= optind
;
263 if (numeric_opt
!= 0)
265 string_min
= (int) strtoul (argv
[numeric_opt
- 1] + 1, &s
, 0);
266 if (s
!= NULL
&& *s
!= 0)
267 fatal (_("invalid integer argument %s"), argv
[numeric_opt
- 1] + 1);
270 fatal (_("invalid minimum string length %d"), string_min
);
290 if (bfd_init () != BFD_INIT_MAGIC
)
291 fatal (_("fatal error: libbfd ABI mismatch"));
292 set_default_bfd_target ();
296 datasection_only
= FALSE
;
297 SET_BINARY (fileno (stdin
));
298 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
303 for (; optind
< argc
; ++optind
)
305 if (strcmp (argv
[optind
], "-") == 0)
306 datasection_only
= FALSE
;
310 exit_status
|= !strings_file (argv
[optind
]);
318 return (exit_status
);
321 /* Scan section SECT of the file ABFD, whose printable name is
322 FILENAME. If it contains initialized data set GOT_A_SECTION and
323 print the strings in it. */
326 strings_a_section (bfd
*abfd
, asection
*sect
, const char *filename
,
327 bfd_boolean
*got_a_section
)
329 bfd_size_type sectsize
;
332 if ((sect
->flags
& DATA_FLAGS
) != DATA_FLAGS
)
335 sectsize
= bfd_get_section_size (sect
);
339 if (!bfd_malloc_and_get_section (abfd
, sect
, &mem
))
341 non_fatal (_("%s: Reading section %s failed: %s"),
342 filename
, sect
->name
, bfd_errmsg (bfd_get_error ()));
346 *got_a_section
= TRUE
;
347 print_strings (filename
, NULL
, sect
->filepos
, 0, sectsize
, (char *) mem
);
351 /* Scan all of the sections in FILE, and print the strings
352 in the initialized data section(s).
354 Return TRUE if successful,
355 FALSE if not (such as if FILE is not an object file). */
358 strings_object_file (const char *file
)
362 bfd_boolean got_a_section
;
364 abfd
= bfd_openr (file
, target
);
367 /* Treat the file as a non-object file. */
370 /* This call is mainly for its side effect of reading in the sections.
371 We follow the traditional behavior of `strings' in that we don't
372 complain if we don't recognize a file to be an object file. */
373 if (!bfd_check_format (abfd
, bfd_object
))
379 got_a_section
= FALSE
;
380 for (s
= abfd
->sections
; s
!= NULL
; s
= s
->next
)
381 strings_a_section (abfd
, s
, file
, &got_a_section
);
383 if (!bfd_close (abfd
))
389 return got_a_section
;
392 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
395 strings_file (char *file
)
399 /* get_file_size does not support non-S_ISREG files. */
401 if (stat (file
, &st
) < 0)
404 non_fatal (_("'%s': No such file"), file
);
406 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
407 file
, strerror (errno
));
410 else if (S_ISDIR (st
.st_mode
))
412 non_fatal (_("Warning: '%s' is a directory"), file
);
416 /* If we weren't told to scan the whole file,
417 try to open it as an object file and only look at
418 initialized data sections. If that fails, fall back to the
420 if (!datasection_only
|| !strings_object_file (file
))
424 stream
= fopen (file
, FOPEN_RB
);
427 fprintf (stderr
, "%s: ", program_name
);
432 print_strings (file
, stream
, (file_ptr
) 0, 0, 0, (char *) 0);
434 if (fclose (stream
) == EOF
)
436 fprintf (stderr
, "%s: ", program_name
);
445 /* Read the next character, return EOF if none available.
446 Assume that STREAM is positioned so that the next byte read
447 is at address ADDRESS in the file.
449 If STREAM is NULL, do not read from it.
450 The caller can supply a buffer of characters
451 to be processed before the data in STREAM.
452 MAGIC is the address of the buffer and
453 MAGICCOUNT is how many characters are in it. */
456 get_char (FILE *stream
, file_ptr
*address
, int *magiccount
, char **magic
)
461 for (i
= 0; i
< encoding_bytes
; i
++)
473 /* Only use getc_unlocked if we found a declaration for it.
474 Otherwise, libc is not thread safe by default, and we
475 should not use it. */
477 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
478 c
= getc_unlocked (stream
);
487 r
= (r
<< 8) | (c
& 0xff);
495 r
= ((r
& 0xff) << 8) | ((r
& 0xff00) >> 8);
498 r
= (((r
& 0xff) << 24) | ((r
& 0xff00) << 8)
499 | ((r
& 0xff0000) >> 8) | ((r
& 0xff000000) >> 24));
506 /* Find the strings in file FILENAME, read from STREAM.
507 Assume that STREAM is positioned so that the next byte read
508 is at address ADDRESS in the file.
509 Stop reading at address STOP_POINT in the file, if nonzero.
511 If STREAM is NULL, do not read from it.
512 The caller can supply a buffer of characters
513 to be processed before the data in STREAM.
514 MAGIC is the address of the buffer and
515 MAGICCOUNT is how many characters are in it.
516 Those characters come at address ADDRESS and the data in STREAM follow. */
519 print_strings (const char *filename
, FILE *stream
, file_ptr address
,
520 int stop_point
, int magiccount
, char *magic
)
522 char *buf
= (char *) xmalloc (sizeof (char) * (string_min
+ 1));
530 /* See if the next `string_min' chars are all graphic chars. */
532 if (stop_point
&& address
>= stop_point
)
535 for (i
= 0; i
< string_min
; i
++)
537 c
= get_char (stream
, &address
, &magiccount
, &magic
);
544 if (! STRING_ISGRAPHIC (c
))
546 /* Found a non-graphic. Try again starting with next char. */
547 if (encoding_bytes
> 1)
549 /* In case of multibyte encodings rewind using magic buffer. */
552 /* If no magic buffer exists: use memory of c. */
564 magiccount
+= (encoding_bytes
-1);
567 c
= (( c
& 0xff0000) >> 16) | ( c
& 0xff00)
568 | (( c
& 0xff) << 16);
576 /* If magic buffer exists: rewind. */
577 magic
= magic
- (encoding_bytes
-1);
580 address
= address
- (encoding_bytes
-1);
588 /* We found a run of `string_min' graphic characters. Print up
589 to the next non-graphic character. */
592 printf ("%s: ", filename
);
594 switch (address_radix
)
597 #ifdef HAVE_LONG_LONG
598 if (sizeof (start
) > sizeof (long))
601 printf ("%7llo ", (unsigned long long) start
);
603 printf ("%7I64o ", (unsigned long long) start
);
607 #elif !BFD_HOST_64BIT_LONG
608 if (start
!= (unsigned long) start
)
609 printf ("++%7lo ", (unsigned long) start
);
612 printf ("%7lo ", (unsigned long) start
);
616 #ifdef HAVE_LONG_LONG
617 if (sizeof (start
) > sizeof (long))
620 printf ("%7lld ", (unsigned long long) start
);
622 printf ("%7I64d ", (unsigned long long) start
);
626 #elif !BFD_HOST_64BIT_LONG
627 if (start
!= (unsigned long) start
)
628 printf ("++%7ld ", (unsigned long) start
);
631 printf ("%7ld ", (long) start
);
635 #ifdef HAVE_LONG_LONG
636 if (sizeof (start
) > sizeof (long))
639 printf ("%7llx ", (unsigned long long) start
);
641 printf ("%7I64x ", (unsigned long long) start
);
645 #elif !BFD_HOST_64BIT_LONG
646 if (start
!= (unsigned long) start
)
647 printf ("%lx%8.8lx ", (unsigned long) (start
>> 32),
648 (unsigned long) (start
& 0xffffffff));
651 printf ("%7lx ", (unsigned long) start
);
660 c
= get_char (stream
, &address
, &magiccount
, &magic
);
663 if (! STRING_ISGRAPHIC (c
))
665 if (encoding_bytes
> 1)
667 /* In case of multibyte encodings rewind using magic buffer. */
670 /* If no magic buffer exists: use memory of c. */
682 magiccount
+= (encoding_bytes
-1);
685 c
= (( c
& 0xff0000) >> 16) | ( c
& 0xff00)
686 | (( c
& 0xff) << 16);
694 /* If magic buffer exists: rewind. */
695 magic
= magic
- (encoding_bytes
-1);
697 address
= address
- (encoding_bytes
-1);
704 if (output_separator
)
705 fputs (output_separator
, stdout
);
713 usage (FILE *stream
, int status
)
715 fprintf (stream
, _("Usage: %s [option(s)] [file(s)]\n"), program_name
);
716 fprintf (stream
, _(" Display printable strings in [file(s)] (stdin by default)\n"));
717 fprintf (stream
, _(" The options are:\n"));
719 if (DEFAULT_STRINGS_ALL
)
720 fprintf (stream
, _("\
721 -a - --all Scan the entire file, not just the data section [default]\n\
722 -d --data Only scan the data sections in the file\n"));
724 fprintf (stream
, _("\
725 -a - --all Scan the entire file, not just the data section\n\
726 -d --data Only scan the data sections in the file [default]\n"));
728 fprintf (stream
, _("\
729 -f --print-file-name Print the name of the file before each string\n\
730 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
731 -<number> least [number] characters (default 4).\n\
732 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
733 -w --include-all-whitespace Include all whitespace as valid string characters\n\
734 -o An alias for --radix=o\n\
735 -T --target=<BFDNAME> Specify the binary file format\n\
736 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
737 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
738 -s --output-separator=<string> String used to separate strings in output.\n\
739 @<file> Read options from <file>\n\
740 -h --help Display this information\n\
741 -v -V --version Print the program's version number\n"));
742 list_supported_targets (program_name
, stream
);
743 if (REPORT_BUGS_TO
[0] && status
== 0)
744 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);