Skip to content

Releases: Albasha0x0/Corvus

v2.3.0

Choose a tag to compare

@github-actions github-actions released this 15 Oct 17:27

156 tools and 15 prompts, as in 2.2.0: everything new is a parameter, a view or a kind of an existing tool. No breaking
changes; engine output stored by 2.2.0 is computed again once (the cache layout changed).

  • Evidence as input. compare_assemblies, compare_native_images, compare_folders and diff_function take
    oldResult / newResult (a kept result, last:N or a bundle entry) and compare them without running anything;
    read_result format=verify takes one bundle entry and against=. What a side does not show is unknown, never
    removed, added or equal: a page of a longer result, a result that is not complete, or a facet either side lacks.
  • Completeness per facet. Function results name pseudocode, callers, callees, xrefs, strings and cfg as
    available or unavailable (with the reason) in the provenance and in coverage.facets; a record that says it stopped
    early (truncated, cut, incomplete, partial) has coverage partial.
  • Engine databases. docs/engine-databases.md states the contract (identity, reuse across sessions and command-line
    calls, invalidation, the user's own databases) with measured cold and warm times. load_assembly opens a Ghidra
    project (.gpr, program=) from a copy, leaving the original untouched. Import overrides (processor, language,
    compiler spec, seeds, disabled analyzers) apply before the first analysis in both engines.
  • Engine edits. declare_native_types inserts fields with the later ones moved down, resizes a struct and names its
    gaps; set_native_local inferStruct= (Ghidra) declares a struct from a pointer's loads and stores and types the local,
    storage= moves an argument to a register (IDA __usercall, Ghidra custom storage); define_native kind=flow
    (Ghidra) sets or clears a flow override and repairs the function. set_native_stack_var and set_native_operand
    take items= batches, and get_native_frame reads several functions in one request. Stack edits carry their offset
    from the return address, so a member made in IDA lands in the same slot in Ghidra. Ghidra refuses a calling
    convention its compiler spec lacks and names the ones it has.
  • Engine output cache. Renaming a local or a stack member makes only that function's stored answers stale.
  • Emulation. emulate_native candidates= runs many argument sets on one emulator in one request.
  • Debug info. load_pdb reads DWARF 2–5 for ELF and Mach-O (the image's sections, .build-id and .gnu_debuglink
    files, dSYM bundles, debuginfod on request) into names, types, prototypes with parameter names, source lines and
    inlined frames, pushed into IDA and Ghidra.
  • WebAssembly. A .wasm file loads as a native image: WAT byte-equal to wasm2wat, a lifted view, calls, xrefs,
    CFG and strings; summarize_file view=wasm validates in-process (verdicts equal to wasm-validate) and joins the
    imports to their JS glue; compare_native_images compares two builds' interfaces and function bodies.
  • Network. search_container kind=packet filters pcap / pcapng captures with Wireshark display filters, no TShark
    needed (HTTP/2, QUIC Initial server names, SMB2, NTLMSSP and Kerberos names too; other fields through TShark).
    kind=endpoint lists the endpoints an APK, .NET or Mach-O app's code names (Retrofit, OkHttp, Ktor, HttpClient,
    Refit, gRPC) and joins them with a capture. summarize_file view=protobuf rebuilds embedded descriptors as .proto.
  • Formats and managed code. get_il source=true (Portable PDB sequence points, local names, SourceLink),
    get_attributes typed arguments and [Flags] members, FieldRVA data in get_type_info, Il2Cpp metadata without the
    binary, obfuscator identification with evidence, view=sqlite paging and recovery, streamed reads of files over
    64 MiB, Win32 resource details, search_bytes nibble and bit masks, R8 / ProGuard mappings for DEX, Flutter string
    pools, an Objective-C header export and Android screen and bugreport views.

v2.2.0

Choose a tag to compare

@github-actions github-actions released this 15 Oct 08:17

