// Copyright (c) StellaOps. All rights reserved.
// Licensed under AGPL-3.0-or-later. See LICENSE in the project root.
using System.Collections.Immutable;
namespace StellaOps.BinaryIndex.Ghidra;
///
/// Bridge interface for ghidriff Python tool integration.
/// ghidriff provides automated binary diff reports using Ghidra.
///
public interface IGhidriffBridge
{
///
/// Run ghidriff to compare two binaries.
///
/// Path to the older binary version.
/// Path to the newer binary version.
/// ghidriff configuration options.
/// Cancellation token.
/// Diff result with added, removed, and modified functions.
Task DiffAsync(
string oldBinaryPath,
string newBinaryPath,
GhidriffDiffOptions? options = null,
CancellationToken ct = default);
///
/// Run ghidriff to compare two binaries from streams.
///
/// Stream of the older binary version.
/// Stream of the newer binary version.
/// ghidriff configuration options.
/// Cancellation token.
/// Diff result with added, removed, and modified functions.
Task DiffAsync(
Stream oldBinary,
Stream newBinary,
GhidriffDiffOptions? options = null,
CancellationToken ct = default);
///
/// Generate a formatted report from ghidriff results.
///
/// The diff result to format.
/// Output format.
/// Cancellation token.
/// Formatted report string.
Task GenerateReportAsync(
GhidriffResult result,
GhidriffReportFormat format,
CancellationToken ct = default);
///
/// Check if ghidriff is available (Python + ghidriff installed).
///
/// Cancellation token.
/// True if ghidriff is available.
Task IsAvailableAsync(CancellationToken ct = default);
///
/// Get ghidriff version information.
///
/// Cancellation token.
/// Version string.
Task GetVersionAsync(CancellationToken ct = default);
}
///
/// Options for ghidriff diff operation.
///
public sealed record GhidriffDiffOptions
{
///
/// Path to Ghidra installation (auto-detected if not set).
///
public string? GhidraPath { get; init; }
///
/// Path for Ghidra project files (temp dir if not set).
///
public string? ProjectPath { get; init; }
///
/// Whether to include decompiled code in results.
///
public bool IncludeDecompilation { get; init; } = true;
///
/// Whether to include disassembly listing in results.
///
public bool IncludeDisassembly { get; init; } = true;
///
/// Functions to exclude from comparison (by name pattern).
///
public ImmutableArray ExcludeFunctions { get; init; } = [];
///
/// Maximum number of concurrent Ghidra instances.
///
public int MaxParallelism { get; init; } = 1;
///
/// Maximum analysis time in seconds.
///
public int TimeoutSeconds { get; init; } = 600;
}
///
/// Result of a ghidriff comparison.
///
/// SHA256 hash of the old binary.
/// SHA256 hash of the new binary.
/// Name/path of the old binary.
/// Name/path of the new binary.
/// Functions added in new binary.
/// Functions removed from old binary.
/// Functions modified between versions.
/// Comparison statistics.
/// Raw JSON output from ghidriff.
public sealed record GhidriffResult(
string OldBinaryHash,
string NewBinaryHash,
string OldBinaryName,
string NewBinaryName,
ImmutableArray AddedFunctions,
ImmutableArray RemovedFunctions,
ImmutableArray ModifiedFunctions,
GhidriffStats Statistics,
string RawJsonOutput);
///
/// A function from ghidriff output.
///
/// Function name.
/// Function address.
/// Function size in bytes.
/// Decompiled signature.
/// Decompiled C code (if requested).
public sealed record GhidriffFunction(
string Name,
ulong Address,
int Size,
string? Signature,
string? DecompiledCode);
///
/// A function diff from ghidriff output.
///
/// Function name.
/// Address in old binary.
/// Address in new binary.
/// Size in old binary.
/// Size in new binary.
/// Signature in old binary.
/// Signature in new binary.
/// Similarity score.
/// Decompiled code from old binary.
/// Decompiled code from new binary.
/// List of instruction-level changes.
public sealed record GhidriffDiff(
string FunctionName,
ulong OldAddress,
ulong NewAddress,
int OldSize,
int NewSize,
string? OldSignature,
string? NewSignature,
decimal Similarity,
string? OldDecompiled,
string? NewDecompiled,
ImmutableArray InstructionChanges);
///
/// Statistics from ghidriff comparison.
///
/// Total functions in old binary.
/// Total functions in new binary.
/// Number of added functions.
/// Number of removed functions.
/// Number of modified functions.
/// Number of unchanged functions.
/// Time taken for analysis.
public sealed record GhidriffStats(
int TotalOldFunctions,
int TotalNewFunctions,
int AddedCount,
int RemovedCount,
int ModifiedCount,
int UnchangedCount,
TimeSpan AnalysisDuration);
///
/// Report output format for ghidriff.
///
public enum GhidriffReportFormat
{
/// JSON format.
Json,
/// Markdown format.
Markdown,
/// HTML format.
Html
}