cybersecurity · intermediate · ~15 min · safe pentest lab
Bounds-safe offset/length parsing of a record-style binary format.
Read a filename out of a (mock) NTFS MFT record. The format is simplified, but the defensive shape — check the signature, bounds-check offsets, bounded-copy — is the same as the real thing.
Implement int read_mft_name(const uint8_t *rec, size_t n, char *out, size_t cap) that copies the record's name into out.
rec, n: a fixture record buffer and its length, baked into the harness. Layout:'F','I','L','E'name_offset (u16 LE)name_length (u16 LE)name_length ASCII bytes starting at rec[name_offset]out, cap: the output buffer and its capacity.Returns int: the number of bytes written to out (excluding the NUL) on success, or -1 on failure.
rec with signature FILE, name_offset 10, name_length 5, name "audit"
read_mft_name(rec, n, out, cap) -> out = "audit", returns 5
cap == 0, n < 8, the signature mismatches, name_offset + name_length walks past n, or the name would not fit in cap.end = (size_t)name_offset + (size_t)name_length as size_t to avoid 16-bit overflow.Real MFT parsing is complex. The defensive shape — magic, bounds-checked offsets, bounded copy — is the same in the mock and the real format.
A byte buffer + its length, an output buffer + capacity.
Non-negative byte count, or -1 on any failure.
Signature must match. Cast to size_t before adding. NUL-terminate output.
#include <stdint.h>
#include <stddef.h>
int read_mft_name(const uint8_t *rec, size_t n, char *out, size_t cap) {
/* TODO */
(void)rec; (void)n; (void)out; (void)cap;
return -1;
}
Adding off + len as u16 (overflows). Forgetting that len == 0 is a legal empty name. Reading rec[4..7] when n < 8.
Name length 0. Offset right at the end of the buffer. NULL inputs.
O(len) per call.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.