156 tools and 15 prompts (2.1.0 had 13): investigate_feature and check_reimplementation are new prompts. No
breaking changes.

  • Model gateways. Every tool's input schema stays inside the subset the strictest model gateways accept (no $ref
    or combinators, one declared type, typed array items, depth ≤ 10); corvus status names any tool outside it.
  • Untrusted-content marker. Every result that may quote the analyzed file, errors included, carries
    untrustedContent: true and source: analysis_target in its provenance.
  • Long engine opens. An open that outlasts the call's deadline answers with its stage and seconds so far
    (details.stage, details.seconds); calling again picks up the same open.
  • Captures. summarize_file view=pcap reads pcap and pcapng as a stream: flows, DNS names and answers, TLS server
    names and ALPN (split ClientHellos joined) and HTTP/1.x requests, with every cap stated. search_container kind=endpoint also reads pcap captures and Fiddler .saz sessions.
  • Formats. New summarize_file views: sqlite (own B-tree reader: schema, row counts, sample rows), flutter
    (Dart AOT snapshot version, features and engine build id) and rust (cargo-auditable dependency lists in ELF, PE
    and Mach-O). get_pe_info reports ELF CET, BTI and PAC from the GNU property note, and reads 8-byte aligned notes
    correctly.
  • Linux and Android crash dumps. open_minidump, dump_stack, read_dump_memory and bucket_minidumps read ELF
    core files: threads, registers, the signal, modules matched by build id, and stacks unwound through .eh_frame.
  • Native. survey_features finds crypto and hash constants (AES, SHA-2, MD5, SHA-1, CRC-32, Blowfish, ChaCha,
    TEA, FNV, MurmurHash3) and more anti-analysis checks (hypervisor ids, analysis-tool names).
    search_instructions value=min..max searches a constant range. NativeAOT frozen strings name their MethodTable.
  • Engines. set_native_type with a no-return prototype stops the callers' flow at the call in IDA and Ghidra.
    ghidra_script compiles a script once per source and runs installed scripts by name= with arguments.
    get_engine_status lists Ghidra's analysis errors and warnings.
  • Evidence. read_result format=evidence bundles kept results or the latest calls with their provenance;
    format=verify runs them again and names what changed. The new prompts walk from a behaviour to the code behind it
    and check a reimplementation by emulation.
  • Android and Unity. get_android_device_info gains view=processes|features|services|settings|files.
    unity_overview reads Mono APKs, zipped Windows and Linux titles in place, and WebGL builds.
  • Release testing. test.ps1 -Full -Reuse reruns only the test families whose inputs changed since their last
    pass; patch releases gate on it, minor releases still run the whole exhaustive suite.

v2.1.0

Choose a tag to compare

@github-actions github-actions released this 15 Oct 07:15

156 tools (2.0.2 had 155): analyze_js is new, in the web toolset. No breaking changes.

  • Raw images. load_assembly format=raw arch= base= entry= maps headerless code (firmware, shellcode, ROM dumps).
    Our index decodes x86, x64, ARM, Thumb and ARM64; MIPS, PowerPC, RISC-V and 6502 go to IDA and Ghidra, which set
    the processor, bitness, base and entry before analysis. DOS .COM (x86-16) and MZ (dos-mz) images load too.
    Each layout gets its own id (name[x64@0x400000]), database and project.
  • JavaScript bundles. analyze_js reads bundlers and source maps (a minified line:column maps to the original
    source and name), module tables (webpack, esbuild, Browserify, Parcel, Metro, AMD, SystemJS, Rollup/Vite chunks),
    each module's requires and dependents, and strings and names with their original positions. It also identifies
    Hermes bytecode.
  • Electron. search_container kind=electron lists preload scripts, contextBridge keys, IPC channels, process
    and shell sinks and native add-ons (with their N-API registrations), each with file:line:column.
    compare_folders compares .asar archives entry by entry.
  • Captures. search_container kind=endpoint gives a capture's request templates, with id segments folded and
    query values hidden.
  • Archives and formats. tar (plain, gz, bz2, xz), 7z, RAR, single gzip/bzip2/xz files, xar (macOS .pkg) and
    cpio open as containers, with limits that stop archive bombs. New summarize_file views: wasm (imports,
    exports, toolchain, names) and firmware (formats found at their offsets inside an opaque image).
  • Apple. New summarize_file views: apple (an .ipa or .app: Info.plist, each Mach-O's role and signature
    verdict, entitlements, provisioning profile), plist (keyed archives decoded) and nib (classes, outlets and
    actions, with each action resolved to its implementation). verify_native_imports resolves Mach-O load commands
    as dyld does.
  • Ghidra. Ghidra archives (.gzf) load directly. A completion pass after the standard analysis finds more
    references while the image stays usable. reanalyze_native takes background=true and preset=.
    decompile_native view=pcode shows high p-code. Warm cross-reference queries are 2–30× faster.
  • Fixes. server_status no longer walks the engine cache on every call (about 950 ms down to 20 ms), and
    reference-pack downloads time out instead of stalling a search.

v2.0.2

Choose a tag to compare

@github-actions github-actions released this 14 Oct 11:05

Full Changelog: v2.0.1...v2.0.2

Full Changelog: v2.0.1...v2.0.2

v2.0.1

Choose a tag to compare

