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 bfd_boolean
strings_file (char *);
150 static void print_strings (const char *, FILE *, file_ptr
, int, int, char *);
151 static void usage (FILE *, int) ATTRIBUTE_NORETURN
;
153 int main (int, char **);
156 main (int argc
, char **argv
)
160 bfd_boolean files_given
= FALSE
;
164 #if defined (HAVE_SETLOCALE)
165 setlocale (LC_ALL
, "");
167 bindtextdomain (PACKAGE
, LOCALEDIR
);
168 textdomain (PACKAGE
);
170 program_name
= argv
[0];
171 xmalloc_set_program_name (program_name
);
172 bfd_set_error_program_name (program_name
);
174 expandargv (&argc
, &argv
);
177 include_all_whitespace
= FALSE
;
178 print_addresses
= FALSE
;
179 print_filenames
= FALSE
;
180 if (DEFAULT_STRINGS_ALL
)
181 datasection_only
= FALSE
;
183 datasection_only
= TRUE
;
186 output_separator
= NULL
;
188 while ((optc
= getopt_long (argc
, argv
, "adfhHn:wot:e:T:s:Vv0123456789",
189 long_options
, (int *) 0)) != EOF
)
194 datasection_only
= FALSE
;
198 datasection_only
= TRUE
;
202 print_filenames
= TRUE
;
210 string_min
= (int) strtoul (optarg
, &s
, 0);
211 if (s
!= NULL
&& *s
!= 0)
212 fatal (_("invalid integer argument %s"), optarg
);
216 include_all_whitespace
= TRUE
;
220 print_addresses
= TRUE
;
225 print_addresses
= TRUE
;
226 if (optarg
[1] != '\0')
252 if (optarg
[1] != '\0')
254 encoding
= optarg
[0];
258 output_separator
= optarg
;
263 print_version ("strings");
270 numeric_opt
= optind
;
275 if (numeric_opt
!= 0)
277 string_min
= (int) strtoul (argv
[numeric_opt
- 1] + 1, &s
, 0);
278 if (s
!= NULL
&& *s
!= 0)
279 fatal (_("invalid integer argument %s"), argv
[numeric_opt
- 1] + 1);
282 fatal (_("invalid minimum string length %d"), string_min
);
303 set_default_bfd_target ();
307 datasection_only
= FALSE
;
308 SET_BINARY (fileno (stdin
));
309 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
314 for (; optind
< argc
; ++optind
)
316 if (strcmp (argv
[optind
], "-") == 0)
317 datasection_only
= FALSE
;
321 exit_status
|= strings_file (argv
[optind
]) == FALSE
;
329 return (exit_status
);
332 /* Scan section SECT of the file ABFD, whose printable name is in
333 ARG->filename and whose size might be in ARG->filesize. If it
334 contains initialized data set `got_a_section' and print the
337 FIXME: We ought to be able to return error codes/messages for
338 certain conditions. */
341 strings_a_section (bfd
*abfd
, asection
*sect
, void *arg
)
343 filename_and_size_t
* filename_and_sizep
;
344 bfd_size_type
*filesizep
;
345 bfd_size_type sectsize
;
348 if ((sect
->flags
& DATA_FLAGS
) != DATA_FLAGS
)
351 sectsize
= bfd_get_section_size (sect
);
356 /* Get the size of the file. This might have been cached for us. */
357 filename_and_sizep
= (filename_and_size_t
*) arg
;
358 filesizep
= & filename_and_sizep
->filesize
;
364 if (bfd_stat (abfd
, &st
))
367 /* Cache the result so that we do not repeatedly stat this file. */
368 *filesizep
= st
.st_size
;
371 /* Compare the size of the section against the size of the file.
372 If the section is bigger then the file must be corrupt and
373 we should not try dumping it. */
374 if (sectsize
>= *filesizep
)
377 mem
= xmalloc (sectsize
);
379 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sectsize
))
381 got_a_section
= TRUE
;
383 print_strings (filename_and_sizep
->filename
, NULL
, sect
->filepos
,
384 0, sectsize
, (char *) mem
);
390 /* Scan all of the sections in FILE, and print the strings
391 in the initialized data section(s).
393 Return TRUE if successful,
394 FALSE if not (such as if FILE is not an object file). */
397 strings_object_file (const char *file
)
399 filename_and_size_t filename_and_size
;
402 abfd
= bfd_openr (file
, target
);
405 /* Treat the file as a non-object file. */
408 /* This call is mainly for its side effect of reading in the sections.
409 We follow the traditional behavior of `strings' in that we don't
410 complain if we don't recognize a file to be an object file. */
411 if (!bfd_check_format (abfd
, bfd_object
))
417 got_a_section
= FALSE
;
418 filename_and_size
.filename
= file
;
419 filename_and_size
.filesize
= 0;
420 bfd_map_over_sections (abfd
, strings_a_section
, & filename_and_size
);
422 if (!bfd_close (abfd
))
428 return got_a_section
;
431 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
434 strings_file (char *file
)
438 /* get_file_size does not support non-S_ISREG files. */
440 if (stat (file
, &st
) < 0)
443 non_fatal (_("'%s': No such file"), file
);
445 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
446 file
, strerror (errno
));
450 /* If we weren't told to scan the whole file,
451 try to open it as an object file and only look at
452 initialized data sections. If that fails, fall back to the
454 if (!datasection_only
|| !strings_object_file (file
))
458 stream
= fopen (file
, FOPEN_RB
);
461 fprintf (stderr
, "%s: ", program_name
);
466 print_strings (file
, stream
, (file_ptr
) 0, 0, 0, (char *) 0);
468 if (fclose (stream
) == EOF
)
470 fprintf (stderr
, "%s: ", program_name
);
479 /* Read the next character, return EOF if none available.
480 Assume that STREAM is positioned so that the next byte read
481 is at address ADDRESS in the file.
483 If STREAM is NULL, do not read from it.
484 The caller can supply a buffer of characters
485 to be processed before the data in STREAM.
486 MAGIC is the address of the buffer and
487 MAGICCOUNT is how many characters are in it. */
490 get_char (FILE *stream
, file_ptr
*address
, int *magiccount
, char **magic
)
495 for (i
= 0; i
< encoding_bytes
; i
++)
507 /* Only use getc_unlocked if we found a declaration for it.
508 Otherwise, libc is not thread safe by default, and we
509 should not use it. */
511 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
512 c
= getc_unlocked (stream
);
521 r
= (r
<< 8) | (c
& 0xff);
529 r
= ((r
& 0xff) << 8) | ((r
& 0xff00) >> 8);
532 r
= (((r
& 0xff) << 24) | ((r
& 0xff00) << 8)
533 | ((r
& 0xff0000) >> 8) | ((r
& 0xff000000) >> 24));
540 /* Find the strings in file FILENAME, read from STREAM.
541 Assume that STREAM is positioned so that the next byte read
542 is at address ADDRESS in the file.
543 Stop reading at address STOP_POINT in the file, if nonzero.
545 If STREAM is NULL, do not read from it.
546 The caller can supply a buffer of characters
547 to be processed before the data in STREAM.
548 MAGIC is the address of the buffer and
549 MAGICCOUNT is how many characters are in it.
550 Those characters come at address ADDRESS and the data in STREAM follow. */
553 print_strings (const char *filename
, FILE *stream
, file_ptr address
,
554 int stop_point
, int magiccount
, char *magic
)
556 char *buf
= (char *) xmalloc (sizeof (char) * (string_min
+ 1));
564 /* See if the next `string_min' chars are all graphic chars. */
566 if (stop_point
&& address
>= stop_point
)
569 for (i
= 0; i
< string_min
; i
++)
571 c
= get_char (stream
, &address
, &magiccount
, &magic
);
577 if (! STRING_ISGRAPHIC (c
))
578 /* Found a non-graphic. Try again starting with next char. */
583 /* We found a run of `string_min' graphic characters. Print up
584 to the next non-graphic character. */
587 printf ("%s: ", filename
);
589 switch (address_radix
)
592 #ifdef HAVE_LONG_LONG
593 if (sizeof (start
) > sizeof (long))
596 printf ("%7llo ", (unsigned long long) start
);
598 printf ("%7I64o ", (unsigned long long) start
);
602 #elif !BFD_HOST_64BIT_LONG
603 if (start
!= (unsigned long) start
)
604 printf ("++%7lo ", (unsigned long) start
);
607 printf ("%7lo ", (unsigned long) start
);
611 #ifdef HAVE_LONG_LONG
612 if (sizeof (start
) > sizeof (long))
615 printf ("%7lld ", (unsigned long long) start
);
617 printf ("%7I64d ", (unsigned long long) start
);
621 #elif !BFD_HOST_64BIT_LONG
622 if (start
!= (unsigned long) start
)
623 printf ("++%7ld ", (unsigned long) start
);
626 printf ("%7ld ", (long) start
);
630 #ifdef HAVE_LONG_LONG
631 if (sizeof (start
) > sizeof (long))
634 printf ("%7llx ", (unsigned long long) start
);
636 printf ("%7I64x ", (unsigned long long) start
);
640 #elif !BFD_HOST_64BIT_LONG
641 if (start
!= (unsigned long) start
)
642 printf ("%lx%8.8lx ", (unsigned long) (start
>> 32),
643 (unsigned long) (start
& 0xffffffff));
646 printf ("%7lx ", (unsigned long) start
);
655 c
= get_char (stream
, &address
, &magiccount
, &magic
);
658 if (! STRING_ISGRAPHIC (c
))
663 if (output_separator
)
664 fputs (output_separator
, stdout
);
672 usage (FILE *stream
, int status
)
674 fprintf (stream
, _("Usage: %s [option(s)] [file(s)]\n"), program_name
);
675 fprintf (stream
, _(" Display printable strings in [file(s)] (stdin by default)\n"));
676 fprintf (stream
, _(" The options are:\n"));
678 if (DEFAULT_STRINGS_ALL
)
679 fprintf (stream
, _("\
680 -a - --all Scan the entire file, not just the data section [default]\n\
681 -d --data Only scan the data sections in the file\n"));
683 fprintf (stream
, _("\
684 -a - --all Scan the entire file, not just the data section\n\
685 -d --data Only scan the data sections in the file [default]\n"));
687 fprintf (stream
, _("\
688 -f --print-file-name Print the name of the file before each string\n\
689 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
690 -<number> least [number] characters (default 4).\n\
691 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
692 -w --include-all-whitespace Include all whitespace as valid string characters\n\
693 -o An alias for --radix=o\n\
694 -T --target=<BFDNAME> Specify the binary file format\n\
695 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
696 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
697 -s --output-separator=<string> String used to separate strings in output.\n\
698 @<file> Read options from <file>\n\
699 -h --help Display this information\n\
700 -v -V --version Print the program's version number\n"));
701 list_supported_targets (program_name
, stream
);
702 if (REPORT_BUGS_TO
[0] && status
== 0)
703 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);