nullcon2023-chall-bmpass

AES-ECB bitmap encryption challenge for NullCon 2023 Berlin
git clone https://git.sinitax.com/sinitax/nullcon2023-chall-bmpass
Log | Files | Refs | sfeed.txt

recover.c (3125B)


      1#include "raylib.h"
      2
      3#include <err.h>
      4#include <string.h>
      5#include <stdio.h>
      6#include <stdint.h>
      7#include <stdbool.h>
      8#include <stdlib.h>
      9
     10#define BLOCKSIZE 16
     11#define BESTN 4
     12
     13struct block {
     14	uint8_t data[BLOCKSIZE];
     15	uint32_t cnt;
     16};
     17
     18uint8_t *
     19read_file(const char *filename, size_t *size)
     20{
     21	uint8_t *buf;
     22	FILE *f;
     23
     24	f = fopen(filename, "r");
     25	if (!f) err(1, "fopen");
     26
     27	fseek(f, 0, SEEK_END);
     28	*size = ftell(f);
     29	fseek(f, 0, SEEK_SET);
     30
     31	buf = malloc(*size);
     32	if (!buf) err(1, "malloc");
     33
     34	if (!fread(buf, *size, 1, f))
     35		err(1, "fread");
     36
     37	fclose(f);
     38
     39	return buf;
     40}
     41
     42void
     43update(struct block *blocks, struct block *bestblocks,
     44	size_t *blockslen, uint8_t *img, size_t imglen)
     45{
     46	struct block cmp, tmp;
     47	size_t tmpcnt;
     48	size_t i, k;
     49
     50	memset(bestblocks, 0, BESTN * sizeof(struct block));
     51	*blockslen = 0;
     52	for (i = 0; i < imglen - BLOCKSIZE + 1; i += BLOCKSIZE) {
     53		for (k = 0; k < *blockslen; k++) {
     54			if (!memcmp(blocks[k].data, &img[i], BLOCKSIZE)) {
     55				blocks[k].cnt += 1;
     56				break;
     57			}
     58		}
     59		if (k == *blockslen) {
     60			memcpy(blocks[k].data, &img[i], BLOCKSIZE);
     61			blocks[k].cnt = 1;
     62			*blockslen += 1;
     63		}
     64
     65		memcpy(&cmp, &blocks[k], sizeof(struct block));
     66		for (k = 0; k < BESTN; k++) {
     67			if (cmp.cnt > bestblocks[k].cnt || !bestblocks[k].cnt) {
     68				memcpy(&tmp, &bestblocks[k], sizeof(struct block));
     69				memcpy(&bestblocks[k], &cmp, sizeof(struct block));
     70				memcpy(&cmp, &tmp, sizeof(struct block));
     71			}
     72		}
     73	}
     74}
     75
     76
     77int
     78main(int argc, const char **argv)
     79{
     80	const int wwidth = 1920;
     81	const int wheight = 1080;
     82	struct block bestblocks[BESTN];
     83	struct block *blocks;
     84	char textbuf[256];
     85	size_t blockslen;
     86	size_t imgoff, imglen;
     87	size_t width, height;
     88	size_t x, y, pos, i;
     89	uint8_t *img;
     90
     91	if (argc < 2) return 1;
     92
     93	img = read_file(argv[1], &imglen);
     94
     95	blocks = malloc(imglen / BLOCKSIZE * sizeof(struct block));
     96	if (!blocks) err(1, "malloc");
     97
     98	InitWindow(wwidth, wheight, "bmpass");
     99
    100	update(blocks, bestblocks, &blockslen, img, imglen);
    101
    102	width = wwidth;
    103	imgoff = 0;
    104	while (!WindowShouldClose()) {
    105		if (IsKeyDown(KEY_LEFT) && width > 0)
    106			width -= 1;
    107		else if (IsKeyDown(KEY_RIGHT))
    108			width += 1;
    109		else if (IsKeyDown(KEY_DOWN) && imgoff > 0)
    110			imgoff -= BLOCKSIZE;
    111		else if (IsKeyDown(KEY_UP))
    112			imgoff += BLOCKSIZE;
    113		else if (IsKeyDown(KEY_ESCAPE))
    114			break;
    115
    116		BeginDrawing();
    117
    118		ClearBackground(GRAY);
    119
    120		height = (imglen - imgoff) / width;
    121		for (y = 0; y < height; y++) {
    122			if (y >= wheight) continue;
    123			for (x = 0; x < width; x++) {
    124				if (x >= wwidth) continue;
    125				pos = (imgoff + y * width + x)
    126					/ BLOCKSIZE * BLOCKSIZE;
    127				if (pos + BLOCKSIZE >= imglen) continue;
    128				for (i = 0; i < BESTN; i++) {
    129					if (!memcmp(bestblocks[i].data,
    130							img + pos, BLOCKSIZE))
    131						break;
    132				}
    133				if (i != BESTN)
    134					DrawPixel(x, wheight - 1 - y, BLACK);
    135				else
    136					DrawPixel(x, wheight - 1 - y, WHITE);
    137			}
    138		}
    139
    140		snprintf(textbuf, sizeof(textbuf), "imgoff %lu", imgoff);
    141		DrawText(textbuf, 10, wheight - 40, 20, BLACK);
    142
    143		snprintf(textbuf, sizeof(textbuf), "width %lu", width);
    144		DrawText(textbuf, 10, wheight - 20, 20, BLACK);
    145
    146		EndDrawing();
    147	}
    148
    149	CloseWindow();
    150}