@github-actions github-actions released this 14 Oct 07:22
  • Security. Built with .NET SDK 10.0.402: the self-contained builds carry runtime 10.0.13 (the October 2026 .NET
    security release), and System.Security.Cryptography.Pkcs is 10.0.13 (CVE-2026-84008, CVE-2026-70162). Update
    framework-dependent installs (dotnet tool, dnx) to a 10.0.13 runtime.
  • nuget.org and the MCP Registry. The CorvusRE .NET tool package carries a README (with the registry's ownership
    line), so it is published on nuget.org (dotnet tool install -g CorvusRE, or dnx CorvusRE --yes) and listed in the
    MCP Registry as io.github.Albasha0x0/corvus.
  • Unsaved-session notice stays one line. Loading an image with many abandoned edit or patch sessions names the
    newest one with its replay command and counts the older ones, instead of one line per session.
  • Release assets ship under the corvus name only.
  • Docs. A shorter README; feature detail in features.md, server options in
    installation.md.

Full Changelog: v2.0.0...v2.0.1

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 13 Oct 22:59

155 tools (1.3.0 had 158): decompile_type, decompile_assembly_attributes and find_overrides are folded into other
tools. This is the breaking release. Every tool now follows one output contract: a structured record with an output
schema on every tool, a list envelope {items, offset, limit, total, totalExact, hasMore, nextOffset} on every list,
a token budget per part (text and structured content are each fitted to it), errors with a Next: line, and long or
cut results kept under an id that read_result pages. Edit tools preview by default (dryRun=true). Parameter names,
paging units and record shapes changed across every family; the checklist below covers what a 1.x caller must change.

