Presentation overview
In Decoding the Secrets of Pizza and Malware: Introduction to Reverse Engineering, I introduced the purpose of reverse engineering and the steps involved in understanding an existing program.
The presentation used pizza as an accessible analogy: an analyst works through layers to understand the ingredients, structure, and decisions that produced the final result. Applied to malware, that means moving from an unfamiliar program toward an explanation of its hidden behavior.
- Representation
Identify the frame layout and the executable architecture.
- Validation
Follow header, format, and checksum rejection paths.
- Decision
Recover the enabling flag and the strict reading > 3000 comparison.
- Verification
Test boundaries and compare predictions with fixture outputs.
Technical focus
The session connected an approachable introduction with binary analysis and malware internals. Its emphasis was on the reasoning process: asking what a program does, examining its parts, and building an explanation from evidence.
Technical context: from analogy to a testable explanation
The following worked example is added for this archive. It is not a reconstruction of a demonstration delivered in May 2023.
The pizza analogy is useful because it starts with a finished object and asks how its parts produce the whole. With software, however, the analyst must also account for decisions that depend on input and execution state. Looking at an ingredient list is not equivalent to observing the preparation process.
For a binary, the first layer might be its file format and architecture. The next might be functions, constants, and references. The explanation then needs to connect those pieces: which input reaches a comparison, which branch follows, and what output or side effect results?
A benign decision to recover
Consider the site’s six-byte frame example. After the frame passes its format and checksum checks, its enabling flag and reading determine the result. For a valid, enabled frame, the threshold condition is reading greater than 3000, not greater than or equal to 3000.
That single distinction gives an analyst useful boundary cases:
| Valid frame input | Expected threshold behavior |
|---|---|
| Enabled, reading 2999 | Does not exceed the threshold. |
| Enabled, reading 3000 | Does not exceed the threshold. |
| Enabled, reading 3001 | Exceeds the threshold. |
| Disabled, reading 3001 | The enabling condition prevents the positive result. |
A checksum failure belongs to an earlier validation path. Treating it as an ordinary low reading would lose part of the recovered behavior.
Static interpretation and observation
Disassembly exposes instructions; decompilation helps express them in a higher-level form. Neither automatically recovers the original author’s variable names or intent. The Ghidra project provides tools for disassembly and decompilation, but the analyst still has to interpret the result and test relevant assumptions.
For malware analysis, the same discipline separates a suspicious capability from an observed action. A networking function in a binary is a lead. Explaining its arguments, reachability, and relationship to captured activity turns that lead into a finding.
A good explanation therefore ends with something another reader can inspect: the relevant input, the recovered condition, the resulting behavior, and the limits of the evidence.
My role and related work
I delivered the introductory presentation in May 2023. The session is recorded in my technical presentations history.
The same interest in making reverse engineering understandable informs my compiled-binary walkthrough and interactive reverse-engineering Lab. Those are separate, newer demonstrations.
Expressing the recovered condition
Once format and checksum validation has succeeded, the decision can be written as:
Here, e means the enabling flag is set, r is the unsigned reading, and b is the positive threshold result. This equation deliberately excludes invalid frames: those take a separate rejection path.
# Teaching helper for already validated inputs, not a frame parser.
def exceeds_threshold(reading, enabled):
return enabled and reading > 3000
assert not exceeds_threshold(3000, True)
assert exceeds_threshold(3001, True)
assert not exceeds_threshold(3001, False)
The compact expression makes a subtle branch difference visible. Replacing > with >= changes the result at exactly 3000. The downloadable fixture additionally verifies parsing, flag handling, and checksum failures.