Skip to content

Commit 9c23f79

Browse files
committed
feat(obfuscation): multi-signal obfuscation analysis with detection wiring
Add ObfuscationProfile per function: sliding-window + const-pool entropy, byte-array payload runs, indirect-dispatch ratio, control-flow-flattening (fan-in), and in-loop decoder shape. Scoring: dispositive (data-entropy) signals flag alone; structural signals corroborate only (lone-signal cap below MODERATE). Applicability gating stops inapplicable signals diluting the mean; a dispositive floor keeps corroboration from ever lowering a score. Detection: relax the required-call hard gate for indirect-dispatch samples; add an obf>0.8 confidence floor on already-partial matches; carry obfuscation score/class/signals into Signature and MatchDetails. Tests: helper units, SSA integration, nil-fn fallback, fuzz seeds, benchmark, and engine gate/floor/visibility behavior. README documents per-function scope and the known package-level-payload gap.
1 parent de79499 commit 9c23f79

8 files changed

Lines changed: 1327 additions & 3 deletions

File tree

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,17 @@ Where $p(x_i)$ is the probability of byte value $x_i$ appearing in the function'
610610

611611
Functions with HIGH or PACKED entropy combined with suspicious call patterns receive elevated confidence scores.
612612

613+
### Multi-Signal Obfuscation Profile
614+
615+
Beyond string-literal entropy, each function gets an `ObfuscationProfile` combining six signals into a single 0..1 score (`NONE`/`LOW`/`MODERATE`/`HIGH`). The signals are weighted by evidentiary strength:
616+
617+
- **Dispositive** (data-entropy — sufficient alone to flag a function): sliding-window entropy over the full constant pool (catches a packed blob averaged away by benign log strings), non-string const-pool entropy (catches `[]byte{...}` / `[]int` payloads that never enter string literals), and byte-array payload runs.
618+
- **Corroborating** (structural — consistent with idiomatic Go, so meaningful only in combination): indirect/reflective dispatch ratio, control-flow-flattening (fan-in concentration at a dispatcher header), and in-loop byte-decoder shape.
619+
620+
A single corroborating signal cannot by itself reach `MODERATE` — it takes one dispositive signal, or two corroborating signals together. This avoids flagging benign higher-order functions (callback runners, visitors, middleware), which are indirect-dispatch by construction.
621+
622+
**Known gap — package-level payloads.** Payload entropy is attributed per-function: a high-entropy literal local to the analyzed function is detected directly. Package-level payload globals are **not yet** attributed to their consuming function (the constants are lowered into package `init`, not the function body); these are intended to be caught by a paired decoder-loop heuristic, which is not yet implemented. Until then, package-level-blob + separate-decoder layouts are a known gap.
623+
613624
### Call Signature Resolution
614625

615626
The topology extractor resolves call targets to stable identifiers:

0 commit comments

Comments
 (0)