Upgrading from 1.x

  • Edits preview by default. Every .NET and native edit tool, and migrate_native_names, defaults to dryRun=true
    and ends with "Nothing changed (dry run); pass dryRun=false to apply". Pass dryRun=false to apply.

  • Removed tools.

    Removed Use instead
    decompile_type decompile_member with the type
    decompile_assembly_attributes get_attributes format=csharp
    find_overrides find_references kind=overrides
  • Renamed parameters (no aliases):

    Tool 1.x 2.0
    every tool with a size limit maxChars maxTokens
    find_call_paths maxPaths limit (with offset)
    diff_function maxLines offset, limit, maxTokens
    inspect_instruction count limit
    ida_python maxOutput, file maxTokens, scriptPath
    ghidra_script timeout timeoutSeconds
    find_virtual_calls, emulate_native, reanalyze_native seconds timeoutSeconds
    search_decompiled cursor, seconds offset, timeoutSeconds
    search_instructions, reanalyze_native start, end from, to
    list_imports module library
    load_pdb force allowMismatch
    patch_bytes, patch_asm force allowUnsafe
    export_engine_database force overwrite
    get_resource, get_android_resource savePath outputPath
    export_edits, save_session path outputPath (parameter and record)
    undo_native_edit number editId
  • Booleans that now default to false, under a new name with the opposite sense. Omitting them behaves as before.

    Tool 1.x 2.0
    apply_edits stopOnError=true continueOnError=false
    compare_assemblies listAddedRemovedTypes=true typeCountsOnly=false
    decompile_java smaliFallback=true javaOnly=false
    disassemble function=true fromAddress=false
    dump_stack exceptionContext=true dumpTimeContext=false
    install_android_package replace=true keepInstalled=false
    read_dump_memory imageFallback=true dumpOnly=false
    trace_native_values followGlobals=true stopAtGlobals=false
    unpack_container load=true extractOnly=false
    comment_native dedupe=true repeatLine=false
    find_call_paths includeVirtual=true directOnly=false
    find_references includeVirtualCalls=true directOnly=false
    list_types includeNested=true topLevelOnly=false
    migrate_native_names comments=true namesOnly=false
    build tools useNames=true codeOnly=false

    set_native_type now defaults rename to false, and get_native_frame needs locals=true for decompiler locals.

  • Lists take arrays. Parameters that took a separated string are arrays: record_note / update_note tags,
    compare_folders exclude (globs), extract_strings types, simplify_methods passes, compare_assemblies
    changes, migrate_native_names sources, search_code_pattern images, update_to_new_build include,
    oldIl2Cpp and newIl2Cpp.

  • Paging counts rows. offset counts rows, nodes, blocks or bytes as each tool states, never characters; continue
    with the nextOffset the result gives. truncated is gone from every record: hasMore, nextOffset and
    totalExact say it. Most default page sizes are smaller (listed per family below); maxTokens raises a page.

  • Records changed. Row arrays are named items almost everywhere, and many fields were renamed or dropped. The
    full described schema of every tool is in docs/schemas. By default the text part is readable rows, not
    the record's JSON: read values from the structured content (CORVUS_RESULT_MODE=json restores a JSON copy in the
    text).

  • Edit ids. .NET edits are numbered <assembly>#<n> and native edits <image>#<n>. The ids are stable: undoing
    an edit no longer renumbers the others. undo_edit and diff_edits take the id in number; undo_native_edit
    takes editId (image#n, #n or n, or a comma list).

Changes in behaviour

.NET read

  • Consolidated tools. decompile_member decompiles a whole type, get_attributes format=csharp gives assembly
    attributes as C#, and find_references kind=overrides lists overrides.
  • List contract. Every .NET list tool returns the list envelope, pages by rows with [More: offset=N] /
    [End: …] footers ("N things (showing a-b)") and takes maxTokens. get_call_tree and compare_assemblies page
    by rows (was characters), get_call_tree loses maxNodes, and list_resources gains offset and limit.
  • New parameters. get_type_info section, offset, limit; get_assembly_info view (default summary;
    references, tables and heaps only in their views); get_attributes format, offset, limit, maxTokens;
    get_type_hierarchy and resolve_symbol offset, limit; search_il context; export_project overwrite.
  • Default limits. list_namespaces 2000 → 200, list_types 300 → 150, find_references 300 → 150,
    find_callees 2000 → 200, search_strings and search_constants 200 → 100, get_r2r_code maxInstructions
    5000 → 1500.
  • Records. TypeEntry.fullName → name, and kind is absent for a plain class; MemberEntry.ilInstructions →
    il. Member references are flat (label, token, assembly); find_references shows the member only where it
    changes and get_call_tree rows lose id/parent and show depth only where it changes; basis appears only when
    derived. New records for get_attributes, get_type_hierarchy, decompile_member, get_il, get_resource,
    get_r2r_code and find_r2r_method.
  • get_type_info. nestedTypes, fields, properties, events and methods become one items array with
    kind, plus counts. The default section=summary lists the first 8 of each kind. The top-level fullName moves to
    type.label; member rows drop name (they carry token, signature, kind, il; a constructor shows the type
    name).
  • export_project is annotated destructive. It decompiles a private snapshot outside the workspace lock, writes
    through a staging folder (whole or not at all), replaces a previous export with overwrite=true and returns a
    record.

.NET edits

  • Preview by default on rename_symbol, rename_namespace, stub_method, patch_method_csharp,
    patch_method_il, add_members_csharp, add_types_csharp, simplify_methods and apply_edits.
    patch_method_csharp, add_members_csharp, add_types_csharp, undo_edit and apply_edits are marked
    long-running and report progress.
  • Records. All 15 edit tools return records. A single edit gives {applied, dryRun, changes[{kind, target}], editIds}, and its text ends "Edit . Unsaved edits in …". list_edits pages rows (offset, limit,
    maxTokens) of {number, editId, tool, description}.
  • apply_edits. A rolled-back script, or one where every edit failed, is now an error with code failed and
    per-edit items in partial (was success); items carry code and basis.
  • revert_edits returns a resultId holding the discarded edits as a script.
  • simplify_methods. passes is an array of fold, cfg, inline (omit for all three); maxDepth and
    budget are plain integers (8 and 100000); the totals line follows the header.
  • compare_assemblies is read-only and in the readonly tool list: tokenMapPath and overwrite are removed and
    tokenMap=true returns a tokenMapResultId (write it with read_result outputPath=). Default page 200 → 100.
  • find_counterpart. symbol is optional, symbols[] takes up to 100, with offset/limit and a
    CounterpartList record.
  • patch_method_il operand syntax moved from the tool description to the edits guide.
  • diff_edits gives an exact totalChars on every page (the "+" after the total in [More: …] is gone); a diff
    stops at 200 members with a closing note line.

Native analysis

  • Default limits. list_imports 500 → 200, list_exports 500 → 300, list_functions 300 → 150,
    list_globals 300 → 200, search_native_strings 300 → 100, resolve_call_targets 100 → 75,
    search_pdb_symbols 200 → 150, find_xrefs 500 → 200, verify_native_imports 500 → 100,
    get_call_arguments 100 → 50. 17 native list tools take maxTokens as their last parameter.
  • native_call_tree returns NativeTreeNode rows with a per-page frontier of unexpanded nodes. offset counts
    nodes (was characters), a new limit (200) sets the page and maxNodes drops from 500 to 250. direction=both is
    caller/callee rows by call site (was two sections).
  • get_cfg. Record blocks → items with offset, total and a whole-function summary; truncated → cut;
    offset counts blocks, new limit (150).
  • read_bytes. offset is a byte offset from address; the record is a ByteDump with nextOffset and
    nextAddress, paged by whole 16-byte lines within the budget.
  • **`di...
Read more

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 19:57

158 tools (1.2.0 had 155). New are look-alike function search, p-code emulation and folder comparison. The release
also adds Electron, Objective-C / Swift and Go metadata, a faster and parallel code index (results are the same at any
thread count), faster IDA sessions, and reliability work across the server: calls that hold or wait on the workspace,
leftover calls, worker lifetime and logs.

Changes in behaviour

  • Busy server. Calls cancelled or past their deadline that keep running are capped (CORVUS_MAX_LEFTOVER_CALLS,
    default 2). At the cap a new call is refused as provider_unavailable with retryAfterMs. A call that times out
    waiting for the workspace lock names the calls holding it (details.blockedBy). server_status lists both and no
    longer takes the lock.
  • Errors. Save tools report only IO faults as io_error; unclassified faults are internal with a Next (also per
    item in apply_edits). decompile_java without JADX or Java is not retryable (details.reason not_configured).
    A Blazor folder whose boot manifest lists none of the present assemblies is not_found.
  • rename_symbol keeps a generic type's arity suffix and refuses a different arity.
  • set_native_local (Ghidra) checks that the rename took effect: a local without storage in use, or a name the
    decompiler kept, fails instead of succeeding.
  • Deterministic records. unity_overview, compare_native_images, update_to_new_build and
    find_similar_functions no longer carry elapsed time, so two identical calls give identical bytes.
  • Code index persist format 11. Older indexes are rebuilt on first use.
  • IDA cache keys are short (16 hex characters). Existing entries migrate. Input paths over 259 characters fail up
    front and give their length.

New tools

  • find_similar_functions ranks look-alike functions using MinHash sketches of instruction shapes, then rescores
    them exactly. It searches across all loaded images and also reports duplicate groups and near-duplicate clusters.
  • emulate_native runs a function or range in Ghidra's p-code emulator over the program's bytes, with a private
    stack, arguments by calling convention, stubs for calls, and instruction and time budgets.
  • compare_folders compares two folders or zip-family archives entry by entry by streaming SHA-256. It reports
    moves and case-only renames, and gives a next call per changed binary and inline diffs of small text files.
  • update_to_new_build now also takes two .NET assemblies: member notes follow their find_counterpart match and
    file notes move to the new build.

Formats and metadata

  • Electron: ASAR archives with integrity checks, unpacked entries and links; summarize_file reports Electron,
    Chromium and Node versions, fuses, the entry point and webPreferences values. Node-API add-on callbacks are named
    after their JavaScript names.
  • Unity WebGL data files and HAR / mitmproxy captures open as containers.
  • Mach-O: Objective-C and Swift metadata readers and a Swift demangler; list_cpp_classes and get_native_type list
    Objective-C classes, categories and protocols and Swift types.
  • Go: build info for PE, ELF and Mach-O; function sizes from each function's own tables; noreturn runtime functions.
  • ELF and Mach-O patch-site extension stubs (patch_asm beyond a site's size).

Native analysis

  • ARM: functions found in gaps from ARM32 and ARM64 prologues; .ARM.exidx / .ARM.extab exception data; ARM64X
    and ARM64EC images decoded in both instruction sets; ARM32 crypto instructions; JNIEnv / JavaVM calls named with their
    parameters; floating-point and System V call arguments (struct return, variadic vector count, 16-byte structs).
  • Index speed: discovery, sorting, noreturn propagation, RTTI, .pdata and virtual call resolution run on several
    threads. Allocation on a 130 MB NativeAOT image drops from 3.1 GB to 0.32 GB.
  • IDA: function and string lists are kept per session. Rename pushes are journaled and re-decompile only the
    affected functions. A first decompile on a large ELF drops from 7–10 s to 0.6 s. find_xrefs, resolve_address and
    search_bytes take lists of targets. An .i64 beside the input starts the cache as a copy, and the user's file is
    never written. A script loop is interrupted in place at its cancel or deadline.

Operations

  • Engine workers end within a second of a killed server on Linux and macOS.
  • The engine database cache is bounded (CORVUS_ANALYSIS_CACHE_MB / _DAYS).
  • Each call writes one info log line (CORVUS_LOG_FORMAT=json). --trace records argument values only with
    --trace-args, with secrets masked.
  • Per-RID publishes are ReadyToRun, so each cold CLI call is about 0.4 s faster.
  • verify_native_imports reports progress, never rebuilds stubs per call (300 s to 7 s cold on a large app) and no
    longer hits dnlib's LockException.
  • export_project decompiles outside the workspace lock.
  • New: a CorvusRE NuGet .NET tool package, MCP bundles (.mcpb) per desktop target, and an updated SECURITY.md.

v1.2.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 01:23

155 tools (1.1.0 had 101) and 13 prompts (9). The project takes its current name, Corvus. This
release adds a second decompiler engine (Ghidra), ELF and Mach-O images, our own ARM64 and ARM32 / Thumb-2 analysis,
NativeAOT and mobile Il2Cpp builds, Android packages and devices, deeper crash-dump decoding, and a round of reliability
work across the server and its engine workers.

Renamed to Corvus

  • Program and registration. The program is corvus (corvus.exe), installed under Corvus, and registers with
    clients under the MCP key corvus. Release archives are corvus-<rid> from the Albasha0x0/Corvus repository.
  • Names. Environment variables are CORVUS_* and resources use the corvus:// scheme.
  • Earlier installs. On first start, data, client entries and skill folders of an earlier install move to the new
    names; files saved by earlier versions (sessions, edit scripts, patch sets, notes, engine databases) are still read.

Changes in behaviour

  • Exports never overwrite by default. Files written by export and save tools are written atomically and refuse to
    replace an existing file unless overwrite=true; links and device names are refused as targets. save_assembly
    recognizes the original through links and hard links, refuses an original that changed on disk since it loaded, and
    save_native verifies the written file before renaming it into place.
  • uninstall keeps user data. Annotations, caches and symbols stay; --purge-data removes them.
  • Call deadline. A tool not marked long-running ends with a timeout error after twice --timeout; cancelled calls
    stop waiting for the workspace lock. New error codes cancelled and changed_on_disk (docs/errors.md).
  • Closed argument values are advertised as enums and checked before the tool runs, with aliases and a
    did-you-mean suggestion; limit < 1 is invalid_argument on every paged native tool.
  • Native names. A name on several addresses is an ambiguous error listing them; hex-shaped names (Bach, ...h)
    resolve as names before MASM numbers; a name on a jump thunk and on its body resolves to the body.
  • Incomplete results say so. Regex searches that time out report what was not evaluated; a cut-short read_bytes
    says so; read_bytes shows bytes with no file data (.bss, virtual size past raw size) as ?? with a gap list.
  • Member labels carry generic parameters (Method<T>(string)), so generic and non-generic overloads differ in
    diffs and replays; older edit scripts resolve their bare labels as before.
  • Native patches pad with the architecture's NOP (whole NOPs on ARM64) and are refused where none is defined.
  • IDA before 9.0 is refused with the reason; the reported idalib version shows in server_status.
  • Inputs: FIFOs, sockets, devices and directories are refused as input files.

Second engine: Ghidra

  • engine=ghidra everywhere an engine is used: decompile_native, the code tools (list_functions, disassemble,
    get_cfg, find_xrefs, native_call_tree, resolve_call_targets, trace_native_values, inspect_instruction),
    the type, frame and local edit tools, crossCheck and find_xrefs Type::member. A session per engine and image;
    auto takes a complete IDA analysis, then Ghidra's, else ours. Ghidra 12.0 or newer through CORVUS_GHIDRA_DIR and a
    JDK; the worker is built on first use.
  • Saved projects per file SHA-256 and profile key, warm reopen, rebase, damaged-project rebuild, an analysis budget
    with a partial save that reanalyze_native completes, and a background function pass after the open.
  • Large functions decompile: 200 MB decompiler payload, one retry with four times the time on a fresh decompiler,
    timeoutSeconds per call.
  • Ghidra's names (loader and analysis names, function identification included) form a name layer below the others;
    FUN_ / LAB_ / DAT_ and IDA default names resolve as addresses.
  • ghidra_script runs a Java GhidraScript in the worker in one transaction, rolled back on failure (opt-in,
    --ghidra-scripting). export_engine_database writes a .gzf archive, or Ghidra's own types as .h / .gdt.

IDA and engine depth

  • New edit tools: define_native (code, functions, data, undefined bytes), set_native_operand (number base, char,
    offset, stack variable, enum member, struct offset), reanalyze_native; enum, struct and union member upsert,
    type delete and rename (followed into the other edits), stack member delete, clear=true to restore the engine's
    own local. All kept per file hash, replayed on a new database, exported and carried to new builds.
  • Comments: kinds eol, pre, plate and pseudocode comments placed on the statement, with append and dedupe;
    rename_native and comment_native take batches with dryRun, stopOnError and per-item results;
    showDecompile=after|diff on the type and name edits.
  • Views: list_globals, search_instructions, convert_number, get_engine_status, search_decompiled (regex
    over every function's pseudocode, resumable by cursor), decompile_native functions=[...] and callersOf=,
    list_functions view=candidates, find_xrefs direction=from|both and kind=, list_native_types filters,
    related=true and members, list_cpp_classes engine=ida|ghidra, typed reads (get_native_type read=true,
    read_bytes type=), export_engine_database (.i64 copy), make_code_pattern in IDA / x64dbg / mask formats.
  • Worker control: cancel and deadlines inside the IDA and Ghidra workers (partial results with a cursor; the worker
    is killed only past a grace period), CORVUS_ENGINE_REQUEST_TIMEOUT / CORVUS_ENGINE_OPEN_TIMEOUT,
    CORVUS_ENGINE_ANALYSIS=none for huge or hostile inputs, a read-only snapshot when another server holds the
    database, batch mode so no dialog waits, engine sessions and open-stage timings in server_status.

Own engine: ELF, Mach-O, ARM64 and ARM32

  • ELF and Mach-O images load beside PE (universal files by slice) through every native tool: relocations, PLT and
    GOT, symbol versions, chained fixups, exports trie, function starts, compact unwind, code signature and encryption.
    IDA and Ghidra open them too. Itanium C++ demangler, Itanium RTTI (single, multiple and virtual bases) for classes,
    type push and virtual calls, Itanium exception tables in get_exception_info, System V x64 calling convention.
  • ARM64 decoder, function discovery, jump tables, call arguments (integer and floating-point), value tracing and
    call targets; inspect_instruction on the built-in decoder; ARM64X / ARM64EC images from their CHPE metadata.
  • ARM32 / Thumb-2: own A32 / T32 decoder (VFP and NEON included) with per-function state, cross-references through
    literal pools and MOVW / MOVT, TBB / TBH and PC-relative jump tables, IT blocks, AAPCS call arguments and value
    traces, fixed-address executables.
  • Discovery: Go function tables (Go 1.2 to 1.24, ELF / PE / Mach-O) as a function and name source; static and
    fixed-address ELF (a static x86-64 Linux executable: 194 to 3,112 functions; its i386 build: 19 to 3,173); x64
    absolute switch tables; jump thunks named j_<target>. Image-scope resolve_call_targets on a 3.8 MB library:
    1,474 s to 12 s (ARM32), over 900 s to 7 s (ARM64).
  • Patching ELF and Mach-O: patch_bytes, patch_asm, undo and save_native (universal files keep their other
    slices); bytes the loader rewrites are refused unless forced, encrypted bytes refused.
  • Packers and protectors reported with evidence in summarize_file and get_pe_info (detection only).

Native analysis

  • inspect_instruction, get_native_type (PDB, RTTI, Il2Cpp and engine types; field paths at an offset),
    trace_native_values (interprocedural value slices across functions and loaded images, struct fields, switch
    case selection) and resolve_call_targets (targets with basis and confidence).
  • analyze_native_function (a function dossier in bounded sections, up to 16 at once, component=true),
    trace_native_feature (from a text to the ranked functions behind it), native goals in find_call_paths,
    diff_function (aligned instruction and pseudocode diff of a matched pair), get_cfg switch cases,
    native_call_tree direction=both, summarize_file triage for native images.

NativeAOT

  • get_nativeaot_info and a nativeaot name layer from the image's own metadata: method bodies, MethodTables,
    vtable slots, frozen strings, statics and interface dispatch cells, ranked below PDB names, pushed to IDA and Ghidra
    and exported. .NET 7 to 11 layouts, PE, ELF and Mach-O, 64- and 32-bit.

Il2Cpp and Unity

  • Mobile and desktop layouts: Android, iOS, macOS and Linux games, read from .apk / .xapk / .apks / .aab /
    .ipa; ELF and Mach-O game binaries; metadata up to v39; builds that fill the code registration at run time.
  • 32-bit games get headers and prototypes pushed to IDA and Ghidra; Il2Cpp games and minidumps are kept in sessions;
    unity_overview reads packages and iOS layouts.

Android

  • Packages: manifest and resources (binary XML, resources.arsc, app bundle protobuf), APK signature verification
    (v1 to v4 with rotation and several signers, content digests recomputed), .NET for Android assembly stores.
  • Code: DEX reader and Dalvik disassembler (list_dex_classes, get_dex_class, disassemble_dex, search_dex,
    find_dex_references), decompile_java through JADX, map_java_dotnet (also Unity Mono C# to Java),
    list_jni_bindings, export_project to a Gradle project skeleton.
  • Devices through adb: read-only by default; install and uninstall behind --allow-device-changes.

Crash dumps

  • .NET decoding: managed exception, mixed frames, dump_heap and dump_object; DAC lookup with signature check and
    opt-in...
Read more

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 10 Oct 14:08

101 tools (1.0.1 had 54). This release adds the native PE track (analysis, IDA engine, PDB, patching, crash dumps,
build migration) and a batch of usability and analysis-depth work on top of it.

Changes in behaviour

  • Unknown argument names are errors. A parameter a tool does not declare is invalid_argument with the closest
    declared names ("unknown parameter 'max_chars'. Did you mean 'maxChars'?"; details.suggestions), instead of being
    ignored while the tool ran with its defaults. Clients that sent extra arguments must drop them.
  • load_pdb is marked destructive: clear=true removes imported PDB names and their saved copy.
  • With engine=auto (the default), list_functions, disassemble, get_cfg, find_xrefs and native_call_tree
    answer from IDA for an image once IDA has finished analyzing it in the session; pass engine=ours for the built-in
    index only.

New in this batch

  • Persistent native code index. Each image's code index is saved per user, keyed by the file's SHA-256 and the build
    options; reopening the same bytes loads it (msedge.dll, 334 MB: 2.6 s instead of 36 s; GameAssembly.dll, 206 MB:
    1.8 s instead of 54 s). Changed, damaged or older-format entries are rebuilt; bounded by size (8 GB) and age (30 days),
    least recently used first. --index-cache <dir|off>, --index-cache-mb, --index-cache-days; shown in server_status.
  • Imported names survive restarts. Names from load_pdb and apply_il2cpp_names are saved beside user renames and
    reapplied when the same file loads again, also with the PDB moved or deleted (a real game: 434,680 names restored in 0.8 s).
    list_native_edits lists each layer and whether it was restored; clear=true removes a layer.
  • Engine preference engine=auto|ours|ida (server default --engine / CORVUS_ENGINE): see above; auto never starts
    IDA and costs about 0.1 µs per call. With IDA, our names still win and RTTI virtual-call edges IDA lacks are added.
    Every result names its engine.
  • PDB types in IDA. decompile_native loads the PDB's structs, enums, typedefs and prototypes into the IDA database
    once per PDB, through IDA's PDB loader or the server's own PDB type reader, so pseudocode uses real struct and member
    names (return source->flags; instead of return *(unsigned int *)(a1 + 712);).
  • Virtual calls through RTTI. obj->vfunc() sites are resolved from MSVC RTTI class hierarchies into
    virtual_exact / virtual_possible call-graph edges (+11,041 edges on Qt6Widgets.dll, +15,026 on Acrobat.dll).
    find_virtual_calls lists the sites; crossCheck=true compares with IDA (98-100% agreement on Qt6Widgets and
    steamclient). native_call_tree calls=direct|virtual.
  • Built-in Il2Cpp metadata reader. load_assembly on an Il2Cpp game folder or global-metadata.dat reads metadata
    versions 24-31 through LibCpp2IL, also from a memory dump of GameAssembly.dll; no external dumper. On a real game every method,
    RVA, vtable slot, field and field offset matches Il2CppDumper's output. Unreadable metadata is an error with a reason;
    unreadable items are listed by reason.
  • unity_overview. One call on a Unity title: engine version per source, Mono or Il2Cpp with evidence and metadata
    state (readable, encrypted, header tampered), anti-cheat / obfuscator / packer / middleware markers (optional Detect
    It Easy), and the next tool calls. Under 0.2 s on the titles tested.
  • inspect_process. Read-only view of a running local process (Windows): modules, memory regions, threads and
    stacks, named through PE, PDB, Il2Cpp and user names. Opens only query and read handles, writes and suspends nothing,
    closes every handle before returning (docs/live-inspection.md).
  • Patch-site extension. patch_asm / patch_bytes extend=true turn a site that is too small into a jump to a
    relocation stub that runs the new code (and the displaced instructions, stubMode=before|after) and returns after the
    site. placement=auto|cave|section: a code cave when one fits, else a new executable section (undo removes it byte
    for byte). Exports describe grown files (JSON v2, IDAPython, IPS / IPS32; .dif refuses them with grown_file).
  • update_to_new_build. One call carries names, comments, PDB / Il2Cpp layers, patches (stubs re-created), code
    patterns with drift and the Il2Cpp method mapping to a new build, with one report: what carried, what did not and why.

Also since 1.0.1

  • Native PE images: own PE parser; x86 / x64 code index (functions, xrefs, CFGs, strings); MSVC demangler, RTTI and
    exception metadata; PDB reader with opt-in symbol download; Win32 resources; ReadyToRun code; P/Invoke verification
    with verdicts; late-bound imports and call-site arguments; navigation across loaded images and between managed and
    native code; ARM / ARM64 through IDA.
  • IDA (idalib) engine: decompile_native, analysis cached per file hash, names, patches and types pushed in,
    library-function names, optional background analysis (--ida-prewarm).
  • Native editing: renames and comments kept per file hash, patch_bytes / patch_asm (full MASM assembler,
    relocation-correct under ASLR), undo, save_native, export_native_patches, migrate_native_patches.
  • Builds and dumps: compare_native_images, address and name migration, rebuild-stable code patterns; minidumps
    (open_minidump, dump_stack, read_dump_memory).
  • Il2Cpp: string literals, metadata <-> native navigation both ways, complete struct layouts and prototypes, C++
    bindings in Il2Cpp style with generic templates.
  • Protocol: typed errors with a JSON copy, structured output for list / search / info tools, response-size guard with
    read_result, server_status with a tool-catalog digest, one audited annotations table.
  • .NET: normalized IL hash, tiered unique-only member matching, many simplify_methods readability passes.

v1.0.1

Choose a tag to compare

@github-actions github-actions released this 08 Oct 04:42

Full Changelog: v1.0.0...v1.0.1