Repository navigation
Releases: Albasha0x0/Corvus
Release list
v2.3.0
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_foldersanddiff_functiontake
oldResult/newResult(a kept result,last:Nor a bundle entry) and compare them without running anything;
read_result format=verifytakes one bundle entry andagainst=. What a side does not show isunknown, 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,stringsandcfgas
available or unavailable (with the reason) in the provenance and incoverage.facets; a record that says it stopped
early (truncated,cut,incomplete,partial) has coveragepartial. - Engine databases.
docs/engine-databases.mdstates the contract (identity, reuse across sessions and command-line
calls, invalidation, the user's own databases) with measured cold and warm times.load_assemblyopens 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_typesinserts 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_varandset_native_operand
takeitems=batches, andget_native_framereads 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_pdbreads DWARF 2–5 for ELF and Mach-O (the image's sections,.build-idand.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
.wasmfile loads as a native image: WAT byte-equal towasm2wat, a lifted view, calls, xrefs,
CFG and strings;summarize_file view=wasmvalidates in-process (verdicts equal towasm-validate) and joins the
imports to their JS glue;compare_native_imagescompares two builds' interfaces and function bodies. - Network.
search_container kind=packetfilters 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=endpointlists 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=protobufrebuilds embedded descriptors as.proto. - Formats and managed code.
get_il source=true(Portable PDB sequence points, local names, SourceLink),
get_attributestyped arguments and[Flags]members, FieldRVA data inget_type_info, Il2Cpp metadata without the
binary, obfuscator identification with evidence,view=sqlitepaging and recovery, streamed reads of files over
64 MiB, Win32 resource details,search_bytesnibble 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
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 statusnames any tool outside it. - Untrusted-content marker. Every result that may quote the analyzed file, errors included, carries
untrustedContent: trueandsource: analysis_targetin 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=pcapreads 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=endpointalso reads pcap captures and Fiddler.sazsessions. - Formats. New
summarize_fileviews:sqlite(own B-tree reader: schema, row counts, sample rows),flutter
(Dart AOT snapshot version, features and engine build id) andrust(cargo-auditable dependency lists in ELF, PE
and Mach-O).get_pe_inforeports 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_memoryandbucket_minidumpsread ELF
core files: threads, registers, the signal, modules matched by build id, and stacks unwound through.eh_frame. - Native.
survey_featuresfinds 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..maxsearches a constant range. NativeAOT frozen strings name their MethodTable. - Engines.
set_native_typewith a no-return prototype stops the callers' flow at the call in IDA and Ghidra.
ghidra_scriptcompiles a script once per source and runs installed scripts byname=with arguments.
get_engine_statuslists Ghidra's analysis errors and warnings. - Evidence.
read_result format=evidencebundles kept results or the latest calls with their provenance;
format=verifyruns 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_infogainsview=processes|features|services|settings|files.
unity_overviewreads Mono APKs, zipped Windows and Linux titles in place, and WebGL builds. - Release testing.
test.ps1 -Full -Reusereruns 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
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_jsreads bundlers and source maps (a minifiedline:columnmaps 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=electronlists preload scripts, contextBridge keys, IPC channels, process
and shell sinks and native add-ons (with their N-API registrations), each withfile:line:column.
compare_folderscompares.asararchives entry by entry. - Captures.
search_container kind=endpointgives 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. Newsummarize_fileviews:wasm(imports,
exports, toolchain, names) andfirmware(formats found at their offsets inside an opaque image). - Apple. New
summarize_fileviews:apple(an.ipaor.app: Info.plist, each Mach-O's role and signature
verdict, entitlements, provisioning profile),plist(keyed archives decoded) andnib(classes, outlets and
actions, with each action resolved to its implementation).verify_native_importsresolves 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_nativetakesbackground=trueandpreset=.
decompile_native view=pcodeshows high p-code. Warm cross-reference queries are 2–30× faster. - Fixes.
server_statusno 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
Full Changelog: v2.0.1...v2.0.2
Full Changelog: v2.0.1...v2.0.2
v2.0.1
- Security. Built with .NET SDK 10.0.402: the self-contained builds carry runtime 10.0.13 (the October 2026 .NET
security release), andSystem.Security.Cryptography.Pkcsis 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, ordnx CorvusRE --yes) and listed in the
MCP Registry asio.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
corvusname 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
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 todryRun=true
and ends with "Nothing changed (dry run); pass dryRun=false to apply". PassdryRun=falseto apply. -
Removed tools.
Removed Use instead decompile_typedecompile_memberwith the typedecompile_assembly_attributesget_attributes format=csharpfind_overridesfind_references kind=overrides -
Renamed parameters (no aliases):
Tool 1.x 2.0 every tool with a size limit maxCharsmaxTokensfind_call_pathsmaxPathslimit(withoffset)diff_functionmaxLinesoffset,limit,maxTokensinspect_instructioncountlimitida_pythonmaxOutput,filemaxTokens,scriptPathghidra_scripttimeouttimeoutSecondsfind_virtual_calls,emulate_native,reanalyze_nativesecondstimeoutSecondssearch_decompiledcursor,secondsoffset,timeoutSecondssearch_instructions,reanalyze_nativestart,endfrom,tolist_importsmodulelibraryload_pdbforceallowMismatchpatch_bytes,patch_asmforceallowUnsafeexport_engine_databaseforceoverwriteget_resource,get_android_resourcesavePathoutputPathexport_edits,save_sessionpathoutputPath(parameter and record)undo_native_editnumbereditId -
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_editsstopOnError=truecontinueOnError=falsecompare_assemblieslistAddedRemovedTypes=truetypeCountsOnly=falsedecompile_javasmaliFallback=truejavaOnly=falsedisassemblefunction=truefromAddress=falsedump_stackexceptionContext=truedumpTimeContext=falseinstall_android_packagereplace=truekeepInstalled=falseread_dump_memoryimageFallback=truedumpOnly=falsetrace_native_valuesfollowGlobals=truestopAtGlobals=falseunpack_containerload=trueextractOnly=falsecomment_nativededupe=truerepeatLine=falsefind_call_pathsincludeVirtual=truedirectOnly=falsefind_referencesincludeVirtualCalls=truedirectOnly=falselist_typesincludeNested=truetopLevelOnly=falsemigrate_native_namescomments=truenamesOnly=falsebuild tools useNames=truecodeOnly=falseset_native_typenow defaultsrenameto false, andget_native_frameneedslocals=truefor decompiler locals. -
Lists take arrays. Parameters that took a separated string are arrays:
record_note/update_notetags,
compare_foldersexclude(globs),extract_stringstypes,simplify_methodspasses,compare_assemblies
changes,migrate_native_namessources,search_code_patternimages,update_to_new_buildinclude,
oldIl2CppandnewIl2Cpp. -
Paging counts rows.
offsetcounts rows, nodes, blocks or bytes as each tool states, never characters; continue
with thenextOffsetthe result gives.truncatedis gone from every record:hasMore,nextOffsetand
totalExactsay it. Most default page sizes are smaller (listed per family below);maxTokensraises a page. -
Records changed. Row arrays are named
itemsalmost 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=jsonrestores 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_editanddiff_editstake the id innumber;undo_native_edit
takeseditId(image#n,#norn, or a comma list).
Changes in behaviour
.NET read
- Consolidated tools.
decompile_memberdecompiles a whole type,get_attributes format=csharpgives assembly
attributes as C#, andfind_references kind=overrideslists 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 takesmaxTokens.get_call_treeandcompare_assembliespage
by rows (was characters),get_call_treelosesmaxNodes, andlist_resourcesgainsoffsetandlimit. - New parameters.
get_type_infosection,offset,limit;get_assembly_infoview(defaultsummary;
references, tables and heaps only in their views);get_attributesformat,offset,limit,maxTokens;
get_type_hierarchyandresolve_symboloffset,limit;search_ilcontext;export_projectoverwrite. - Default limits.
list_namespaces2000 → 200,list_types300 → 150,find_references300 → 150,
find_callees2000 → 200,search_stringsandsearch_constants200 → 100,get_r2r_codemaxInstructions
5000 → 1500. - Records.
TypeEntry.fullName→name, andkindis absent for a plain class;MemberEntry.ilInstructions→
il. Member references are flat (label,token,assembly);find_referencesshows the member only where it
changes andget_call_treerows loseid/parentand showdepthonly where it changes;basisappears only when
derived. New records forget_attributes,get_type_hierarchy,decompile_member,get_il,get_resource,
get_r2r_codeandfind_r2r_method. get_type_info.nestedTypes,fields,properties,eventsandmethodsbecome oneitemsarray with
kind, pluscounts. The defaultsection=summarylists the first 8 of each kind. The top-levelfullNamemoves to
type.label; member rows dropname(they carrytoken,signature,kind,il; a constructor shows the type
name).export_projectis 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 withoverwrite=trueand 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_methodsandapply_edits.
patch_method_csharp,add_members_csharp,add_types_csharp,undo_editandapply_editsare 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_editspages 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 codefailedand
per-edit items inpartial(was success); items carrycodeandbasis.revert_editsreturns aresultIdholding the discarded edits as a script.simplify_methods.passesis an array offold,cfg,inline(omit for all three);maxDepthand
budgetare plain integers (8 and 100000); the totals line follows the header.compare_assembliesis read-only and in thereadonlytool list:tokenMapPathandoverwriteare removed and
tokenMap=truereturns atokenMapResultId(write it withread_result outputPath=). Default page 200 → 100.find_counterpart.symbolis optional,symbols[]takes up to 100, withoffset/limitand a
CounterpartListrecord.patch_method_iloperand syntax moved from the tool description to the edits guide.diff_editsgives an exacttotalCharson 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_imports500 → 200,list_exports500 → 300,list_functions300 → 150,
list_globals300 → 200,search_native_strings300 → 100,resolve_call_targets100 → 75,
search_pdb_symbols200 → 150,find_xrefs500 → 200,verify_native_imports500 → 100,
get_call_arguments100 → 50. 17 native list tools takemaxTokensas their last parameter. native_call_treereturnsNativeTreeNoderows with a per-pagefrontierof unexpanded nodes.offsetcounts
nodes (was characters), a newlimit(200) sets the page andmaxNodesdrops from 500 to 250.direction=bothis
caller/callee rows by call site (was two sections).get_cfg. Recordblocks→itemswithoffset,totaland a whole-functionsummary;truncated→cut;
offsetcounts blocks, newlimit(150).read_bytes.offsetis a byte offset fromaddress; the record is aByteDumpwithnextOffsetand
nextAddress, paged by whole 16-byte lines within the budget.- **`di...
v1.3.0
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 asprovider_unavailablewithretryAfterMs. A call that times out
waiting for the workspace lock names the calls holding it (details.blockedBy).server_statuslists both and no
longer takes the lock. - Errors. Save tools report only IO faults as
io_error; unclassified faults areinternalwith a Next (also per
item inapply_edits).decompile_javawithout JADX or Java is not retryable (details.reasonnot_configured).
A Blazor folder whose boot manifest lists none of the present assemblies isnot_found. rename_symbolkeeps 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_buildand
find_similar_functionsno 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_functionsranks 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_nativeruns 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_folderscompares 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_buildnow also takes two .NET assemblies: member notes follow theirfind_counterpartmatch and
file notes move to the new build.
Formats and metadata
- Electron: ASAR archives with integrity checks, unpacked entries and links;
summarize_filereports Electron,
Chromium and Node versions, fuses, the entry point andwebPreferencesvalues. 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_classesandget_native_typelist
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_asmbeyond a site's size).
Native analysis
- ARM: functions found in gaps from ARM32 and ARM64 prologues;
.ARM.exidx/.ARM.extabexception 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,
.pdataand 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_addressand
search_bytestake lists of targets. An.i64beside 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).--tracerecords 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_importsreports progress, never rebuilds stubs per call (300 s to 7 s cold on a large app) and no
longer hits dnlib'sLockException.export_projectdecompiles 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
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 underCorvus, and registers with
clients under the MCP keycorvus. Release archives arecorvus-<rid>from theAlbasha0x0/Corvusrepository. - Names. Environment variables are
CORVUS_*and resources use thecorvus://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 unlessoverwrite=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_nativeverifies the written file before renaming it into place. uninstallkeeps user data. Annotations, caches and symbols stay;--purge-dataremoves 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 codescancelledandchanged_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 < 1isinvalid_argumenton 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_bytesshows 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=ghidraeverywhere 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,crossCheckandfind_xrefs Type::member. A session per engine and image;
autotakes a complete IDA analysis, then Ghidra's, else ours. Ghidra 12.0 or newer throughCORVUS_GHIDRA_DIRand 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 thatreanalyze_nativecompletes, 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,
timeoutSecondsper 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_scriptruns a Java GhidraScript in the worker in one transaction, rolled back on failure (opt-in,
--ghidra-scripting).export_engine_databasewrites a.gzfarchive, 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=trueto 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,plateand pseudocode comments placed on the statement, with append and dedupe;
rename_nativeandcomment_nativetake batches withdryRun,stopOnErrorand per-item results;
showDecompile=after|diffon 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=[...]andcallersOf=,
list_functions view=candidates,find_xrefs direction=from|bothandkind=,list_native_typesfilters,
related=trueand members,list_cpp_classes engine=ida|ghidra, typed reads (get_native_type read=true,
read_bytes type=),export_engine_database(.i64copy),make_code_patternin 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=nonefor 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 inserver_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 inget_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_instructionon 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 namedj_<target>. Image-scoperesolve_call_targetson 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 andsave_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_fileandget_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) andresolve_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 infind_call_paths,
diff_function(aligned instruction and pseudocode diff of a matched pair),get_cfgswitch cases,
native_call_tree direction=both,summarize_filetriage for native images.
NativeAOT
get_nativeaot_infoand 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_overviewreads 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_javathrough JADX,map_java_dotnet(also Unity Mono C# to Java),
list_jni_bindings,export_projectto 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_heapanddump_object; DAC lookup with signature check and
opt-in...
v1.1.0
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_argumentwith 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_pdbis marked destructive:clear=trueremoves imported PDB names and their saved copy.- With
engine=auto(the default),list_functions,disassemble,get_cfg,find_xrefsandnative_call_tree
answer from IDA for an image once IDA has finished analyzing it in the session; passengine=oursfor 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 inserver_status. - Imported names survive restarts. Names from
load_pdbandapply_il2cpp_namesare 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_editslists each layer and whether it was restored;clear=trueremoves a layer. - Engine preference
engine=auto|ours|ida(server default--engine/CORVUS_ENGINE): see above;autonever 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_nativeloads 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 ofreturn *(unsigned int *)(a1 + 712);). - Virtual calls through RTTI.
obj->vfunc()sites are resolved from MSVC RTTI class hierarchies into
virtual_exact/virtual_possiblecall-graph edges (+11,041 edges on Qt6Widgets.dll, +15,026 on Acrobat.dll).
find_virtual_callslists the sites;crossCheck=truecompares with IDA (98-100% agreement on Qt6Widgets and
steamclient).native_call_tree calls=direct|virtual. - Built-in Il2Cpp metadata reader.
load_assemblyon an Il2Cpp game folder orglobal-metadata.datreads 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_bytesextend=trueturn 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;.difrefuses them withgrown_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_statuswith a tool-catalog digest, one audited annotations table. - .NET: normalized IL hash, tiered unique-only member matching, many
simplify_methodsreadability passes.