Help us shape the future of Go! Take the 2026 Go Developer Survey

topology

package
v7.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 19, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CapExec       = "exec"
	CapSyscall    = "syscall"
	CapPlugin     = "plugin"
	CapNetwork    = "network"
	CapReflection = "reflection"
	CapFilesystem = "filesystem"
)

Capability classes name the families of security-sensitive operations a function can reach. Risk scoring treats the first appearance of a class in a function as an escalation, independent of how many calls changed.

Variables

View Source
var (
	MaxStringLiteralLen = 4096      // 4KB limit per string
	MaxTotalStringBytes = 1024 * 64 // 64KB limit per function

)

Functions

func CalculateEntropy

func CalculateEntropy(data []byte) float64

Returns the Shannon entropy of a byte slice. Result ranges from 0.0 (completely uniform/predictable) to 8.0 (maximum randomness). High entropy (>7.0) often indicates packed/encrypted code. Normal code typically has entropy between 4.5 and 6.5.

func CallGuards added in v7.2.0

func CallGuards(fn, callee *ssa.Function) (n int, ok bool)

CallGuards returns the fewest conditional branches, loop conditions excluded, that any reference to callee in fn is control-dependent on, counted as CapabilityGuards counts a capability's references. ok is false when fn does not reference callee, or has more than 2000 blocks.

func CalleeCapability

func CalleeCapability(callee *ssa.Function) (key, class string, ok bool)

CalleeCapability returns the CallTargets key of a callee and its capability class ("" when it has none). ok is false for a package initializer, which is not a call target.

func ClassifyCallTarget

func ClassifyCallTarget(pkgPath, recv, name string) string

ClassifyCallTarget maps a callee, identified by import path, receiver type name ("" for package-level functions) and function name, to its capability class, or "" when the callee is not security-sensitive.

func EntropyDistance

func EntropyDistance(e1, e2 float64) float64

Calculates the absolute difference between two entropy values. Used for fuzzy matching: two functions with similar entropy are more likely related.

func GenerateFuzzyHash

func GenerateFuzzyHash(t *FunctionTopology) string

GenerateFuzzyHash creates a short representation of the function structure.

func IsVerificationCall

func IsVerificationCall(pkgPath, recv, name string) bool

IsVerificationCall reports whether a callee, identified like ClassifyCallTarget's arguments, is a verification primitive: a constant-time or MAC comparison, a signature or certificate check, a password hash comparison, or a path containment check.

func MapSimilarity

func MapSimilarity(a, b map[string]int) float64

MapSimilarity calculates the similarity between two frequency maps.

func SetTopologyLimits

func SetTopologyLimits(maxLen, maxTotal int)

SetTopologyLimits adjusts the memory safeguards for string processing.

func TopologyFingerprint

func TopologyFingerprint(t *FunctionTopology) string

func TopologySimilarity

func TopologySimilarity(a, b *FunctionTopology) float64

TopologySimilarity calculates the similarity between two function topologies.

Types

type EntropyClass

type EntropyClass int

Categorizes entropy levels for quick analysis.

const (
	EntropyLow    EntropyClass = iota // < 4.0: Simple/sparse code
	EntropyNormal                     // 4.0-6.5: Typical compiled code
	EntropyHigh                       // 6.5-7.5: Potentially obfuscated
	EntropyPacked                     // > 7.5: Likely packed/encrypted
)

func ClassifyEntropy

func ClassifyEntropy(entropy float64) EntropyClass

Determines the entropy class from a raw entropy value.

func (EntropyClass) String

func (c EntropyClass) String() string

type EntropyProfile

type EntropyProfile struct {
	// Overall entropy of the function body
	Overall float64

	// Entropy of string literals within the function
	StringLiteralEntropy float64

	// Entropy classification
	Classification EntropyClass
}

Captures entropy characteristics for malware analysis.

func CalculateEntropyProfile

func CalculateEntropyProfile(bodyBytes []byte, stringLiterals []string) EntropyProfile

Builds a complete entropy profile for analysis.

type FunctionTopology

