1/*************************************************************************** 2 * binoffset.c 3 * (C) 2002 Randy Dunlap <rdunlap@xenotime.net> 4 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 19# binoffset.c: 20# - searches a (binary) file for a specified (binary) pattern 21# - returns the offset of the located pattern or ~0 if not found 22# - exits with exit status 0 normally or non-0 if pattern is not found 23# or any other error occurs. 24 25****************************************************************/ 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <string.h> 30#include <errno.h> 31#include <unistd.h> 32#include <fcntl.h> 33#include <sys/types.h> 34#include <sys/stat.h> 35#include <sys/mman.h> 36 37#define VERSION "0.1" 38#define BUF_SIZE (16 * 1024) 39#define PAT_SIZE 100 40 41char *progname; 42char *inputname; 43int inputfd; 44unsigned int bix; /* buf index */ 45unsigned char patterns [PAT_SIZE] = {0}; /* byte-sized pattern array */ 46int pat_len; /* actual number of pattern bytes */ 47unsigned char *madr; /* mmap address */ 48size_t filesize; 49int num_matches = 0; 50off_t firstloc = 0; 51 52void usage (void) 53{ 54 fprintf (stderr, "%s ver. %s\n", progname, VERSION); 55 fprintf (stderr, "usage: %s filename pattern_bytes\n", 56 progname); 57 fprintf (stderr, " [prints location of pattern_bytes in file]\n"); 58 exit (1); 59} 60 61void get_pattern (int pat_count, char *pats []) 62{ 63 int ix, err, tmp; 64 65#ifdef DEBUG 66 fprintf (stderr,"get_pattern: count = %d\n", pat_count); 67 for (ix = 0; ix < pat_count; ix++) 68 fprintf (stderr, " pat # %d: [%s]\n", ix, pats[ix]); 69#endif 70 71 for (ix = 0; ix < pat_count; ix++) { 72 tmp = 0; 73 err = sscanf (pats[ix], "%5i", &tmp); 74 if (err != 1 || tmp > 0xff) { 75 fprintf (stderr, "pattern or value error in pattern # %d [%s]\n", 76 ix, pats[ix]); 77 usage (); 78 } 79 patterns [ix] = tmp; 80 } 81 pat_len = pat_count; 82} 83 84void search_pattern (void) 85{ 86 for (bix = 0; bix < filesize; bix++) { 87 if (madr[bix] == patterns[0]) { 88 if (memcmp (&madr[bix], patterns, pat_len) == 0) { 89 if (num_matches == 0) 90 firstloc = bix; 91 num_matches++; 92 } 93 } 94 } 95} 96 97#ifdef NOTDEF 98size_t get_filesize (int fd) 99{ 100 off_t end_off = lseek (fd, 0, SEEK_END); 101 lseek (fd, 0, SEEK_SET); 102 return (size_t) end_off; 103} 104#endif 105 106size_t get_filesize (int fd) 107{ 108 int err; 109 struct stat stat; 110 111 err = fstat (fd, &stat); 112 fprintf (stderr, "filesize: %ld\n", err < 0 ? (long)err : stat.st_size); 113 if (err < 0) 114 return err; 115 return (size_t) stat.st_size; 116} 117 118int main (int argc, char *argv []) 119{ 120 progname = argv[0]; 121 122 if (argc < 3) 123 usage (); 124 125 get_pattern (argc - 2, argv + 2); 126 127 inputname = argv[1]; 128 129 inputfd = open (inputname, O_RDONLY); 130 if (inputfd == -1) { 131 fprintf (stderr, "%s: cannot open '%s'\n", 132 progname, inputname); 133 exit (3); 134 } 135 136 filesize = get_filesize (inputfd); 137 138 madr = mmap (0, filesize, PROT_READ, MAP_PRIVATE, inputfd, 0); 139 if (madr == MAP_FAILED) { 140 fprintf (stderr, "mmap error = %d\n", errno); 141 close (inputfd); 142 exit (4); 143 } 144 145 search_pattern (); 146 147 if (munmap (madr, filesize)) 148 fprintf (stderr, "munmap error = %d\n", errno); 149 150 if (close (inputfd)) 151 fprintf (stderr, "%s: error %d closing '%s'\n", 152 progname, errno, inputname); 153 154 fprintf (stderr, "number of pattern matches = %d\n", num_matches); 155 if (num_matches == 0) 156 firstloc = ~0; 157 printf ("%ld\n", firstloc); 158 fprintf (stderr, "%ld\n", firstloc); 159 160 exit (num_matches ? 0 : 2); 161} 162 163/* end binoffset.c */ 164