xorcat

Tool for testing xor keys on encrypted data
git clone https://git.sinitax.com/sinitax/xorcat
Log | Files | Refs | LICENSE | sfeed.txt

xorcat.c (2374B)


      1#include <unistd.h>
      2#include <err.h>
      3#include <stdbool.h>
      4#include <string.h>
      5#include <stdint.h>
      6#include <stdio.h>
      7#include <stdlib.h>
      8
      9static const char usage[] = "USAGE: xorcat [-h] [-m] KEYMASK";
     10
     11void
     12xorcat(uint8_t *indata, size_t insize, uint8_t *key, size_t keylen)
     13{
     14	uint8_t writebuf[4098];
     15	size_t i, nout, pos;
     16
     17	pos = 0;
     18	while (pos < insize) {
     19		for (i = 0; i < sizeof(writebuf) && i < insize - pos; i++)
     20			writebuf[i] = indata[pos + i] ^ key[(pos + i) % keylen];
     21		nout = write(STDOUT_FILENO, writebuf, i);
     22		if (nout != i) err(1, "write");
     23		pos += i;
     24	}
     25}
     26
     27uint8_t *
     28collect(size_t *size)
     29{
     30	uint8_t readbuf[4098];
     31	uint8_t *data;
     32	size_t nread, cap;
     33
     34	cap = 4098;
     35	data = malloc(cap);
     36	if (!data) err(1, "malloc");
     37
     38	*size = 0;
     39	while (1) {
     40		nread = read(STDIN_FILENO, readbuf, sizeof(readbuf));
     41		if (nread <= 0) break;
     42		if (cap < *size + nread) {
     43			cap *= 2;
     44			data = realloc(data, cap);
     45		}
     46		memcpy(data + *size, readbuf, nread);
     47		*size += nread;
     48	}
     49
     50	return data;
     51}
     52
     53int
     54main(int argc, const char **argv)
     55{
     56	uint8_t *mask, *key, keyb;
     57	const char *maskarg;
     58	size_t keylen;
     59	uint8_t *indata;
     60	size_t insize;
     61	bool markers;
     62	ssize_t i;
     63
     64	if (argc <= 1) {
     65		printf("%s\n", usage);
     66		exit(0);
     67	}
     68
     69	maskarg = NULL;
     70	markers = false;
     71	for (i = 1; i < argc; i++) {
     72		if (!strcmp(argv[i], "-h")) {
     73			printf("%s\n", usage);
     74			exit(0);
     75		} else if (!strcmp(argv[i], "-m")) {
     76			markers = true;
     77		} else if (maskarg) {
     78			errx(1, "Multiple mask arguments");
     79		} else {
     80			maskarg = argv[i];
     81		}
     82	}
     83
     84	if (!maskarg)
     85		errx(1, "Missing mask");
     86
     87	if (strlen(maskarg) % 2)
     88		errx(1, "Bad mask length");
     89
     90	keylen = strlen(maskarg) / 2;
     91	mask = calloc(keylen, 1);
     92	key = calloc(keylen, 1);
     93	if (!mask || !key) err(1, "malloc");
     94
     95	for (i = 0; i < keylen; i++) {
     96		if (!strncmp(argv[1] + 2 * i, "??", 2)) {
     97			mask[i] = 1;
     98		} else {
     99			if (!sscanf(maskarg + 2 * i, "%02hhX", &keyb))
    100				errx(1, "Bad mask");
    101			key[i] = (uint8_t) keyb;
    102		}
    103	}
    104
    105	indata = collect(&insize);
    106	while (1) {
    107		if (markers) {
    108			printf("\n");
    109			printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>> ");
    110			for (i = 0; i < keylen; i++)
    111				printf("%02X", key[i]);
    112			printf("\n");
    113			fflush(stdout);
    114		}
    115
    116		xorcat(indata, insize, key, keylen);
    117
    118		for (i = keylen - 1; i >= 0; i--) {
    119			if (mask[i]) {
    120				key[i] += 1;
    121				if (key[i]) break;
    122			}
    123		}
    124		if (i < 0) break;
    125	}
    126
    127	free(key);
    128	free(mask);
    129}