2 Find occurances of one binary file within another
4 Author: TJ <linux@tjworld.net>
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, version 3 of the License.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <sys/types.h>
30 usage(const char *name) {
31 printf("Usage: %s: [-d] -n <needle> -h <haystack>\n", name);
32 printf("Copyright 2010 TJ <linux@tjworld.net>\n"
33 "Licensed under the terms of the GNU GPL v3\n\n"
34 "\t-d\tprint matching addresses in decimal not hexadecimal\n"
35 "\t-n\tpath to the file containing the needle\n"
36 "\t-h\tpath to the file containing the haystack\n\n"
38 "\tInformation messages are written to stderr and only matches are written to stdout.\n"
39 "\tThis allows the output to be piped through other filters.\n"
44 main(int argc, char *argv[], char *env[]) {
46 int c, use_decimal, needle_fd, haystack_fd;
47 char *needle_name, *haystack_name;
48 void *needle_mmap, *haystack_mmap;
49 struct stat needle_stat, haystack_stat;
51 needle_name = haystack_name = needle_mmap = haystack_mmap = NULL;
54 if (argc > 1) { // must have some parameters
57 while ((c = getopt(argc, argv, "n:h:d")) != -1 ) { // iterate the options
63 haystack_name = optarg;
73 if ((needle_fd = open(needle_name, O_RDONLY)) == -1) {
74 perror("Unable to open needle");
78 if ((haystack_fd = open(haystack_name, O_RDONLY)) == -1) {
79 perror("Unable to open haystack");
84 fstat(needle_fd, &needle_stat);
85 fstat(haystack_fd, &haystack_stat);
86 fprintf(stderr, "Base:\t%s\n", use_decimal == 1 ? "decimal" : "hexadecimal");
87 fprintf(stderr, "Needle:\t\t%12ld\t%s\n", needle_stat.st_size, needle_name);
88 fprintf(stderr, "HayStack:\t%12ld\t%s\n", haystack_stat.st_size, haystack_name);
90 if(MAP_FAILED == (needle_mmap = mmap(needle_mmap, needle_stat.st_size, PROT_READ, MAP_SHARED, needle_fd, 0))) {
91 perror("Unable to memory-map needle");
94 if(MAP_FAILED == (haystack_mmap = mmap(haystack_mmap, haystack_stat.st_size, PROT_READ, MAP_SHARED, haystack_fd, 0))) {
95 perror("Unable to memory-map haystack");
99 void *n = needle_mmap; // convenient short names
100 void *h = haystack_mmap;
101 unsigned long end = haystack_stat.st_size - needle_stat.st_size;
102 unsigned long offset;
104 fprintf(stderr, "Searching...\n");
105 for (offset = 0; offset <= end; offset++) {
106 if (memcmp(n, h+offset, needle_stat.st_size) == 0) { // match ?
107 if (use_decimal) printf("%10ld matches\n", offset);
108 else printf("0x%08lX matches\n", offset);
111 fprintf(stderr, "Done.\n");
118 if (needle_mmap > 0) munmap(needle_mmap, needle_stat.st_size);
119 if (haystack_mmap > 0) munmap(haystack_mmap, haystack_stat.st_size);
120 if (needle_fd > 0) close(needle_fd);
121 if (haystack_fd > 0) close(haystack_fd);