cybersecurity · beginner · ~12 min · safe pentest lab

Detect a firmware blob's type from its magic bytes

Magic-byte file type detection with bounds checks.

Challenge

Identify a firmware blob's type from its magic bytes — before you mount or unpack an image, magic-byte sniffing tells you what it is in 8 bytes.

Task

Implement int detect_firmware_type(const uint8_t *buf, size_t n) that returns a tag for the recognized format.

Input

  • buf, n: a fixture byte buffer and its length, baked into the harness.

Output

Returns int:

  • 1 PE (4D 5A)
  • 2 ELF (7F 45 4C 46)
  • 3 U-Boot uImage (27 05 19 56, big-endian)
  • 4 Squashfs (68 73 71 73, ASCII hsqs)
  • 5 JFFS2 (19 85)
  • 0 unknown
  • -1 if buf == NULL

Example

buf = 7F 45 4C 46 ...   ->   2   (ELF)
buf = 27 05 19 56       ->   3   (uImage)
buf = 00 11 22 33       ->   0   (unknown)

Edge cases

  • If n is too short to check a given magic, skip that magic.
  • NULL buffer returns -1.

Rules

  • Compare with memcmp against constant byte arrays; bounds-check n before each compare.
  • uImage's magic is the on-disk byte order 27 05 19 56 (do not treat it as little-endian).

Why this matters

Before you mount or unpack a firmware image, you need to know what it is. Magic-byte sniffing answers the question in 8 bytes.

Input format

A const byte buffer + its length.

Output format

Type tag (0..5) or -1 on NULL.

Constraints

Bounds-check before every memcmp. Buf-NULL handling explicit.

Starter code

#include <stdint.h>
#include <stddef.h>
int detect_firmware_type(const uint8_t *buf, size_t n) {
    /* TODO */
    (void)buf; (void)n;
    return -1;
}

Common mistakes

Letting PE's 2-byte prefix match before ELF's 4-byte prefix is checked. Reading past n. Treating uImage as little-endian.

Edge cases to handle

Buffer exactly 2 bytes (PE / JFFS2 only). NULL buf.

Complexity

O(1) — bounded number of memcmps.

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.