[9] | 1 | /* strings - print ASCII strings in a file Author: Peter S. Housel */
|
---|
| 2 |
|
---|
| 3 | /*
|
---|
| 4 | This is a version of the BSD "strings" program for Minix. It is used
|
---|
| 5 | to search a file for printable strings. To install,
|
---|
| 6 |
|
---|
| 7 | cc -o strings strings.c
|
---|
| 8 | chmem =8000 strings
|
---|
| 9 |
|
---|
| 10 | Command: strings - search file for printable strings
|
---|
| 11 | Syntax: strings [-] [-o] [-len] file ...
|
---|
| 12 | Flags: - Search the entire file. If this option is not given, only
|
---|
| 13 | the initialized data segment of files that appear to be
|
---|
| 14 | "a.out" format is searched.
|
---|
| 15 | -o Print the offset (in octal) with each string.
|
---|
| 16 | -len Use "len" as the minimum string length. The default is 4.
|
---|
| 17 |
|
---|
| 18 | Examples: strings core
|
---|
| 19 | strings -o a.out > str
|
---|
| 20 |
|
---|
| 21 | Strings searches the specified file(s) for printable ASCII strings (four
|
---|
| 22 | or more printable characters followed by a newline or a null) and writes
|
---|
| 23 | them to the standard output. This can be used to find out, for example, to
|
---|
| 24 | find out what program a "core" file came from, what kinds of error messages
|
---|
| 25 | are in an executable, or to see ASCII data hidden in a "binary" data file.
|
---|
| 26 |
|
---|
| 27 | P.S. The program doesn't use the "a.out.h" file posted last week by
|
---|
| 28 | Dick van Veen, both because it was written before then, and because
|
---|
| 29 | not everybody has a.out.h yet. Future revisions probably ought to, though.
|
---|
| 30 |
|
---|
| 31 | */
|
---|
| 32 |
|
---|
| 33 |
|
---|
| 34 |
|
---|
| 35 | #include <ctype.h>
|
---|
| 36 | #include <stdlib.h>
|
---|
| 37 | #include <string.h>
|
---|
| 38 | #include <stdio.h>
|
---|
| 39 |
|
---|
| 40 | /* Minix (8086 version) dependant definitions */
|
---|
| 41 | #define SMALLMAGIC 0x04100301L /* small model a.out magic number */
|
---|
| 42 | #define SEPARATEMAGIC 0x04200301L /* separate instruction/data a.out */
|
---|
| 43 |
|
---|
| 44 | #define HDR_MAGIC 0 /* 0'th long magic number */
|
---|
| 45 | #define HDR_HSIZE 1 /* 1'st long size of header */
|
---|
| 46 | #define HDR_TSIZE 2 /* 2'nd long size of text */
|
---|
| 47 | #define HDR_DSIZE 3 /* 3'rd long size of init'ed data */
|
---|
| 48 | #define HDR_BSIZE 4 /* 4'th long size of bss */
|
---|
| 49 | #define HDR_TOTMEM 6 /* 6'th long total memory */
|
---|
| 50 |
|
---|
| 51 | #define HDR_LEN 8 /* total length of header */
|
---|
| 52 |
|
---|
| 53 | /* Miscellaneous definitions */
|
---|
| 54 | #define STRLEN 4 /* default minimum string length */
|
---|
| 55 | #define STRBUF 512 /* buffer length for strings */
|
---|
| 56 |
|
---|
| 57 | _PROTOTYPE(int main, (int argc, char **argv));
|
---|
| 58 | _PROTOTYPE(void strings, (char *filename));
|
---|
| 59 | _PROTOTYPE(void usage, (void));
|
---|
| 60 |
|
---|
| 61 | int strmin = STRLEN; /* minimum string length */
|
---|
| 62 | int printoff = 0; /* print octal offset of each str */
|
---|
| 63 | int objall = 0; /* search entire a.out file, not */
|
---|
| 64 |
|
---|
| 65 | /* Just initialized data segment */
|
---|
| 66 |
|
---|
| 67 | int main(argc, argv)
|
---|
| 68 | int argc;
|
---|
| 69 | char *argv[];
|
---|
| 70 | {
|
---|
| 71 | while ((++argv, --argc) && '-' == (*argv)[0]) {
|
---|
| 72 | if (!strcmp(*argv, "-"))
|
---|
| 73 | ++objall;
|
---|
| 74 | else if (!strcmp(*argv, "-o"))
|
---|
| 75 | ++printoff;
|
---|
| 76 | else if (isdigit((*argv)[1]))
|
---|
| 77 | strmin = atoi(&(*argv)[1]);
|
---|
| 78 | else
|
---|
| 79 | usage();
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 | if (0 == argc) usage();
|
---|
| 83 | while (argc--) strings(*argv++);
|
---|
| 84 | return(0);
|
---|
| 85 | }
|
---|
| 86 |
|
---|
| 87 | void strings(filename)
|
---|
| 88 | char *filename;
|
---|
| 89 | {
|
---|
| 90 | char buf[STRBUF]; /* the strings buffer */
|
---|
| 91 | char *bufptr; /* pointer into the strings buffer */
|
---|
| 92 | FILE *input; /* input file */
|
---|
| 93 | long header[HDR_LEN]; /* buffer for reading the header */
|
---|
| 94 | long offset; /* file offset */
|
---|
| 95 | long limit; /* limit, if doing data segment only */
|
---|
| 96 | int c; /* input character */
|
---|
| 97 |
|
---|
| 98 | if (NULL == (input = fopen(filename, "r"))) {
|
---|
| 99 | fprintf(stderr, "strings: ");
|
---|
| 100 | perror(filename);
|
---|
| 101 | exit(1);
|
---|
| 102 | }
|
---|
| 103 | if (HDR_LEN == fread(header, sizeof(long), (size_t)HDR_LEN, input)
|
---|
| 104 | && (SMALLMAGIC == header[HDR_MAGIC]
|
---|
| 105 | ||SEPARATEMAGIC == header[HDR_MAGIC]) && !objall) {
|
---|
| 106 | offset = header[HDR_HSIZE] + header[HDR_TSIZE]; /* object file */
|
---|
| 107 | limit = offset + header[HDR_DSIZE];
|
---|
| 108 | } else {
|
---|
| 109 | offset = 0L;
|
---|
| 110 | limit = 0L;
|
---|
| 111 | }
|
---|
| 112 |
|
---|
| 113 | fseek(input, offset, 0);
|
---|
| 114 | bufptr = buf;
|
---|
| 115 |
|
---|
| 116 | while (!limit || offset < limit) {
|
---|
| 117 | if (EOF == (c = getc(input))) break;
|
---|
| 118 | if ((('\0' == c || '\n' == c) && bufptr - buf >= strmin)
|
---|
| 119 | || (bufptr - buf == STRBUF - 1)) {
|
---|
| 120 | *bufptr = '\0';
|
---|
| 121 | if (printoff) printf("%lo:", offset - (bufptr - buf));
|
---|
| 122 | puts(buf);
|
---|
| 123 | bufptr = buf;
|
---|
| 124 | } else if ((' ' <= c && c < 0177) || '\t' == c)
|
---|
| 125 | *bufptr++ = c;
|
---|
| 126 | else
|
---|
| 127 | bufptr = buf;
|
---|
| 128 |
|
---|
| 129 | ++offset;
|
---|
| 130 | }
|
---|
| 131 |
|
---|
| 132 | fclose(input);
|
---|
| 133 | }
|
---|
| 134 |
|
---|
| 135 | void usage()
|
---|
| 136 | {
|
---|
| 137 | fprintf(stderr, "usage: strings [-] [-o] [-num] file ...\n");
|
---|
| 138 | exit(1);
|
---|
| 139 | }
|
---|