A malware classifier almost never looks at raw bytes directly (Unit 2's examples assumed features like these already existed). Static analysis extracts structural features without ever running the file, which is both safer and faster than dynamic analysis:
- Imported API calls: does the file import
CreateRemoteThread,VirtualAllocEx, orRegSetValue, each associated more often with malicious than benign software. - Section entropy: a packed or encrypted payload has high byte-level entropy; a normal code section does not. Entropy above roughly 7.0 bits per byte (out of a maximum of 8) is a classic packing indicator.
- PE header anomalies: an unusual number of sections, a suspicious timestamp, or a mismatched declared-versus-actual file size.
- String artefacts: embedded URLs, IP addresses, or suspicious strings such as command-and-control-style domain patterns.
Tool in focus: Shannon Entropy as a Packing Detector
Entropy, $H = -\sum_i p_i \log_2 p_i$ over the byte-value distribution $p_i$, measures randomness. Ordinary executable code and English-like strings sit well below the theoretical maximum of 8 bits per byte; compressed or encrypted payloads sit close to it. A single numpy one-liner over a file's raw bytes is often the single most informative static feature a malware classifier can have.
shannon_entropy.py
import numpy as np
def shannon_entropy(data: bytes) -> float:
if not data:
return 0.0
counts = np.bincount(np.frombuffer(data, dtype=np.uint8), minlength=256)
probs = counts[counts > 0] / len(data)
return float(-np.sum(probs * np.log2(probs)))
Try it yourself: Read the Entropy
Running shannon_entropy over three files gives: a plain-text README at 4.1 bits per byte, an ordinary unpacked executable at 5.8 bits per byte, and a suspicious downloaded file at 7.9 bits per byte. Using the packing threshold from this topic, which file most warrants a closer look, and what does its entropy alone, with no other evidence, actually tell you, and not tell you, about what it contains?

