findhex

Hex pattern matcher
git clone https://git.sinitax.com/sinitax/findhex
Log | Files | Refs | LICENSE | sfeed.txt

commit 8fde78de2cf95793fe4aed00b899aca2695164b6
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed, 21 Sep 2022 00:51:10 +0200

Initial version

Diffstat:
A.gitignore | 1+
AMakefile | 9+++++++++
Afindhex.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +findhex diff --git a/Makefile 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 @@ -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); +}