Skip to content

v1.6.2

Choose a tag to compare

@totekuh totekuh released this 27 Aug 13:09
· 19 commits to master since this release

Winbox v1.6.2

Winbox 1.6.2 is a substantial kdbg and PyGhidra reliability patch. It completes
roadmap items 74–87 plus the remaining item 26 IPv6 listener fix: cancellable
offline analysis, deterministic cache repair, typed errors, non-blocking
progress, exact cache selection and accounting, selectable attach staging,
target-liveness diagnostics, bounded exact-PDB enrichment, complete enrichment
cache ownership, bounded PDB extraction, and durable preparation jobs.

Typed debugger and decompiler errors

  • Added the versioned winbox.error/1 error object across the debugger daemon,
    PyGhidra worker, clients, CLI, and every kdbg MCP wrapper. Errors now preserve
    stable codes, bounded messages and details, retryability, operation identity,
    and at most three recovery hints.
  • Retained legacy error strings for mixed-version compatibility while teaching
    current clients to prefer structured error data.
  • Classified invalid requests and arguments, busy/state conflicts, timeouts,
    cancellation, missing sessions and cache entries, stale identity, worker
    startup and transport failures, CR3 poisoning, and unsupported operations.
  • Standardized MCP failures on the existing winbox.mcp/1 envelope instead of
    embedding indented JSON or requiring callers to infer state from prose.

Non-blocking PyGhidra status and progress

  • Added an atomic API-6 heartbeat sidecar that reports worker health without
    starting the JVM or entering the serialized Ghidra request queue.
  • Status now distinguishes idle, busy, stale, unknown, and stopped,
    with active operation, exact request ID, phase, binary digest, elapsed time,
    phase progress, progress age, cancellation state, and bounded last failure.
  • Published progress for project import/open, auto-analysis, enrichment,
    decompilation, save, repair, and shutdown while keeping caller-supplied host
    paths out of the public heartbeat.
  • Added cooperative cancellation markers tied to an exact request ID. Client
    timeout, disconnect, explicit cancellation, SIGTERM, and SIGINT all converge
    on the same bounded cancellation path.

Offline preparation and resumable analysis

  • Added winbox kdbg ghidra prepare [MODULE|all] and
    kdbg_decomp_prepare(...) to analyze and enrich exact staged artifacts while
    the VM continues running, removing cold Ghidra work from debugger stop time.
  • Added optional attach-time --prewarm / prewarm=true, which starts offline
    preparation only after the exact attach manifest has been frozen.
  • Added foreground and durable background preparation, per-module results,
    bounded failures, analysis-timeout validation, and forceable enrichment
    regeneration.
  • Auto-analysis now uses a cooperative Ghidra task monitor. Cancellation or
    timeout leaves the project deliberately incomplete; the next exact request
    resumes that partial project instead of deleting useful analysis.
  • Added exact request-ID cancellation via winbox kdbg ghidra cancel --request-id ID and kdbg_decomp_cancel(request_id=...).
  • Fixed partial-project resume when exact private PDB names collide at one
    address. Existing equal names are reused; genuine Ghidra duplicate-name
    conflicts receive a deterministic RVA suffix and retain truthful provenance
    instead of failing the complete project.

Durable preparation-job lifecycle

  • Added random token-and-nonce background job identities, PID plus Linux
    process-start identity, one-second heartbeats, current module and exact worker
    request publication, and atomic state records.
  • Added winbox kdbg ghidra prepare-status [TOKEN] and
    kdbg_decomp_prepare_status(token=...) for latest or exact job inspection.
  • Reconciled dead and PID-reused launchers/children to a durable lost state
    instead of leaving jobs permanently starting, running, or cancelling.
  • Added nonce-bound token cancellation through winbox kdbg ghidra cancel --token TOKEN and kdbg_decomp_cancel(token=...). A child forwards the
    marker only to its own current request; terminal jobs reject cancellation
    safely as not_running.
  • Forwarded cancellation into PDB extraction before Ghidra starts, and routed
    SIGTERM/SIGINT through the same cooperative path.
  • Retained completed, partial, failed, cancelled, and lost records/logs for at
    most 30 days or 128 terminal jobs. Active, malformed, and symlink/untrusted
    records are never retention-pruned.
  • Kept version-1 job records readable as explicit legacy-unknown state during
    migration.