type FunctionTopology struct {
	FuzzyHash string

	// Basic metrics
	ParamCount  int
	ReturnCount int
	BlockCount  int
	InstrCount  int
	LoopCount   int
	BranchCount int // if statements
	PhiCount    int

	// Complexity metrics
	CyclomaticComplexity int

	// Call profile: map of "package.func" or "method" -> count
	CallSignatures map[string]int

	// CallTargets counts every function called or referenced as a value,
	// keyed by import-path-qualified name ("os/exec.Command"). Package
	// initializers are excluded. Capabilities maps the subset of those keys
	// that are security-sensitive to their capability class (CapExec, ...).
	CallTargets  map[string]int
	Capabilities map[string]string

	// Checks holds the verifications this function performs: calls to a
	// verification primitive (MAC and signature checks, certificate
	// verification, password hash comparison; see IsVerificationCall), to a
	// helper that reaches one, and to a function or interface method named
	// like a verification whose result decides a branch (see
	// collectCheckHelpers). Losing one is how a guard gets deleted.
	Checks map[string]bool

	// CapabilityGuards maps each Capabilities key to the fewest conditional
	// branches, loop conditions excluded, that any of its references in this
	// function is control-dependent on. 0 means some reference runs
	// unconditionally. Nil when the function has more than 2000 blocks.
	CapabilityGuards map[string]int

	// WeakSettings and SecureSettings hold constant stores to security
	// configuration fields, written "crypto/tls.Config.InsecureSkipVerify=true".
	// A weak setting weakens security on its own; a secure setting weakens it
	// by its removal. See collectSecuritySettings.
	WeakSettings   map[string]bool
	SecureSettings map[string]bool

	// ErrorExits counts the two-way branches with exactly one side that ends
	// the function with a failure: a non-nil error return, a panic, a call
	// that never returns, or an HTTP 4xx/5xx response.
	ErrorExits int

	// Granular instruction tracking
	InstrCounts map[string]int

	// Type signature (normalized)
	ParamTypes  []string
	ReturnTypes []string

	// Control flow features
	HasDefer   bool
	HasRecover bool
	HasPanic   bool
	HasGo      bool
	HasSelect  bool
	HasRange   bool

	// HasInfiniteLoop reports a `for` statement without a condition
	// (`for { ... }`) in the function's own body. Such a loop only ends
	// through break, return, goto or panic.
	HasInfiniteLoop bool

	// Operator profile
	BinOpCounts map[string]int
	UnOpCounts  map[string]int

	// String literal hashes (for behavioral matching)
	StringLiterals []string

	// Entropy analysis for obfuscation detection
	EntropyScore   float64
	EntropyProfile EntropyProfile

	// Multi-signal obfuscation analysis: sliding-window and const-pool entropy,
	// indirect/reflective dispatch ratio, control-flow flattening, and in-loop
	// decoder fingerprints. Captures payloads the string-only entropy path misses.
	Obfuscation ObfuscationProfile
	// contains filtered or unexported fields
}

FunctionTopology captures the structural "shape" of a function independent of names.

func ExtractTopology

func ExtractTopology(fn *ssa.Function) *FunctionTopology

ExtractTopology analyzes an SSA function and extracts its structural features.

type ObfuscationClass

type ObfuscationClass int

ObfuscationClass buckets the overall obfuscation score for quick triage.

const (
	ObfuscationNone     ObfuscationClass = iota // < 0.25
	ObfuscationLow                              // 0.25 - 0.50
	ObfuscationModerate                         // 0.50 - 0.75
	ObfuscationHigh                             // >= 0.75
)

func (ObfuscationClass) String

func (c ObfuscationClass) String() string

type ObfuscationProfile

type ObfuscationProfile struct {
	// MaxWindowEntropy is the highest Shannon entropy (0..8) found in any
	// sliding window across the concatenated constant pool (strings + byte/int
	// arrays). Unlike a global mean, a single packed blob surfaces here even
	// when surrounded by benign data.
	MaxWindowEntropy float64

	// ConstPoolEntropy is the Shannon entropy (0..8) of the *non-string*
	// constant pool: integer and byte constants flowing into the function.
	// This is the signal the old path was completely missing.
	ConstPoolEntropy float64

	// ByteArrayPayloadBytes is the total number of bytes contributed by
	// small-integer constants (0..255) that look like an encoded payload.
	ByteArrayPayloadBytes int

	// IndirectCallRatio is dynamic+reflective calls over all calls. High values
	// indicate dispatch-table / reflection obfuscation that evades name-based
	// signatures.
	IndirectCallRatio float64

	// FlatteningScore estimates control-flow-flattening likelihood from the
	// dispatcher shape (one block with many predecessors and successors driving
	// a state variable). 0..1.
	FlatteningScore float64

	// DecoderLoopLikelihood is 0..1 evidence of an in-loop decode/XOR routine:
	// a loop body containing byte-wise arithmetic/bitwise ops over an indexed
	// buffer. This is the structural fingerprint of a string/payload decryptor.
	DecoderLoopLikelihood float64

	// Score is the aggregate 0..1 obfuscation score.
	Score float64

	// Class is the bucketed Score.
	Class ObfuscationClass

	// Indicators lists the human-readable signals that fired, for reporting.
	Indicators []string
}

ObfuscationProfile captures multi-signal obfuscation evidence for a function. All ratios are normalized 0..1 unless noted.

func AnalyzeObfuscation

func AnalyzeObfuscation(t *FunctionTopology) ObfuscationProfile

AnalyzeObfuscation builds an ObfuscationProfile for an already-extracted topology. It re-walks the SSA function (held in t.fn) to gather the non-string constant pool, which ExtractTopology intentionally does not retain. If the underlying function is unavailable it falls back to string-only signals so the result is still meaningful for synthesized topologies in tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL