Digital Forensics / Intermediate: artifact-specific offline analysis / Lesson 9
Check file signatures against declared structure
Use a custom byte format to distinguish a header match, a valid structure, and a meaningful interpretation.
On this page
Lesson goals
- Explain why an extension or magic value is only one format clue.
- Validate lengths and truncation without reading untrusted files.
Treat names and signatures as clues
A filename extension, a leading byte signature, and a parser result can disagree. A header match may identify a candidate format without proving that the rest is valid, complete, or safe to render. A container can hold nested objects with different meanings. Start with the exact bytes and documented format assumptions, preserving the display name as metadata. This lesson defines a tiny classroom format called LABF; it is not a real file standard. No unknown file is opened, executed, rendered, or submitted to a conversion tool.
Define a tiny layout before writing a parser
The fictional LABF object contains four ASCII magic bytes, a one-byte payload length, and exactly that many payload bytes. The first program accepts one known object and returns a controlled category for missing header, bad magic, or inconsistent length. Those categories reflect this teaching format only. Bounds are checked before the payload is interpreted, and no content is executed. Real formats can require checksums, nested records, version-specific rules, and resource limits; this parser implements none of them. Its value is making structural assumptions explicit enough to test independently.
def parse_labf(raw):
if len(raw) < 5:
return "TRUNCATED_HEADER"
if raw[:4] != b"LABF":
return "BAD_MAGIC"
if len(raw) != 5 + raw[4]:
return "LENGTH_MISMATCH"
return raw[5:]
assert parse_labf(b"LABF\x03abc") == b"abc"
assert parse_labf(b"LAB") == "TRUNCATED_HEADER"
assert parse_labf(b"OTHER\x00") == "BAD_MAGIC"
assert parse_labf(b"LABF\x04abc") == "LENGTH_MISMATCH"
print("four custom-format structure cases checked")
four custom-format structure cases checked
The complete program parses four author-created byte strings in memory. It is not a forensic file-identification tool and validates no real format. The malformed cases are handled explicitly without executing or repairing their content.
Demonstrate why a prefix alone is insufficient
The second program shows a valid and a truncated object sharing the same LABF prefix. A simplistic signature search would call both candidates, while length validation distinguishes them. That is a concrete reason to report candidate identification separately from successful structural validation. A real signature can also occur inside unrelated data, and a valid container may still include unsupported or misleading content. Preserve the offset and object boundary that produced the match. Do not infer original filename, authorship, or application use from the signature alone.
valid = b"LABF\x03abc"
truncated = b"LABF\x03a"
assert valid.startswith(b"LABF") and truncated.startswith(b"LABF")
assert len(valid) == 5 + valid[4]
assert len(truncated) != 5 + truncated[4]
print("same prefix; different structural validity")
same prefix; different structural validity
The complete program compares two fixed synthetic objects. It establishes only the declared LABF length property. No real file is recovered, classified, or validated, and no content processor is invoked.
Review nested structure and parser limits
For an actual approved format analysis, identify version, container boundaries, compression, encryption, and parser support before interpreting extracted content. A tool may list an entry while failing to decompress it or may skip unsupported records. Retain those distinctions and account for failures. Do not repeatedly try unknown parsers until one displays a preferred result without recording the attempts. A successful open in a general application is not a validation method by itself and may change state or trigger interpretation. This course avoids those operations entirely and uses only fixed local byte arrays.
State the supported level of identification
Report whether the result is a signature candidate, a structure valid under a selected parser, or content interpreted under a documented rule. Include source object, offset, parser version, expected limits, and failed checks. If another parser disagrees, preserve both outputs and investigate field assumptions with known fixtures. A format match does not establish relevance to the case, origin, or intent. The controlled LABF examples demonstrate reasoning about headers and lengths; they do not test a real forensic product or prove that an unknown artifact is genuine.
Common errors and fixes
An extension proves the file type
- Why it happens
- Display metadata replaces byte and structure analysis.
- How to fix it
- Compare declared format clues and validate the supported structure.
- Prevent it next time
- Report identification confidence and parser scope.
A magic match is called a complete valid file
- Why it happens
- Candidate detection is confused with structural validation.
- How to fix it
- Check bounds and all relevant declared fields.
- Prevent it next time
- Include matching-prefix malformed fixtures.
Unsupported entries disappear from a container summary
- Why it happens
- Parser limits are hidden.
- How to fix it
- Retain skipped and failed records with their reasons.
- Prevent it next time
- Reconcile container entries and extracted outputs.
Check your understanding
1. Both fixtures begin LABF. Why can only one be structurally valid?
Show worked solution
The declared payload length must match the remaining bytes. A prefix identifies a candidate but does not satisfy the complete layout. Record the length mismatch rather than padding missing bytes or labeling the truncated candidate a recovered complete object.
2. A parser displays text from an unknown object. What should be reported?
Show worked solution
Identify the source, offset, parser and decoding assumptions, displayed text, and any unsupported structure. Do not infer original application use or authenticity from readability alone. Preserve bytes and use known format evidence or independent checks before strengthening the identification claim.
Key takeaways
- Signatures are clues rather than complete validation.
- Declared layouts need explicit bounds and failure categories.
- Readable output does not establish origin or relevance.