Deterministic cache recovery and exact pruning

  • Added automatic one-shot recovery when Ghidra proves that an exact
    digest/profile project is corrupt or truncated. Only that project's .gpr,
    .rep, .lock, and .lock~ are removed; the hash-addressed binary is
    revalidated and retained, then rebuilt once with no retry loop.
  • Added explicit winbox kdbg ghidra repair --sha256 DIGEST and
    kdbg_decomp_cache_repair(sha256) for the same exact reset/rebuild operation.
    There is no quarantine or backup cache area.
  • Extended cache pruning with repeatable exact SHA-256, project, and module
    selectors. Selectors combine as a union with age and maximum-size policies;
    dry-run remains the default.
  • Added unmatched-selector reporting, precise selected/removed files and bytes,
    owned versus overhead accounting, bounded unattributed paths, and explicit
    residual bytes when a size target cannot be met.
  • Reconciled shared content ownership so one binary can back multiple
    Ghidra/profile projects without double-counting or unsafe deletion.
  • Included digest-keyed enrichment inputs, enrichment results, and recovery
    provenance in the same cache entry. Orphan sidecars remain independently
    digest-addressable; exact pruning removes matching regular files while
    preserving unrelated digests and refusing symlinks.
  • Serialized applied prune and repair under the existing worker/cache
    maintenance lock, preventing mutation while projects are open or requests are
    active.

Selectable and observable attach staging

  • Added full, binaries, and cached-only attach staging policies. full
    preserves exact guest copying and symbol enrichment; binaries copies exact
    images without network symbol work; cached-only performs neither guest
    copies nor downloads and reuses only digest-verified stored artifacts.
  • Added mutation-free attach preflight with discovered modules, mapped byte
    totals, proposed guest/network work, bounded module inventory, and elapsed
    time without taking debugger ownership.
  • Added bounded per-module progress, copy/reuse/failure state, symbol state,
    artifact source, aggregate timing, and truthful complete-snapshot status to
    the frozen attach manifest.
  • Propagated staging policy and artifact source into debugger symbol and
    decompiler evidence so reduced staging cannot masquerade as a complete exact
    snapshot.
  • Added CLI and MCP policy/preflight/prewarm options with validation and kept
    the default behavior compatible as full.

Target-liveness and process-exit diagnostics

  • Captured the attached process's exact EPROCESS address and CreateTime in
    session identity, with ExitTime read from exact PDB-derived layouts when
    available.
  • Added winbox kdbg target-status and kdbg_target_status() to classify the
    original target as alive, exiting, gone, or unknown without silently
    following a reused numeric PID.
  • Compared both the captured EPROCESS directly and the current active-process
    list. Unlinked terminating processes remain identifiable; PID reuse reports
    bounded replacement evidence rather than rebinding the session.
  • Included the same target evidence in every continue-timeout boundary,
    including unrelated-CR3, predicate-filtered, and action-filtered stops.
  • Preserved optional-field compatibility when older/exact PDBs do not expose
    create or exit time.

Bounded exact-PDB enrichment

  • Introduced analysis profile winbox-pdb-enrichment-v3, keyed into durable
    Ghidra project identity so richer evidence cannot be confused with projects
    created under an older profile.
  • Extracted exact public and private function names, named globals, and only
    finite primitive/pointer function signatures whose PDB rendering proves
    their semantics. Variadics, recursive type graphs, excessive parameters,
    oversized names, and ambiguous types are rejected rather than guessed.
  • Applied enrichment inside one Ghidra transaction. Existing non-default names
    and signatures win conflicts; exact names may recover missing or truncated
    function boundaries without laundering inferred analysis as PDB truth.
  • Persisted bounded, atomic per-decision provenance for applied, reused,
    invalid, and conflict-preserved records, including exact source and actual
    applied name.
  • Bounded functions, globals, parameters, symbol output, sidecar size, event
    count, names, and paths. Sidecars are bound to exact PE SHA-256 and PDB build
    identity and are refused on path, symlink, schema, profile, or digest
    mismatch.
  • Public PDBs that contain names but omit private procedure types truthfully
    report zero applied signatures instead of inventing prototypes.

Truly bounded PDB extraction

  • Replaced subprocess.run(capture_output=True) with concurrent stdout/stderr
    drains that retain no more than their declared caps while continuously
    emptying both pipes.
  • Output overflow, timeout, caller cancellation, interruption, nonzero exit,
    and abnormal pipe lifetime terminate and deterministically reap the exact
    llvm-pdbutil child.
  • Kept stderr bounded for actionable diagnostics and made the 64 MiB symbol
    cap an allocation bound rather than an after-the-fact size check.

Exact IPv6 gdbstub listener detection

  • Decoded Linux /proc/net/tcp6 addresses from their four little-endian words
    and retained address-family identity during passive listener probes.
  • Matched only the requested family's exact address or wildcard. An IPv6-only
    listener can no longer make 127.0.0.1 appear occupied, and malformed rows
    are ignored instead of becoming wildcard matches.

