reverse-eng-malware

Fully analyze a malware sample — static, dynamic, and behavioral — including unpacking and IAT rebuild, import-table triage, anti-analysis detection and defeat, IOC extraction, and YARA/Sigma rule wri

SKILL.md

GitHub

Malware analysis (deep RE)

When it applies

defense-malware-triage gave a verdict and you need the deep dive: a packed or obfuscated sample, a family you must write durable detection for, or an implant recovered on an engagement whose C2, injection, and persistence mechanisms you need to document. Covers EXE / DLL / SYS / .NET and script droppers (bat, ps1, vba). Always work inside an isolated analysis VM — detonating an unknown sample on a real host is itself an incident.

Why it works

Malware hides its intent behind packing, dynamic API resolution, and environment checks, but every layer must eventually resolve to real API calls and real behavior. Static analysis maps the capabilities; a debugger or sandbox catches what only exists at runtime (decrypted strings, resolved imports, injected code). Detection written on code/string internals — not hashes — survives recompilation.

Method

Anti-analysis catalog, YARA/Sigma writing guide, and rule examples: see cheatsheet.md next to this file.

  1. Triage fast. file, sha256sum (hash-check VT / MalwareBazaar / Triage — don't upload a possibly targeted sample), diec (packer/compiler ID), floss (deobfuscated strings), pecheck / pescan (PE structural anomalies), rabin2 -zz (strings + xrefs). Record the file class: EXE / DLL / SYS / .NET / script — each has its own anchors below.
  2. Unpack and rebuild the IAT if packed: x86 → ImportREC, x64 → Scylla. If repair fails or the dumped binary crashes on start (self CRC/size checks), stop repairing statically, record the failure, and go dynamic: break on CreateFile / GetFileSize / hashing APIs and use hardware breakpoints or memory search to catch the imports at runtime.
  3. Static deep-dive (Ghidra / IDA / radare2 / x64dbg). One mandatory pass: classify the import table (rabin2 -i / pecheck) into network / file / crypto / process-injection / registry. DLL/SYS → dump the export table too (rabin2 -E). .NET has no classic IAT — use dnSpy IL / metadata / assembly references as the equivalent anchor. A suspiciously clean import table means dynamic resolution — break on GetProcAddress and look for API-hash loops. No ASCII IOCs → retry wide strings (strings -el). Also check .rsrc for embedded payloads and TLS callbacks for code that runs before the entry point.
  4. Dynamic run. Pre-set breakpoints in this order: TLS callbacks → entry point → sensitive APIs → ExitProcess (dump memory the moment it fires, before restarting). Watch: process creation, file writes (ransomware?) or deletes (wiper?), Run/RunOnce keys, HTTP/DNS (C2), VirtualAllocEx (injection), CreateService (persistence). Sandboxes: CAPE (open source, YARA-integrated), Joe Sandbox / ANY.RUN / Triage (commercial), Cuckoo (legacy). Submit to a local CAPE: curl -F "file=@sample.exe" http://localhost:8000/apiv2/tasks/create/file/.
  5. No behavior? The sample is checking its environment (CPUID, RDTSC, PEB flags, tool process names, disk/RAM size). Locate the check statically, patch it or bypass with hardware breakpoints, or move to a higher-fidelity host. Record "no behavior + the condition found" — a dormant run never means "benign".
  6. Produce detection and intel. YARA on stable strings/opcodes; Sigma for behavioral telemetry (tag ATT&CK IDs, convert with sigmac -t splunk rule.yml or sigma convert). Extract IOCs by class: network (C2 IP/domain/URL/User-Agent), host (file paths, mutexes, Run keys, service names), behavioral (ATT&CK techniques), static (PDB path, anomalous section names, import combos like CryptEncrypt + shadow-copy deletion).

Gotchas

  • ImportREC on 64-bit samples does not work — use Scylla on x64.
  • Signed ≠ safe — verify with sigcheck; a forged or revoked signature does not lower the threat level.
  • Long import tables — filter OS noise and report the malicious combination clusters (e.g. FindWindow + WriteProcessMemory + CreateRemoteThread).
  • Script/macro samples — deobfuscate layer by layer (bat set splicing, PowerShell Base64/Gzip/IEX string reversal, VBA stomping/P-code) and keep every layer as evidence.
  • A dormant sample is not a clean sample — use the anti-analysis catalog in the cheatsheet to find what it was checking for.

Verify success

You can state the family/capabilities and the full chain (dropper → payload → persistence → C2), you have host + network IOCs, and a tested YARA rule (matches the sample set, clean against benign files) and/or a Sigma rule — reproducible by someone else from your recorded commands.

References

CAPE/Cuckoo docs; YARA & SigmaHQ rule guides; FLOSS; Detect It Easy; pe-sieve. Ship the Sigma rule with defense-detection-sigma; fast verdicts with defense-malware-triage; generic binary work with reverse-eng-binary-triage and reverse-eng-deobfuscation.


Portions adapted from reverse-skill by zhaoxuya520, MIT License.