3.4 KiB
name, description, domain, subdomain, tags, version, author, license, mitre_attack, d3fend, references
| name | description | domain | subdomain | tags | version | author | license | mitre_attack | d3fend | references | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| writing-yara-rules-from-reversed-code | Turns reverse-engineering findings into durable YARA detections: selecting stable code constructs and constants over volatile strings, extracting opcode/byte patterns with wildcards, and validating rules for low false positives. Activates for requests to write a YARA rule from reversed code, create a detection signature, or convert RE findings into hunting rules. | cybersecurity | reverse-engineering |
|
1.0.0 | analyst-ai-pack | Apache-2.0 |
|
|
|
Writing YARA Rules from Reversed Code
When to Use
- You finished reversing a sample/family and want a detection that survives recompilation and cosmetic changes.
- You need byte-pattern signatures from decryptors, API-hash constants, or unique algorithms rather than fragile strings.
- You are converting RE notes into hunting/scanning rules for a corpus.
Do not use volatile artifacts (file paths, mutex names that change per build, packer stubs shared across unrelated families) as your primary anchor — they cause drift and false hits.
Prerequisites
- The
yaraengine (and ideallyyara-python) for testing. - A small corpus: target samples (true positives) and clean/unrelated files (false-positive control).
Workflow
Step 1: Choose stable anchors
Prefer, in order: a unique algorithm's opcode sequence (decryptor, hashing loop), embedded magic constants (API hashes, XOR keys, S-box), then distinctive strings only if intrinsic.
Step 2: Extract byte patterns with wildcards
Pull the relevant opcodes and wildcard volatile operands (addresses, immediates) so the rule survives relocation/recompilation:
$dec = { 8A 04 ?? 34 ?? 88 04 ?? 41 3B ?? 7? ?? } ; xor-decrypt loop, regs/disp wildcarded
Step 3: Assemble the rule
Combine 2–3 independent anchors with a condition requiring enough of them, plus a cheap
prefilter (file size, PE magic) to keep scanning fast:
python scripts/analyst.py scaffold --name family_xyz --hash 0xABCDEF12
Step 4: Validate against the corpus
Run the rule across true positives and the clean control set; require all TPs match and zero FPs on the control.
yara -r rules/family_xyz.yar ./corpus
Step 5: Tune and document
Adjust thresholds, add meta (author, date, reference, hash), and record which construct each
string anchors so future analysts can maintain it.
Validation
- Rule matches all intended samples and produces zero hits on the clean control set.
- Anchors map to intrinsic code/constants, not build-specific noise.
metadocuments source samples and the reasoning for each pattern.
Pitfalls
- Wildcarding too little (brittle) or too much (false positives); wildcard only volatile bytes.
- Anchoring on shared library/packer code present in unrelated binaries.
- Skipping the clean-corpus test, shipping a noisy rule.
References
- See
references/api-reference.mdfor the rule scaffolder. - YARA documentation and style guide (linked in frontmatter).