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