diff options
| author | Louis Burda <quent.burda@gmail.com> | 2022-09-21 00:51:10 +0200 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2022-09-21 00:51:10 +0200 |
| commit | 8fde78de2cf95793fe4aed00b899aca2695164b6 (patch) | |
| tree | ba6d9ef073a7f26b378c5d3248aef7bc270dac32 | |
| download | findhex-8fde78de2cf95793fe4aed00b899aca2695164b6.tar.gz findhex-8fde78de2cf95793fe4aed00b899aca2695164b6.zip | |
Initial version
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 9 | ||||
| -rw-r--r-- | findhex.c | 92 |
3 files changed, 102 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6c60aea --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +findhex diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2d63bbe --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ + +all: findhex + +clean: + rm -f findhex + +findhex: findhex.c + +.PHONY: all clean diff --git a/findhex.c b/findhex.c new file mode 100644 index 0000000..e515817 --- /dev/null +++ b/findhex.c @@ -0,0 +1,92 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <stdarg.h> + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +void +die(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + vfprintf(stderr, "%s\n", ap); + va_end(ap); + + exit(1); +} + +int +main(int argc, const char **argv) +{ + uint8_t *pattern, *pattern_mask; + size_t patlen; + uint8_t *buf; + size_t buflen; + ssize_t nread; + size_t i, k; + size_t pos, off; + size_t arglen; + FILE *file; + + setvbuf(stdout, NULL, _IONBF, 0); + + if (argc < 2 || argc > 3) die("Usage: findhex PATTERN [FILE]"); + + arglen = strlen(argv[1]); + if (!arglen || arglen % 2 != 0) + die("Pattern length invalid"); + patlen = arglen / 2; + + pattern = calloc(patlen, 1); + pattern_mask = calloc(patlen, 1); + if (!pattern || !pattern_mask) die("Out of Memory"); + + buflen = MAX(patlen * 2, 16 * 1024); + buf = malloc(buflen); + if (!buf) die("Out of Memory"); + + for (i = 0; i < arglen; i += 2) { + if (!strncmp(argv[1] + i, "__", 2)) + continue; + if (!sscanf(argv[1] + i, "%02hX", &pattern[i / 2])) + die("Invalid hex in pattern"); + pattern_mask[i / 2] = 0xff; + } + + if (argc == 3) { + file = fopen(argv[1], "r"); + if (!file) die("Failed to open file"); + } else { + file = stdin; + } + + off = patlen > 0 ? patlen - 1 : 0; + if (fread(buf, 1, off, file) != off) + exit(0); + + pos = 0; + while (1) { + nread = fread(buf + off, 1, buflen - off, file); + if (nread == 0) break; + if (nread < 0) die("%016llX: Read failed", pos); + + for (i = 0; i <= nread + off - patlen; i++) { + for (k = 0; k < patlen; k++) { + if (!pattern_mask[k]) + continue; + if (buf[i+k] != pattern[k]) + break; + } + if (k == patlen) + printf("%016llX\n", pos + i); + } + + pos += nread; + memcpy(buf, buf + buflen - off, off); + } + + fclose(file); +} |
