1 /* strings -- print the strings of printable characters in files
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012
4 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 /* Usage: strings [options] file...
26 - Do not scan only the initialized data section of object files.
29 -f Print the name of the file before each string.
33 -min-len Print graphic char sequences, MIN-LEN or more bytes long,
34 that are followed by a NUL or a newline. Default is 4.
37 -t {o,x,d} Print the offset within the file before each string,
40 -o Like -to. (Some other implementations have -o like -to,
41 others like -td. We chose one arbitrarily.)
43 --encoding={s,S,b,l,B,L}
45 Select character encoding: 7-bit-character, 8-bit-character,
46 bigendian 16-bit, littleendian 16-bit, bigendian 32-bit,
51 Specify a non-default object file format.
54 -h Print the usage message on the standard output.
58 -v Print the program version number.
60 Written by Richard Stallman <rms@gnu.ai.mit.edu>
61 and David MacKenzie <djm@gnu.ai.mit.edu>. */
66 #include "libiberty.h"
67 #include "safe-ctype.h"
70 #define STRING_ISGRAPHIC(c) \
73 && ((c) == '\t' || ISPRINT (c) || (encoding == 'S' && (c) > 127)))
79 /* The BFD section flags that identify an initialized data section. */
80 #define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
82 /* Radix for printing addresses (must be 8, 10 or 16). */
83 static int address_radix
;
85 /* Minimum length of sequence of graphic chars to trigger output. */
86 static int string_min
;
88 /* TRUE means print address within file for each string. */
89 static bfd_boolean print_addresses
;
91 /* TRUE means print filename for each string. */
92 static bfd_boolean print_filenames
;
94 /* TRUE means for object files scan only the data section. */
95 static bfd_boolean datasection_only
;
97 /* TRUE if we found an initialized data section in the current file. */
98 static bfd_boolean got_a_section
;
100 /* The BFD object file format. */
103 /* The character encoding format. */
104 static char encoding
;
105 static int encoding_bytes
;
107 static struct option long_options
[] =
109 {"all", no_argument
, NULL
, 'a'},
110 {"print-file-name", no_argument
, NULL
, 'f'},
111 {"bytes", required_argument
, NULL
, 'n'},
112 {"radix", required_argument
, NULL
, 't'},
113 {"encoding", required_argument
, NULL
, 'e'},
114 {"target", required_argument
, NULL
, 'T'},
115 {"help", no_argument
, NULL
, 'h'},
116 {"version", no_argument
, NULL
, 'v'},
120 /* Records the size of a named file so that we
121 do not repeatedly run bfd_stat() on it. */
125 const char * filename
;
126 bfd_size_type filesize
;
127 } filename_and_size_t
;
129 static void strings_a_section (bfd
*, asection
*, void *);
130 static bfd_boolean
strings_object_file (const char *);
131 static bfd_boolean
strings_file (char *file
);
132 static void print_strings (const char *, FILE *, file_ptr
, int, int, char *);
133 static void usage (FILE *, int);
134 static long get_char (FILE *, file_ptr
*, int *, char **);
136 int main (int, char **);
139 main (int argc
, char **argv
)
143 bfd_boolean files_given
= FALSE
;
147 #if defined (HAVE_SETLOCALE)
148 setlocale (LC_ALL
, "");
150 bindtextdomain (PACKAGE
, LOCALEDIR
);
151 textdomain (PACKAGE
);
153 program_name
= argv
[0];
154 xmalloc_set_program_name (program_name
);
156 expandargv (&argc
, &argv
);
159 print_addresses
= FALSE
;
160 print_filenames
= FALSE
;
161 datasection_only
= TRUE
;
165 while ((optc
= getopt_long (argc
, argv
, "afhHn:ot:e:T:Vv0123456789",
166 long_options
, (int *) 0)) != EOF
)
171 datasection_only
= FALSE
;
175 print_filenames
= TRUE
;
183 string_min
= (int) strtoul (optarg
, &s
, 0);
184 if (s
!= NULL
&& *s
!= 0)
185 fatal (_("invalid integer argument %s"), optarg
);
189 print_addresses
= TRUE
;
194 print_addresses
= TRUE
;
195 if (optarg
[1] != '\0')
221 if (optarg
[1] != '\0')
223 encoding
= optarg
[0];
228 print_version ("strings");
235 numeric_opt
= optind
;
240 if (numeric_opt
!= 0)
242 string_min
= (int) strtoul (argv
[numeric_opt
- 1] + 1, &s
, 0);
243 if (s
!= NULL
&& *s
!= 0)
244 fatal (_("invalid integer argument %s"), argv
[numeric_opt
- 1] + 1);
247 fatal (_("invalid minimum string length %d"), string_min
);
268 set_default_bfd_target ();
272 datasection_only
= FALSE
;
273 SET_BINARY (fileno (stdin
));
274 print_strings ("{standard input}", stdin
, 0, 0, 0, (char *) NULL
);
279 for (; optind
< argc
; ++optind
)
281 if (strcmp (argv
[optind
], "-") == 0)
282 datasection_only
= FALSE
;
286 exit_status
|= strings_file (argv
[optind
]) == FALSE
;
294 return (exit_status
);
297 /* Scan section SECT of the file ABFD, whose printable name is in
298 ARG->filename and whose size might be in ARG->filesize. If it
299 contains initialized data set `got_a_section' and print the
302 FIXME: We ought to be able to return error codes/messages for
303 certain conditions. */
306 strings_a_section (bfd
*abfd
, asection
*sect
, void *arg
)
308 filename_and_size_t
* filename_and_sizep
;
309 bfd_size_type
*filesizep
;
310 bfd_size_type sectsize
;
313 if ((sect
->flags
& DATA_FLAGS
) != DATA_FLAGS
)
316 sectsize
= bfd_get_section_size (sect
);
321 /* Get the size of the file. This might have been cached for us. */
322 filename_and_sizep
= (filename_and_size_t
*) arg
;
323 filesizep
= & filename_and_sizep
->filesize
;
329 if (bfd_stat (abfd
, &st
))
332 /* Cache the result so that we do not repeatedly stat this file. */
333 *filesizep
= st
.st_size
;
336 /* Compare the size of the section against the size of the file.
337 If the section is bigger then the file must be corrupt and
338 we should not try dumping it. */
339 if (sectsize
>= *filesizep
)
342 mem
= xmalloc (sectsize
);
344 if (bfd_get_section_contents (abfd
, sect
, mem
, (file_ptr
) 0, sectsize
))
346 got_a_section
= TRUE
;
348 print_strings (filename_and_sizep
->filename
, NULL
, sect
->filepos
,
349 0, sectsize
, (char *) mem
);
355 /* Scan all of the sections in FILE, and print the strings
356 in the initialized data section(s).
358 Return TRUE if successful,
359 FALSE if not (such as if FILE is not an object file). */
362 strings_object_file (const char *file
)
364 filename_and_size_t filename_and_size
;
367 abfd
= bfd_openr (file
, target
);
370 /* Treat the file as a non-object file. */
373 /* This call is mainly for its side effect of reading in the sections.
374 We follow the traditional behavior of `strings' in that we don't
375 complain if we don't recognize a file to be an object file. */
376 if (!bfd_check_format (abfd
, bfd_object
))
382 got_a_section
= FALSE
;
383 filename_and_size
.filename
= file
;
384 filename_and_size
.filesize
= 0;
385 bfd_map_over_sections (abfd
, strings_a_section
, & filename_and_size
);
387 if (!bfd_close (abfd
))
393 return got_a_section
;
396 /* Print the strings in FILE. Return TRUE if ok, FALSE if an error occurs. */
399 strings_file (char *file
)
403 /* get_file_size does not support non-S_ISREG files. */
405 if (stat (file
, &st
) < 0)
408 non_fatal (_("'%s': No such file"), file
);
410 non_fatal (_("Warning: could not locate '%s'. reason: %s"),
411 file
, strerror (errno
));
415 /* If we weren't told to scan the whole file,
416 try to open it as an object file and only look at
417 initialized data sections. If that fails, fall back to the
419 if (!datasection_only
|| !strings_object_file (file
))
423 stream
= fopen (file
, FOPEN_RB
);
426 fprintf (stderr
, "%s: ", program_name
);
431 print_strings (file
, stream
, (file_ptr
) 0, 0, 0, (char *) 0);
433 if (fclose (stream
) == EOF
)
435 fprintf (stderr
, "%s: ", program_name
);
444 /* Read the next character, return EOF if none available.
445 Assume that STREAM is positioned so that the next byte read
446 is at address ADDRESS in the file.
448 If STREAM is NULL, do not read from it.
449 The caller can supply a buffer of characters
450 to be processed before the data in STREAM.
451 MAGIC is the address of the buffer and
452 MAGICCOUNT is how many characters are in it. */
455 get_char (FILE *stream
, file_ptr
*address
, int *magiccount
, char **magic
)
460 for (i
= 0; i
< encoding_bytes
; i
++)
472 /* Only use getc_unlocked if we found a declaration for it.
473 Otherwise, libc is not thread safe by default, and we
474 should not use it. */
476 #if defined(HAVE_GETC_UNLOCKED) && HAVE_DECL_GETC_UNLOCKED
477 c
= getc_unlocked (stream
);
486 r
= (r
<< 8) | (c
& 0xff);
494 r
= ((r
& 0xff) << 8) | ((r
& 0xff00) >> 8);
497 r
= (((r
& 0xff) << 24) | ((r
& 0xff00) << 8)
498 | ((r
& 0xff0000) >> 8) | ((r
& 0xff000000) >> 24));
505 /* Find the strings in file FILENAME, read from STREAM.
506 Assume that STREAM is positioned so that the next byte read
507 is at address ADDRESS in the file.
508 Stop reading at address STOP_POINT in the file, if nonzero.
510 If STREAM is NULL, do not read from it.
511 The caller can supply a buffer of characters
512 to be processed before the data in STREAM.
513 MAGIC is the address of the buffer and
514 MAGICCOUNT is how many characters are in it.
515 Those characters come at address ADDRESS and the data in STREAM follow. */
518 print_strings (const char *filename
, FILE *stream
, file_ptr address
,
519 int stop_point
, int magiccount
, char *magic
)
521 char *buf
= (char *) xmalloc (sizeof (char) * (string_min
+ 1));
529 /* See if the next `string_min' chars are all graphic chars. */
531 if (stop_point
&& address
>= stop_point
)
534 for (i
= 0; i
< string_min
; i
++)
536 c
= get_char (stream
, &address
, &magiccount
, &magic
);
542 if (! STRING_ISGRAPHIC (c
))
543 /* Found a non-graphic. Try again starting with next char. */
548 /* We found a run of `string_min' graphic characters. Print up
549 to the next non-graphic character. */
552 printf ("%s: ", filename
);
554 switch (address_radix
)
557 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
558 if (sizeof (start
) > sizeof (long))
561 printf ("%7llo ", (unsigned long long) start
);
563 printf ("%7I64o ", (unsigned long long) start
);
567 #elif !BFD_HOST_64BIT_LONG
568 if (start
!= (unsigned long) start
)
569 printf ("++%7lo ", (unsigned long) start
);
572 printf ("%7lo ", (unsigned long) start
);
576 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
577 if (sizeof (start
) > sizeof (long))
580 printf ("%7lld ", (unsigned long long) start
);
582 printf ("%7I64d ", (unsigned long long) start
);
586 #elif !BFD_HOST_64BIT_LONG
587 if (start
!= (unsigned long) start
)
588 printf ("++%7ld ", (unsigned long) start
);
591 printf ("%7ld ", (long) start
);
595 #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
596 if (sizeof (start
) > sizeof (long))
599 printf ("%7llx ", (unsigned long long) start
);
601 printf ("%7I64x ", (unsigned long long) start
);
605 #elif !BFD_HOST_64BIT_LONG
606 if (start
!= (unsigned long) start
)
607 printf ("%lx%8.8lx ", (unsigned long) (start
>> 32),
608 (unsigned long) (start
& 0xffffffff));
611 printf ("%7lx ", (unsigned long) start
);
620 c
= get_char (stream
, &address
, &magiccount
, &magic
);
623 if (! STRING_ISGRAPHIC (c
))
634 usage (FILE *stream
, int status
)
636 fprintf (stream
, _("Usage: %s [option(s)] [file(s)]\n"), program_name
);
637 fprintf (stream
, _(" Display printable strings in [file(s)] (stdin by default)\n"));
638 fprintf (stream
, _(" The options are:\n\
639 -a - --all Scan the entire file, not just the data section\n\
640 -f --print-file-name Print the name of the file before each string\n\
641 -n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
642 -<number> least [number] characters (default 4).\n\
643 -t --radix={o,d,x} Print the location of the string in base 8, 10 or 16\n\
644 -o An alias for --radix=o\n\
645 -T --target=<BFDNAME> Specify the binary file format\n\
646 -e --encoding={s,S,b,l,B,L} Select character size and endianness:\n\
647 s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
648 @<file> Read options from <file>\n\
649 -h --help Display this information\n\
650 -v -V --version Print the program's version number\n"));
651 list_supported_targets (program_name
, stream
);
652 if (REPORT_BUGS_TO
[0] && status
== 0)
653 fprintf (stream
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);