save progress
This commit is contained in:
@@ -0,0 +1,299 @@
|
||||
// Copyright (c) StellaOps. All rights reserved.
|
||||
// Licensed under AGPL-3.0-or-later. See LICENSE in the project root.
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using StellaOps.BinaryIndex.Disassembly;
|
||||
|
||||
namespace StellaOps.BinaryIndex.DeltaSig;
|
||||
|
||||
/// <summary>
|
||||
/// Signature generation options.
|
||||
/// </summary>
|
||||
/// <param name="IncludeCfg">Include control flow graph metrics.</param>
|
||||
/// <param name="IncludeChunks">Include rolling chunk hashes for resilience.</param>
|
||||
/// <param name="ChunkSize">Size of rolling chunks in bytes (default 2KB).</param>
|
||||
/// <param name="HashAlgorithm">Hash algorithm to use (default sha256).</param>
|
||||
public sealed record SignatureOptions(
|
||||
bool IncludeCfg = true,
|
||||
bool IncludeChunks = true,
|
||||
int ChunkSize = 2048,
|
||||
string HashAlgorithm = "sha256");
|
||||
|
||||
/// <summary>
|
||||
/// Request for generating delta signatures from a binary.
|
||||
/// </summary>
|
||||
public sealed record DeltaSignatureRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// CVE identifier (e.g., CVE-2024-1234).
|
||||
/// </summary>
|
||||
public required string Cve { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Package name.
|
||||
/// </summary>
|
||||
public required string Package { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Shared object name (e.g., libssl.so.1.1).
|
||||
/// </summary>
|
||||
public string? Soname { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Target architecture (e.g., x86_64, aarch64).
|
||||
/// </summary>
|
||||
public required string Arch { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// ABI (e.g., gnu, musl, android).
|
||||
/// </summary>
|
||||
public string Abi { get; init; } = "gnu";
|
||||
|
||||
/// <summary>
|
||||
/// Symbol names to generate signatures for.
|
||||
/// </summary>
|
||||
public required IReadOnlyList<string> TargetSymbols { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// State of this signature: "vulnerable" or "patched".
|
||||
/// </summary>
|
||||
public required string SignatureState { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Signature generation options.
|
||||
/// </summary>
|
||||
public SignatureOptions? Options { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A complete delta signature for a binary.
|
||||
/// </summary>
|
||||
public sealed record DeltaSignature
|
||||
{
|
||||
/// <summary>
|
||||
/// Schema identifier for this signature format.
|
||||
/// </summary>
|
||||
public string Schema { get; init; } = "stellaops.deltasig.v1";
|
||||
|
||||
/// <summary>
|
||||
/// Schema version.
|
||||
/// </summary>
|
||||
public string SchemaVersion { get; init; } = "1.0.0";
|
||||
|
||||
/// <summary>
|
||||
/// CVE this signature is for.
|
||||
/// </summary>
|
||||
public required string Cve { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Package reference.
|
||||
/// </summary>
|
||||
public required PackageRef Package { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Target platform reference.
|
||||
/// </summary>
|
||||
public required TargetRef Target { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Normalization recipe used.
|
||||
/// </summary>
|
||||
public required NormalizationRef Normalization { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Signature state: "vulnerable" or "patched".
|
||||
/// </summary>
|
||||
public required string SignatureState { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Individual symbol signatures.
|
||||
/// </summary>
|
||||
public required ImmutableArray<SymbolSignature> Symbols { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// When this signature was generated (UTC).
|
||||
/// </summary>
|
||||
public DateTimeOffset GeneratedAt { get; init; } = DateTimeOffset.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// Additional metadata.
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<string, object>? Metadata { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Package reference for a delta signature.
|
||||
/// </summary>
|
||||
/// <param name="Name">Package name.</param>
|
||||
/// <param name="Soname">Shared object name.</param>
|
||||
public sealed record PackageRef(string Name, string? Soname);
|
||||
|
||||
/// <summary>
|
||||
/// Target platform reference.
|
||||
/// </summary>
|
||||
/// <param name="Arch">CPU architecture (x86_64, aarch64, etc.).</param>
|
||||
/// <param name="Abi">ABI (gnu, musl, android, etc.).</param>
|
||||
public sealed record TargetRef(string Arch, string Abi);
|
||||
|
||||
/// <summary>
|
||||
/// Normalization recipe reference for reproducibility.
|
||||
/// </summary>
|
||||
/// <param name="RecipeId">Recipe identifier (e.g., elf.delta.norm.x64).</param>
|
||||
/// <param name="RecipeVersion">Recipe version.</param>
|
||||
/// <param name="Steps">List of normalization steps applied.</param>
|
||||
public sealed record NormalizationRef(
|
||||
string RecipeId,
|
||||
string RecipeVersion,
|
||||
ImmutableArray<string> Steps);
|
||||
|
||||
/// <summary>
|
||||
/// Signature for a single symbol (function).
|
||||
/// </summary>
|
||||
public sealed record SymbolSignature
|
||||
{
|
||||
/// <summary>
|
||||
/// Symbol name.
|
||||
/// </summary>
|
||||
public required string Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Section containing the symbol (e.g., .text).
|
||||
/// </summary>
|
||||
public string Scope { get; init; } = ".text";
|
||||
|
||||
/// <summary>
|
||||
/// Hash algorithm used.
|
||||
/// </summary>
|
||||
public required string HashAlg { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Hash of the normalized function as hex string.
|
||||
/// </summary>
|
||||
public required string HashHex { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Size of the normalized function in bytes.
|
||||
/// </summary>
|
||||
public required int SizeBytes { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of basic blocks in the control flow graph.
|
||||
/// </summary>
|
||||
public int? CfgBbCount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Hash of the CFG structure (edges).
|
||||
/// </summary>
|
||||
public string? CfgEdgeHash { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Rolling chunk hashes for resilience against small changes.
|
||||
/// </summary>
|
||||
public ImmutableArray<ChunkHash>? Chunks { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hash of a chunk within a function for resilience.
|
||||
/// </summary>
|
||||
/// <param name="Offset">Offset from function start.</param>
|
||||
/// <param name="Size">Chunk size in bytes.</param>
|
||||
/// <param name="HashHex">Hash of the chunk as hex string.</param>
|
||||
public sealed record ChunkHash(int Offset, int Size, string HashHex);
|
||||
|
||||
/// <summary>
|
||||
/// Result of matching a binary against delta signatures.
|
||||
/// </summary>
|
||||
public sealed record MatchResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether a match was found.
|
||||
/// </summary>
|
||||
public required bool Matched { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The CVE that matched.
|
||||
/// </summary>
|
||||
public string? Cve { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The signature state that matched (vulnerable/patched).
|
||||
/// </summary>
|
||||
public string? SignatureState { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Confidence score (0.0 - 1.0).
|
||||
/// </summary>
|
||||
public double Confidence { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Individual symbol match results.
|
||||
/// </summary>
|
||||
public ImmutableArray<SymbolMatchResult> SymbolMatches { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Explanation of the match result.
|
||||
/// </summary>
|
||||
public string? Explanation { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Match result for a single symbol.
|
||||
/// </summary>
|
||||
public sealed record SymbolMatchResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Symbol name.
|
||||
/// </summary>
|
||||
public required string SymbolName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the symbol hash matched exactly.
|
||||
/// </summary>
|
||||
public required bool ExactMatch { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of chunk hashes that matched (partial match).
|
||||
/// </summary>
|
||||
public int ChunksMatched { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Total chunks in the signature.
|
||||
/// </summary>
|
||||
public int ChunksTotal { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Match confidence (0.0 - 1.0).
|
||||
/// </summary>
|
||||
public double Confidence { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Result of authoring signatures from vulnerable and patched binaries.
|
||||
/// </summary>
|
||||
public sealed record AuthoringResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether authoring succeeded.
|
||||
/// </summary>
|
||||
public required bool Success { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Signature for the vulnerable binary.
|
||||
/// </summary>
|
||||
public DeltaSignature? VulnerableSignature { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Signature for the patched binary.
|
||||
/// </summary>
|
||||
public DeltaSignature? PatchedSignature { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Symbols that differ between vulnerable and patched.
|
||||
/// </summary>
|
||||
public ImmutableArray<string> DifferingSymbols { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Error message if authoring failed.
|
||||
/// </summary>
|
||||
public string? Error { get; init; }
|
||||
}
|
||||
Reference in New Issue
Block a user