CLI and MCP surface changes

  • Added CLI commands: kdbg target-status, kdbg ghidra repair, kdbg ghidra prepare, kdbg ghidra prepare-status, and kdbg ghidra cancel.
  • Extended kdbg attach with staging policy, preflight, and prewarm controls,
    and extended kdbg ghidra prune with exact SHA/project/module selectors.
  • Added MCP tools: kdbg_target_status, kdbg_decomp_cache_repair,
    kdbg_decomp_prepare, kdbg_decomp_prepare_status, and
    kdbg_decomp_cancel.
  • Extended existing MCP attach and cache-prune signatures while preserving safe
    defaults. The public catalog grows from 75 to 80 tools; the exhaustive
    CLI manifest covers 130 commands.

Tests and edge cases

  • Complete default suite: 2,692 passed, 5 skipped, 141 live tests
    deselected
    .
  • Focused changed-surface suite: 812 passed.
  • API-6 Docker worker policy suite: 13 passed.
  • Real Docker/PyGhidra integration passed against a stripped fixture, including
    exact signature/global application, duplicate private-name conflicts,
    provenance, corruption/reset/rebuild, cancellation, and partial resume.
  • Added real-process tests for bounded stdout and stderr, output amplification,
    nonzero exit, timeout, cancellation, pipe closure, exact child reaping, child
    death, PID reuse, token/nonce marker identity, signal handling, terminal
    retention, atomic writes, and symlink boundaries.
  • Added unit and integration coverage for typed daemon/worker/MCP errors,
    non-blocking status, every attach policy and preflight, target exit/PID reuse,
    exact cache selection/accounting, corrupt-project recovery, enrichment bounds
    and conflicts, IPv4/IPv6 listeners, CLI forwarding, MCP envelopes, and
    exhaustive CLI/MCP manifest counts.
  • git diff --check, complete CLI/MCP manifest accounting, machine-safe JSON,
    and narrow-terminal lifecycle output also pass.

Live verification

  • Server 2022 full, binaries-only, and cached-only staging all attached
    successfully; preflight performed no guest copies or network enrichment.
  • A temporary target exited during a durable continue and was reported as the
    original captured EPROCESS in exiting state with a real exit time.
  • Live services exact-PDB enrichment applied 1,417 function names and 1,716
    globals with 3,359 bounded provenance events, then reused the warm project in
    0.006 seconds.
  • A detached prepare job completed with a durable token. A cold apphelp
    analysis was cancelled during Ghidra analysis and resumed the same partial
    project successfully.
  • Live cache inventory and exact module/SHA/project dry runs reconciled all
    owned bytes. After enrichment ownership was added, unexplained cache usage
    fell from 1,842,202 bytes in four files to zero without deletion.
  • Bounded extraction completed against the exact services PDB. A cold
    background ntdll job exposed one exact request ID through job and worker
    state, transitioned running to cancelling to cancelled, and resumed its
    partial project to apply 2,431 function names and 1,809 globals.
  • A real IPv6-only listener matched ::1 and did not match 127.0.0.1.
  • Reloaded MCP exposed all 80 tools, token cancellation, exact selectors,
    progress/status, and typed errors. Final runtime cleanup left the Ghidra
    worker stopped, no kdbg session attached, and the VM running with its guest
    agent responsive.

Upgrade notes

  • Fully restart long-running winbox mcp processes after upgrading so they
    load the five new tools, extended signatures, typed errors, and API-6 client.
  • Rebuild/install the isolated worker with winbox kdbg ghidra install. This
    release moves the worker protocol from API 5 to API 6 and the analysis
    profile to winbox-pdb-enrichment-v3; protocol-family isolation prevents an
    old client from downgrading or stopping the new worker.
  • Existing immutable binaries remain reusable. New version/profile-keyed Ghidra
    projects are built without mutating older projects; use cache inventory and
    dry-run pruning to reclaim old entries deliberately.
  • Cache repair deletes only an exact selected project and never creates a
    quarantine. Applied pruning remains explicit and refuses to run while the
    worker owns projects.
  • CET preparation, network isolation, VM state, and debugger attach safety
    defaults are unchanged.

Complete v1.6.1 to v1.6.2 change set

  • Completed roadmap items 74, 75, 79, 80, 81, 82, 83, 84, 85, 86, and 87,
    plus the exact IPv6 listener residual from item 26.
  • Source changes cover the KDBG CLI and MCP server, debugger protocol/client/
    daemon, process walker, HMP listener probe, attach staging, shared typed-error
    model, PyGhidra client/cache/service/worker/container, bounded enrichment
    extractor, and detached prewarmer.
  • Documentation changes cover the README, roadmap, complete decompiler guide,
    release notes, lifecycle semantics, recovery behavior, cache ownership,
    public signatures, compatibility, and live evidence.
  • Test changes cover unit, real-process, daemon-socket, Docker policy, real
    PyGhidra, live-VM manifests, CLI, MCP, staging, cache, target-liveness,
    listener, typed-error, enrichment, cancellation, and job-lifecycle behavior.

Full diff: v1.6.1...v1.6.2