These 83 commits are when the Protocol Buffers files have changed:
| Commit: | 8608d97 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
Decompiler: Fix re-rendering of decompilation caches reloaded from angrDb. (#6669) * Decompiler: Fix re-rendering of decompilation caches reloaded from angrdb. Re-rendering a deserialized codegen (as angr-management does on display/edit) dropped variable declarations and string constants and rendered slightly different C, because several pieces of state were not restored: - VariableManagerInternal never serialized variable_to_types / variables_with_ manual_types, so get_variable_type() returned None and all locals rendered as int. - parse_codegen did not attach the project, and left display options that serialize as None (e.g. max_str_len) unset. Attach project and initialize display options from the codegen constructor defaults. - CConstant string references lost MemoryData.content (not serialized); re-read it from the loader at parse time so strings render as strings, not raw addresses. - regenerate_text() now refreshes CFunction.unified_local_vars from the (restored or updated) variable manager so declarations reflect current types. - CBinaryOp._cstyle_null_cmp is rebuilt from the codegen flag in set_codegen, restoring !x vs x == 0. - Compound-assignment folding (x += 1) compared unified variables by identity; use == so it works across deserialized variables that are equal but not the same object. Adds an end-to-end test (1after909::doit) asserting a reloaded cache re-renders byte-identically. * Lint code.
The documentation is generated from this commit.
| Commit: | 02c374b | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
DecompilationCache: Serialization support. (#6624) Also, - Refactored variable_kb into kb.dec_variables. - Spill decompilation cache into RuntimeDb. - Save decompilation cache into angrDb. Decompilation results can be preserved across runs. - No longer check in _pb2.py files; they are generated during build.
| Commit: | ba6d3f2 | |
|---|---|---|
| Author: | Fish Wang | |
decompiler: Replace the variable_kb hack with kb.dec_variables. Decompilation-discovered variables used to live in a throwaway KnowledgeBase (variable_kb) threaded through Decompiler -> Clinic -> codegen -> dephication -> optimization passes -> deobfuscators, purely to keep them from clobbering the disassembly-level kb.variables. The only attribute ever read off any variable_kb object was .variables. Introduce a dedicated DecompilationVariableManager plugin registered as kb.dec_variables (a VariableManager subclass, so get_knowledge(VariableManager) stays unambiguous, with a working copy()). Variable recovery + Typehoon now write into kb.dec_variables via a thin bridge KB that aliases "variables" to it; every former variable_kb.variables read becomes kb.dec_variables. The variable_kb parameter/attribute is removed from Decompiler, Clinic, both code generators, the dephication chain, and the optimization-pass base. The two disassembly-time deobfuscators keep reading kb.variables. Serialization: the DecompilationCache no longer carries a variable_kb slot; the cross-KB identity check in cache validation is dropped (the store is now shared on kb). parse_codegen reattaches the codegen's variable_manager from kb.dec_variables, points the codegen _variables_in_use at the restored CFunction map, restores indent_delta, and arch-binds pooled SimTypes so a deserialized codegen can be re-rendered. The full-reuse fast path skips regenerate_text() for a freshly deserialized codegen (_handlers is None) whose stored text is already authoritative. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LNnEYkL92gwAk7gQbuW2Tq
| Commit: | e27485b | |
|---|---|---|
| Author: | Fish Wang | |
codegen: Move CFunctionCall display flags to out-of-line node_config. show_demangled_name / show_disambiguated_name default to True and were stored on every CFunctionCall body. They move to a new Codegen.node_config (NodeConfigMsg of per-node NodeConfigEntry, each with a CFunctionCallConfigEntry in a oneof), and a node is recorded there only when it deviates from the True/True default; parse restores the default for any call not listed. On 1after909:doit all 115 calls use the default, so node_config is empty and the two bools vanish from every body (codegen 51.4 -> 50.9 KiB). (node_id lives on NodeConfigEntry rather than NodeConfigMsg so each entry addresses its own node.) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sb2yG3v6dEXvY24r1TWzun
| Commit: | cc83ee6 | |
|---|---|---|
| Author: | Fish Wang | |
ail: Factor the modal edge-data value out of AIL graphs. Each AilGraph now stores the most common non-ins_addr edge-data value once in default_edge_data; edges matching it set has_default_data and keep only their per-edge ins_addr (if any), so the repeated type/outside/stmt_idx/ confirmed attributes are not stored on every edge. On 1after909:doit 115/227 cc_graph edges collapse to the default (fake_return / outside:false / confirmed:true), shrinking the clinic payload from 46.7 to 45.4 KiB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sb2yG3v6dEXvY24r1TWzun
| Commit: | 5702648 | |
|---|---|---|
| Author: | Fish Wang | |
codegen: Merge the two position maps into one flagged entry table. map_pos_to_node and map_pos_to_addr mostly contain identical (start, length, node) entries (341 of 429 addr entries on 1after909:doit), so Codegen now stores a single pos_maps table where each PositionMappingEntry carries in_pos_to_node / in_pos_to_addr membership flags; parse splits it back into the two PositionMapping objects. 9,677 B in 985 entries becomes 8,297 B in 644 entries; whole cache 105.3 -> 103.9 KiB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sb2yG3v6dEXvY24r1TWzun
| Commit: | ceca076 | |
|---|---|---|
| Author: | Fish Wang | |
codegen: zlib-compress the rendered text. Codegen.text becomes bytes text_z (zlib-compressed UTF-8). On 1after909:doit the rendered text shrinks from 10,494 to 1,982 bytes, bringing the whole cache to 105.3 KiB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sb2yG3v6dEXvY24r1TWzun
| Commit: | 37909c4 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
codegen: SimVariable payload pool + delta-encoded ins_addr tags. Two encoding shrinks: (1) CVariable.variable / unified_variable and CFunction.variables_in_use store index+1 refs into a repeated bytes simvar_pool instead of repeating polymorphic SimVariable payloads; parse materializes a fresh SimVariable per reference. (2) When a tag dict carries both ins_addr and vex_block_addr, the pool entry stores ins_offset = ins_addr - vex_block_addr (a 1-2 byte zigzag varint) instead of a second absolute address; ins_addr alone stays absolute. On 1after909:doit: codegen 68.3 -> 61.3 KiB, whole cache 120.8 -> 113.8 KiB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sb2yG3v6dEXvY24r1TWzun
| Commit: | 2a69d19 | |
|---|---|---|
| Author: | Fish Wang | |
codegen: Store only the numeric ident suffix per node. CConstruct.ident is always "<ClassName>_<n>" and the class name is recoverable from the node's kind, so the node table stores just uint32 ident_no; parse reconstructs the string. Non-canonical idents raise at serialize time. On 1after909:doit the codegen payload shrinks from 80.8 KiB to 68.3 KiB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sb2yG3v6dEXvY24r1TWzun
| Commit: | ec8375a | |
|---|---|---|
| Author: | Fish Wang | |
codegen: Typed fields for dominant tags + interned tag dicts. CConstructTags gains typed fields for ins_addr / vex_block_addr / vex_stmt_idx / is_prototype_guessed (JSON map kept for the rest), and whole tag dicts are interned in a per-Codegen tag_pool with nodes holding an index+1 ref (0 = no tags). Parse builds a fresh dict per node so tag dicts are never shared. On 1after909:doit the codegen payload shrinks from 117.1 KiB to 80.8 KiB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sb2yG3v6dEXvY24r1TWzun
| Commit: | 7c85eb0 | |
|---|---|---|
| Author: | Fish Wang | |
clinic: Deduplicate AIL block payloads through a shared block pool. cc_graph and unoptimized_graph are mostly byte-identical block-for-block; both now reference a Clinic-level repeated bytes block_pool (AilGraph.block_refs) so each distinct payload is stored once. Parse creates a fresh Block per graph occurrence, so graphs never share node objects. On 1after909:doit the clinic payload shrinks from 77.2 KiB to 46.7 KiB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sb2yG3v6dEXvY24r1TWzun
| Commit: | e7a6ed0 | |
|---|---|---|
| Author: | Fish Wang | |
codegen: Intern SimType JSON strings in a per-Codegen type pool. Every SimType-carrying field (expr_type, cconst type and reference values, functy, casts, struct/variable types) now stores an index+1 ref into a repeated string type_pool on the Codegen message instead of repeating the JSON encoding; 0 means absent. On 1after909:doit the codegen payload shrinks from 163.4 KiB to 117.1 KiB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sb2yG3v6dEXvY24r1TWzun
| Commit: | ec19b17 | |
|---|---|---|
| Author: | Fish Wang | |
Clinic: Serialize only what the decompiler's cache-reuse path consumes. Clinic.downsize() now clears every non-primitive attribute the reuse path in Decompiler._decompile() does not read (graph -- restored from cc_graph on reuse -- _ail_graph, _init_ail_graph, _init_arg_vvars, _type_hints, derived _blocks_by_addr_and_size/func_args, func_ret_var, data_refs, _inline_functions, the stackarg offset manager, notes, and the runtime typehoon/_spt/scratch/_cache references), and the schema drops the corresponding fields; parse restores the same downsized defaults so live-cached and deserialized clinics are indistinguishable. stack_items stays (primitive result data that tests inspect). Dropping _type_hints orphaned the Atom protobuf family, so key_defs.proto and the atoms/type-hint serialization machinery are removed as well. Two decompiler tests that read clinic.graph post-run now use the decompiler-level d.ail_graph. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sb2yG3v6dEXvY24r1TWzun
| Commit: | 9f3f4bb | |
|---|---|---|
| Author: | Fish | |
Cleanups
| Commit: | 0ba96f7 | |
|---|---|---|
| Author: | Fish Wang | |
SRDA: Drop SRDAModel serialization; downsize Clinic before caching. An SRDAModel is always regenerated fresh from an AIL graph (populate_model), so serializing it was redundant: Clinic.downsize() drops the model, Decompiler calls it right before the clinic enters the decompilation cache, and the SRDAModel Serializable machinery, srda_model.proto, the VVarSet message, and the pack/parse_vvar_set helpers are removed. The AILCodeLocation / Tag / Definition messages in key_defs.proto (and their Serializable implementations) existed solely for SRDAModel's uses/defs maps and go away too; the Atom family stays for Clinic._type_hints. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bx3znTs2E4cRq6c2rjPHXA
| Commit: | 25b9d2a | |
|---|---|---|
| Author: | Fish Wang | |
c_serialize: Derive _DISPLAY_OPTION_ATTRS from the Codegen proto descriptor. Display-option fields occupy the reserved number band [30, 59] in the Codegen message; the attribute list is now generated from that range at import time instead of being hardcoded, so a new display option only needs the proto field. A sanity test guards the band against non-scalar fields, which the setattr-based loops cannot handle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bx3znTs2E4cRq6c2rjPHXA
| Commit: | 8567a95 | |
|---|---|---|
| Author: | Fish Wang | |
codegen: Make CConstruct.idx an int node identity; rename the old string idx to ident. The per-class-name counter string ("CVariable_3") becomes CConstruct.ident, a display label that was never unique within an AST (arg-list nodes are created before reset_ident_counters() in _analyze). The new CConstruct.idx is a per-codegen monotone int that is unique across the codegen's lifetime, allocated in CConstruct.__init__ (which now requires a codegen). SerializeContext uses idx directly as the serialization node id instead of minting its own, and parse resumes the allocator past the largest deserialized idx. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WhTDPq6PB2mA9uVebfmXNw
| Commit: | 8ee342b | |
|---|---|---|
| Author: | Fish Wang | |
OpDescriptor: Serialize to JSON instead of protobuf. Same treatment as DecompilationNote: the class carries its own to_json/from_json, the OpDescriptor protobuf message goes away, and BinopOperatorEntry carries the key as a JSON string. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WhTDPq6PB2mA9uVebfmXNw
| Commit: | 5ee904e | |
|---|---|---|
| Author: | Fish Wang | |
DecompilationNote: Serialize to JSON instead of protobuf. The class carries its own to_json/from_json with a class tag dispatched through a subclass registry, replacing the DecompilationNote/DecompilationNoteEntry protobuf messages and the two duplicated hand-rolled JSON encoders in clinic_serialize and c_serialize. DecompilationCache.notes becomes a map<string, string> of JSON payloads like the clinic and codegen note fields. DeobfuscatedStringsNote now round-trips its deobfuscated strings (base64-encoded) instead of silently degrading to a plain base note. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WhTDPq6PB2mA9uVebfmXNw
| Commit: | 2dc34e0 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
DecompilationCache: Stamp and serialize angr version + decompilation timestamp. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xBzThw25LVGbjGbgDeJzz
| Commit: | 98eeb48 | |
|---|---|---|
| Author: | Claude | |
| Committer: | Fish Wang | |
serialization: Replace the AIL pickle bridge with typed protobuf messages. The AilmentBlob { format_version, data=<pickle> } bridge is gone. Every AIL-typed slot now has an exact schema in the new ail_types.proto, with AIL leaves stored as the native postcard to_bytes() payloads: - AilGraph encodes DiGraph[Block] as repeated Block.to_bytes() plus index-based edges; edge attributes (type/outside/ins_addr/stmt_idx/ confirmed) round-trip through a typed AilEdgeData message with the type strings mirrored as a proto enum. Unknown node types, edge keys or edge type strings raise TypeError at pack time -- no fallback. - ArgVVars / VVarSet / TypeHints / IteExprs / StaticVVars / StaticBuffers cover the remaining container slots. Helpers live in angr.utils.ail_serialization; codegen's three AIL fields are plain to_bytes() bytes now. Reconstructable state is no longer serialized: - SRDAModel keeps only arch_name / func_graph / func_args / track_tmps on the wire. The scan that derives varid_to_vvar, vvar/tmp defs and uses, and the phi bookkeeping is factored out of SReachingDefinitionsAnalysis._analyze into populate_model(), which parse_from_cmessage re-runs over the deserialized graph. Note the reconstructed model is consistent-with-graph, whereas the original in-memory model may be stale relative to its own graph after later in-place simplifications; the round-trip test asserts equality against a fresh scan. - Clinic._blocks_by_addr_and_size is rebuilt from _init_ail_graph and Clinic.func_args from arg_vvars at parse time. angr/utils/ailment_blob.py, ailment_blob.proto and its generated module are deleted; no pickle remains anywhere in the decompilation cache serialization path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eq26AyXr7Ukip8PzLrynTk
| Commit: | bab4585 | |
|---|---|---|
| Author: | Claude | |
| Committer: | Fish Wang | |
serialization: Adapt DecompilationCache branch to Rust AIL classes and master refactors. - atoms.py: the VirtualVariableCategory import-time mirror check now enumerates member names explicitly (the Rust enum class is not iterable), and parsing reconstructs members via _from_int_py() (the Rust class is not callable with an int). - clinic_serialize/clinic.proto: Clinic._stackarg_offsets was replaced by StackArgOffsetManager on master; serialize its stack_arg_offsets records and recompute the SRDA-derived stackoff_to_vvars / all_stackarg_vvars at parse time. _complete_successors was removed by the RegionOverlay work; _rewrite_ites_to_diamond_max_cases, _expose_loop_head_backedges and _constrain_callee_prototypes are new config scalars and round-trip like the others. parse_clinic no longer sets the removed _handlers/_variable_kb attributes and initializes variable_map to a fresh VariableMap. - tests: VirtualVariable construction updated to the Rust signature (idx, varid, bits, category). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eq26AyXr7Ukip8PzLrynTk
| Commit: | fc020dd | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
DecompilationCache: Add top-level protobuf Serializable. Step 6 (final) of the DecompilationCache protobuf serialization effort. Ties together the per-step serialization built up in steps 1-5. New: angr/protos/decompilation_cache.proto with: - DecompilationCache: addr, errors, function_summary, clinic and codegen as embedded bytes (each manages its own format via its own Serializable), arg_vvars / ite_exprs as AilmentBlob, binop_operators / stackvar_max_sizes as repeated entry messages, notes as repeated DecompilationNoteEntry. - DecompilationParameters: closed schema for the 14 keys the user approved earlier. Pass-class refs go through the optimization- pass registry; options round-trip via PARAM_TO_OPTION lookup keyed on DecompilationOption.param. - DecompilationNote: small standalone message (key, name, content_json, level). - OpDescriptor: block_addr, stmt_idx, ins_addr, op. Implementation: decompilation_cache_serialize.py owns the serialize_cache / parse_cache logic. DecompilationCache subclasses Serializable and delegates serialize_to_cmessage / parse_from_cmessage to the helper module. DecompilationNote and OpDescriptor become Serializable in their own files; the JSON encoding the earlier steps used for these classes (in codegen and clinic) remains in place for the inline-fields case. Notably NOT serialized: cfg / variable_kb (decompilation inputs resolved from the parent Project at parse time) and the 4 typehoon-typed Python attributes (typehoon is out of scope until the Rust ailment port lands). Verified end-to-end on fauxware authenticate(): full cache round-trips to 152KB, 14 parameter keys preserved, codegen.text matches exactly, clinic graph (9 nodes) preserved. The cache-hit path was exercised by serializing the cache, parsing it back, installing the parsed cache into kb.decompilations, and re-running the Decompiler — second run hits the cache and produces an identical 362-char decompilation. This closes the feat/decompcache-serialization branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | e0f9c03 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
Clinic: Add protobuf Serializable with AIL pickle bridge. Step 5 of the DecompilationCache protobuf serialization effort. Adds clinic.proto and clinic_serialize.py making Clinic round-trip through protobuf. Splits Clinic state into three buckets: - CLEAN: ~40 primitives, sets/lists of ints, dicts of primitives, and already-Serializable sub-objects (SimVariable variants in arg_list / externs, the SRDAModel held by reaching_definitions, StackItem, DataRefDesc). All round-tripped natively. - AIL-typed: the 5 networkx graphs of ailment Blocks (graph, cc_graph, unoptimized_graph, _ail_graph, _init_ail_graph), plus _blocks_by_addr_and_size, arg_vvars / _init_arg_vvars, func_args, and _type_hints (which carries key_definitions atoms whose VirtualVariable.category is an ailment enum). Each goes through AilmentBlob pickle during the bridging period. - Runtime back-refs: project / kb / function / variable_kb / _cfg / _handlers / _cache / typehoon / _spt are reattached at parse time from kwargs. parse_clinic bypasses Clinic.__init__ (which runs the whole decompilation pipeline) via __new__ + direct attribute population. ClinicMode / ClinicStage / _skip_stages are stored as int32 values matching the Python enums' .value so the schema doesn't track the frequently-evolving ClinicStage member list. StackItemType is a small stable proto enum mirror. optimization_pass_registry from step 1 handles peephole_optimizations and _typehoon_cls FQN round-tripping. func_ret_var is the bare-SimVariable("__retvar") sentinel and is recreated at parse rather than serialized (the base SimVariable class has no protobuf message). Verified on fauxware authenticate(): clinic round-trips to ~140KB (mostly the pickled AIL graphs), 9-node graph preserved, externs / arg_list / stack_items / data_refs / SRDAModel all equal, ClinicMode / ClinicStage / _skip_stages preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | fb439fa | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
codegen: Add table-driven AST serialization for all 34 CConstruct kinds. Step 4b of the DecompilationCache protobuf serialization effort. Introduces c_serialize.py: a table-driven (per-class) serialization helper that walks the C AST, assigns each CConstruct a unique uint32 node_id, and writes a flat list of CConstructNode cmessages. Children that are CConstructs are referenced by id, not embedded — this lets PositionMapping / cexterns / map_addr_to_label reference into the tree without duplicating subtrees and gives us a stable handle for restoring cross-tree references on parse. - SerializeContext / ParseContext encapsulate the id-assignment and resolution machinery; parse is lazy with memoization on _parsed (which would also handle any future sharing in the AST). - Per-subclass serializer/parser pairs registered via _register; c.py invokes register_all() at module load. - Tag dicts are sanitized to entries with str keys and json.dumps-able values; non-conforming entries are silently dropped. - SimType fields are JSON-encoded via SimType.to_json / from_json. - SimVariable fields are stored as "<ClassName>\\0<proto bytes>" so the polymorphic dispatch type tag round-trips with the payload. - Function references are stored as addresses only; reattached via kb.functions.function() at parse time. - The three ailment-coupled subclasses (CAILBlock, CUnsupportedStatement, CDirtyExpression) carry their ailment payload as an AilmentBlob (pickle bridge until the Rust port lands). - serialize_subtree / parse_subtree are convenience entry points that wrap a single CConstruct root in the Codegen envelope, for callers and tests that don't want a full codegen object. - Tighten CFunctionMsg.addr to optional uint64 so HasField works. Verified on fauxware authenticate(): 46 AST nodes across 13 distinct kinds round-trip with matching type counts and node identities. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 4ff09b4 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
codegen.proto: Define schema for C AST + position maps + codegen wrapper. Step 4a of the DecompilationCache protobuf serialization effort. Schema only; Serializable methods come in 4b/4c/4d. Design highlights: - Indexed AST node table: every CConstruct instance gets a unique uint32 node_id assigned at serialize time; children are referenced by id rather than embedded inline so PositionMapping / cexterns / map_addr_to_label can point into the tree without duplicating subtrees and so cross-tree references round-trip cleanly. - 34 per-subclass payload messages + a polymorphic CConstructNode wrapper carrying (node_id, kind, tags, idx, optional CExpression cache fields, oneof body). - The three ailment-coupled subclasses (CAILBlock, CUnsupportedStatement, CDirtyExpression) carry their ailment payload as an AilmentBlob. - SimType-typed fields are stored as JSON strings via SimType.to_json. - SimVariable-typed fields are stored as already-serialized bytes (SimVariable is already Serializable). - Function references are stored as addresses only; callers reattach the Function from KB at parse time. - Position mappings reuse a single PositionMappingMsg / InstructionMappingMsg shape; map_ast_to_pos and map_addr_to_label have their own dedicated entry messages. - Codegen-level message carries text, all four position maps, cexterns, comments, notes, const_formats, and the full set of display options. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | fe04f4f | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
SRDAModel: Add protobuf Serializable with pickle bridge for AIL slots. Step 3 of the DecompilationCache protobuf serialization effort. - Add AilmentBlob proto wrapper (format_version + bytes data) for carrying ailment-typed payloads through the schema while the ailment data classes are ported to Rust separately. format_version=1 is Python pickle; format_version=2 is reserved for the Rust serde encoding once the port lands. - Add angr.utils.ailment_blob.pack/unpack helpers using pickle.HIGHEST_PROTOCOL. Unknown format_versions are rejected. - Add srda_model.proto and make SRDAModel Serializable. CLEAN fields (all_vvar_definitions, all_tmp_definitions, phi_vvar_ids, phivarid_to_varids[_with_unknown], vvar_uses_by_loc) serialize natively; AIL-typed slots (func_graph, func_args, varid_to_vvar, all_vvar_uses, all_tmp_uses) go through AilmentBlob. arch is reattached from the parent Project at parse time via the arch= kwarg. defaultdict semantics are restored for all_vvar_uses, all_tmp_definitions, and all_tmp_uses on parse. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 46c03dc | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
key_definitions: Add protobuf Serializable for atoms, codeloc, tags, Definition. Step 2 of the DecompilationCache protobuf serialization effort. Defines key_defs.proto and makes the following classes Serializable: - Atom hierarchy (Tmp, Register, VirtualVariable, MemoryLocation, GuardUse, ConstantSrc) with a polymorphic oneof. arch is dropped on serialize and reattached from the parent Project on parse via the arch= kwarg. VirtualVariable.oident (heterogeneous: int / tuple / None) is JSON-encoded; tuples re-tuplify on parse. MemoryLocation supports int / SpOffset / HeapAddress(int or Undefined); symbolic (claripy.ast.BV) addresses are explicitly rejected as they are not part of any persisted state targeted by this effort. - AILCodeLocation (frozen dataclass). - Tag hierarchy (Tag, FunctionTag, SideEffectTag, ParameterTag, LocalVariableTag, ReturnValueTag, InitialValueTag, UnknownSizeTag). Tag.metadata is JSON-encoded; non-JSON metadata is rejected. - Definition; only AILCodeLocation codelocs are supported (the more general CodeLocation hierarchy is not yet in scope). VirtualVariableCategory is mirrored locally in the proto so atom serialization does not depend on serializing the ailment IR. An import-time assertion catches drift between the mirror and the ailment IntEnum. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 9178fa2 | |
|---|---|---|
| Author: | Claude | |
| Committer: | Fish Wang | |
serialization: Replace the AIL pickle bridge with typed protobuf messages. The AilmentBlob { format_version, data=<pickle> } bridge is gone. Every AIL-typed slot now has an exact schema in the new ail_types.proto, with AIL leaves stored as the native postcard to_bytes() payloads: - AilGraph encodes DiGraph[Block] as repeated Block.to_bytes() plus index-based edges; edge attributes (type/outside/ins_addr/stmt_idx/ confirmed) round-trip through a typed AilEdgeData message with the type strings mirrored as a proto enum. Unknown node types, edge keys or edge type strings raise TypeError at pack time -- no fallback. - ArgVVars / VVarSet / TypeHints / IteExprs / StaticVVars / StaticBuffers cover the remaining container slots. Helpers live in angr.utils.ail_serialization; codegen's three AIL fields are plain to_bytes() bytes now. Reconstructable state is no longer serialized: - SRDAModel keeps only arch_name / func_graph / func_args / track_tmps on the wire. The scan that derives varid_to_vvar, vvar/tmp defs and uses, and the phi bookkeeping is factored out of SReachingDefinitionsAnalysis._analyze into populate_model(), which parse_from_cmessage re-runs over the deserialized graph. Note the reconstructed model is consistent-with-graph, whereas the original in-memory model may be stale relative to its own graph after later in-place simplifications; the round-trip test asserts equality against a fresh scan. - Clinic._blocks_by_addr_and_size is rebuilt from _init_ail_graph and Clinic.func_args from arg_vvars at parse time. angr/utils/ailment_blob.py, ailment_blob.proto and its generated module are deleted; no pickle remains anywhere in the decompilation cache serialization path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eq26AyXr7Ukip8PzLrynTk
| Commit: | 4bdae5d | |
|---|---|---|
| Author: | Claude | |
| Committer: | Fish Wang | |
serialization: Adapt DecompilationCache branch to Rust AIL classes and master refactors. - atoms.py: the VirtualVariableCategory import-time mirror check now enumerates member names explicitly (the Rust enum class is not iterable), and parsing reconstructs members via _from_int_py() (the Rust class is not callable with an int). - clinic_serialize/clinic.proto: Clinic._stackarg_offsets was replaced by StackArgOffsetManager on master; serialize its stack_arg_offsets records and recompute the SRDA-derived stackoff_to_vvars / all_stackarg_vvars at parse time. _complete_successors was removed by the RegionOverlay work; _rewrite_ites_to_diamond_max_cases, _expose_loop_head_backedges and _constrain_callee_prototypes are new config scalars and round-trip like the others. parse_clinic no longer sets the removed _handlers/_variable_kb attributes and initializes variable_map to a fresh VariableMap. - tests: VirtualVariable construction updated to the Rust signature (idx, varid, bits, category). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eq26AyXr7Ukip8PzLrynTk
| Commit: | 5b0549e | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
DecompilationCache: Add top-level protobuf Serializable. Step 6 (final) of the DecompilationCache protobuf serialization effort. Ties together the per-step serialization built up in steps 1-5. New: angr/protos/decompilation_cache.proto with: - DecompilationCache: addr, errors, function_summary, clinic and codegen as embedded bytes (each manages its own format via its own Serializable), arg_vvars / ite_exprs as AilmentBlob, binop_operators / stackvar_max_sizes as repeated entry messages, notes as repeated DecompilationNoteEntry. - DecompilationParameters: closed schema for the 14 keys the user approved earlier. Pass-class refs go through the optimization- pass registry; options round-trip via PARAM_TO_OPTION lookup keyed on DecompilationOption.param. - DecompilationNote: small standalone message (key, name, content_json, level). - OpDescriptor: block_addr, stmt_idx, ins_addr, op. Implementation: decompilation_cache_serialize.py owns the serialize_cache / parse_cache logic. DecompilationCache subclasses Serializable and delegates serialize_to_cmessage / parse_from_cmessage to the helper module. DecompilationNote and OpDescriptor become Serializable in their own files; the JSON encoding the earlier steps used for these classes (in codegen and clinic) remains in place for the inline-fields case. Notably NOT serialized: cfg / variable_kb (decompilation inputs resolved from the parent Project at parse time) and the 4 typehoon-typed Python attributes (typehoon is out of scope until the Rust ailment port lands). Verified end-to-end on fauxware authenticate(): full cache round-trips to 152KB, 14 parameter keys preserved, codegen.text matches exactly, clinic graph (9 nodes) preserved. The cache-hit path was exercised by serializing the cache, parsing it back, installing the parsed cache into kb.decompilations, and re-running the Decompiler — second run hits the cache and produces an identical 362-char decompilation. This closes the feat/decompcache-serialization branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 5897143 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
Clinic: Add protobuf Serializable with AIL pickle bridge. Step 5 of the DecompilationCache protobuf serialization effort. Adds clinic.proto and clinic_serialize.py making Clinic round-trip through protobuf. Splits Clinic state into three buckets: - CLEAN: ~40 primitives, sets/lists of ints, dicts of primitives, and already-Serializable sub-objects (SimVariable variants in arg_list / externs, the SRDAModel held by reaching_definitions, StackItem, DataRefDesc). All round-tripped natively. - AIL-typed: the 5 networkx graphs of ailment Blocks (graph, cc_graph, unoptimized_graph, _ail_graph, _init_ail_graph), plus _blocks_by_addr_and_size, arg_vvars / _init_arg_vvars, func_args, and _type_hints (which carries key_definitions atoms whose VirtualVariable.category is an ailment enum). Each goes through AilmentBlob pickle during the bridging period. - Runtime back-refs: project / kb / function / variable_kb / _cfg / _handlers / _cache / typehoon / _spt are reattached at parse time from kwargs. parse_clinic bypasses Clinic.__init__ (which runs the whole decompilation pipeline) via __new__ + direct attribute population. ClinicMode / ClinicStage / _skip_stages are stored as int32 values matching the Python enums' .value so the schema doesn't track the frequently-evolving ClinicStage member list. StackItemType is a small stable proto enum mirror. optimization_pass_registry from step 1 handles peephole_optimizations and _typehoon_cls FQN round-tripping. func_ret_var is the bare-SimVariable("__retvar") sentinel and is recreated at parse rather than serialized (the base SimVariable class has no protobuf message). Verified on fauxware authenticate(): clinic round-trips to ~140KB (mostly the pickled AIL graphs), 9-node graph preserved, externs / arg_list / stack_items / data_refs / SRDAModel all equal, ClinicMode / ClinicStage / _skip_stages preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 01a19dd | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
codegen: Add table-driven AST serialization for all 34 CConstruct kinds. Step 4b of the DecompilationCache protobuf serialization effort. Introduces c_serialize.py: a table-driven (per-class) serialization helper that walks the C AST, assigns each CConstruct a unique uint32 node_id, and writes a flat list of CConstructNode cmessages. Children that are CConstructs are referenced by id, not embedded — this lets PositionMapping / cexterns / map_addr_to_label reference into the tree without duplicating subtrees and gives us a stable handle for restoring cross-tree references on parse. - SerializeContext / ParseContext encapsulate the id-assignment and resolution machinery; parse is lazy with memoization on _parsed (which would also handle any future sharing in the AST). - Per-subclass serializer/parser pairs registered via _register; c.py invokes register_all() at module load. - Tag dicts are sanitized to entries with str keys and json.dumps-able values; non-conforming entries are silently dropped. - SimType fields are JSON-encoded via SimType.to_json / from_json. - SimVariable fields are stored as "<ClassName>\\0<proto bytes>" so the polymorphic dispatch type tag round-trips with the payload. - Function references are stored as addresses only; reattached via kb.functions.function() at parse time. - The three ailment-coupled subclasses (CAILBlock, CUnsupportedStatement, CDirtyExpression) carry their ailment payload as an AilmentBlob (pickle bridge until the Rust port lands). - serialize_subtree / parse_subtree are convenience entry points that wrap a single CConstruct root in the Codegen envelope, for callers and tests that don't want a full codegen object. - Tighten CFunctionMsg.addr to optional uint64 so HasField works. Verified on fauxware authenticate(): 46 AST nodes across 13 distinct kinds round-trip with matching type counts and node identities. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | e30dc97 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
codegen.proto: Define schema for C AST + position maps + codegen wrapper. Step 4a of the DecompilationCache protobuf serialization effort. Schema only; Serializable methods come in 4b/4c/4d. Design highlights: - Indexed AST node table: every CConstruct instance gets a unique uint32 node_id assigned at serialize time; children are referenced by id rather than embedded inline so PositionMapping / cexterns / map_addr_to_label can point into the tree without duplicating subtrees and so cross-tree references round-trip cleanly. - 34 per-subclass payload messages + a polymorphic CConstructNode wrapper carrying (node_id, kind, tags, idx, optional CExpression cache fields, oneof body). - The three ailment-coupled subclasses (CAILBlock, CUnsupportedStatement, CDirtyExpression) carry their ailment payload as an AilmentBlob. - SimType-typed fields are stored as JSON strings via SimType.to_json. - SimVariable-typed fields are stored as already-serialized bytes (SimVariable is already Serializable). - Function references are stored as addresses only; callers reattach the Function from KB at parse time. - Position mappings reuse a single PositionMappingMsg / InstructionMappingMsg shape; map_ast_to_pos and map_addr_to_label have their own dedicated entry messages. - Codegen-level message carries text, all four position maps, cexterns, comments, notes, const_formats, and the full set of display options. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 8d41c4e | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
SRDAModel: Add protobuf Serializable with pickle bridge for AIL slots. Step 3 of the DecompilationCache protobuf serialization effort. - Add AilmentBlob proto wrapper (format_version + bytes data) for carrying ailment-typed payloads through the schema while the ailment data classes are ported to Rust separately. format_version=1 is Python pickle; format_version=2 is reserved for the Rust serde encoding once the port lands. - Add angr.utils.ailment_blob.pack/unpack helpers using pickle.HIGHEST_PROTOCOL. Unknown format_versions are rejected. - Add srda_model.proto and make SRDAModel Serializable. CLEAN fields (all_vvar_definitions, all_tmp_definitions, phi_vvar_ids, phivarid_to_varids[_with_unknown], vvar_uses_by_loc) serialize natively; AIL-typed slots (func_graph, func_args, varid_to_vvar, all_vvar_uses, all_tmp_uses) go through AilmentBlob. arch is reattached from the parent Project at parse time via the arch= kwarg. defaultdict semantics are restored for all_vvar_uses, all_tmp_definitions, and all_tmp_uses on parse. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 1982c50 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
key_definitions: Add protobuf Serializable for atoms, codeloc, tags, Definition. Step 2 of the DecompilationCache protobuf serialization effort. Defines key_defs.proto and makes the following classes Serializable: - Atom hierarchy (Tmp, Register, VirtualVariable, MemoryLocation, GuardUse, ConstantSrc) with a polymorphic oneof. arch is dropped on serialize and reattached from the parent Project on parse via the arch= kwarg. VirtualVariable.oident (heterogeneous: int / tuple / None) is JSON-encoded; tuples re-tuplify on parse. MemoryLocation supports int / SpOffset / HeapAddress(int or Undefined); symbolic (claripy.ast.BV) addresses are explicitly rejected as they are not part of any persisted state targeted by this effort. - AILCodeLocation (frozen dataclass). - Tag hierarchy (Tag, FunctionTag, SideEffectTag, ParameterTag, LocalVariableTag, ReturnValueTag, InitialValueTag, UnknownSizeTag). Tag.metadata is JSON-encoded; non-JSON metadata is rejected. - Definition; only AILCodeLocation codelocs are supported (the more general CodeLocation hierarchy is not yet in scope). VirtualVariableCategory is mirrored locally in the proto so atom serialization does not depend on serializing the ailment IR. An import-time assertion catches drift between the mirror and the ailment IntEnum. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 36587c5 | |
|---|---|---|
| Author: | Ati Priya | |
| Committer: | GitHub | |
FunctionParser: Serialize Function._call_sites. (#6613) * FunctionParser: Serialize Function._call_sites. serialize stores the transition graph but not Function._call_sites, and parse_from_cmsg never repopulated it, so functions loaded back from LMDB (SpillingFunctionDict eviction, angrdb) returned nothing from get_call_sites(), get_call_target(), and get_call_return(). _call_sites cannot be rebuilt from transition graph edges. Store the mapping in a new repeated CallSite field on the Function message and restore it in parse_from_cmsg. * lint * Fix pyright errors in FunctionParser. * Fix pyright error in LMDB function manager test.
| Commit: | 5b222a7 | |
|---|---|---|
| Author: | atipriya | |
| Committer: | atipriya | |
FunctionParser: Serialize Function._call_sites. serialize stores the transition graph but not Function._call_sites, and parse_from_cmsg never repopulated it, so functions loaded back from LMDB (SpillingFunctionDict eviction, angrdb) returned nothing from get_call_sites(), get_call_target(), and get_call_return(). _call_sites cannot be rebuilt from transition graph edges. Store the mapping in a new repeated CallSite field on the Function message and restore it in parse_from_cmsg.
| Commit: | 9e9d33b | |
|---|---|---|
| Author: | Claude | |
| Committer: | Fish Wang | |
serialization: Replace the AIL pickle bridge with typed protobuf messages. The AilmentBlob { format_version, data=<pickle> } bridge is gone. Every AIL-typed slot now has an exact schema in the new ail_types.proto, with AIL leaves stored as the native postcard to_bytes() payloads: - AilGraph encodes DiGraph[Block] as repeated Block.to_bytes() plus index-based edges; edge attributes (type/outside/ins_addr/stmt_idx/ confirmed) round-trip through a typed AilEdgeData message with the type strings mirrored as a proto enum. Unknown node types, edge keys or edge type strings raise TypeError at pack time -- no fallback. - ArgVVars / VVarSet / TypeHints / IteExprs / StaticVVars / StaticBuffers cover the remaining container slots. Helpers live in angr.utils.ail_serialization; codegen's three AIL fields are plain to_bytes() bytes now. Reconstructable state is no longer serialized: - SRDAModel keeps only arch_name / func_graph / func_args / track_tmps on the wire. The scan that derives varid_to_vvar, vvar/tmp defs and uses, and the phi bookkeeping is factored out of SReachingDefinitionsAnalysis._analyze into populate_model(), which parse_from_cmessage re-runs over the deserialized graph. Note the reconstructed model is consistent-with-graph, whereas the original in-memory model may be stale relative to its own graph after later in-place simplifications; the round-trip test asserts equality against a fresh scan. - Clinic._blocks_by_addr_and_size is rebuilt from _init_ail_graph and Clinic.func_args from arg_vvars at parse time. angr/utils/ailment_blob.py, ailment_blob.proto and its generated module are deleted; no pickle remains anywhere in the decompilation cache serialization path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eq26AyXr7Ukip8PzLrynTk
| Commit: | 3557a9d | |
|---|---|---|
| Author: | Claude | |
| Committer: | Fish Wang | |
serialization: Adapt DecompilationCache branch to Rust AIL classes and master refactors. - atoms.py: the VirtualVariableCategory import-time mirror check now enumerates member names explicitly (the Rust enum class is not iterable), and parsing reconstructs members via _from_int_py() (the Rust class is not callable with an int). - clinic_serialize/clinic.proto: Clinic._stackarg_offsets was replaced by StackArgOffsetManager on master; serialize its stack_arg_offsets records and recompute the SRDA-derived stackoff_to_vvars / all_stackarg_vvars at parse time. _complete_successors was removed by the RegionOverlay work; _rewrite_ites_to_diamond_max_cases, _expose_loop_head_backedges and _constrain_callee_prototypes are new config scalars and round-trip like the others. parse_clinic no longer sets the removed _handlers/_variable_kb attributes and initializes variable_map to a fresh VariableMap. - tests: VirtualVariable construction updated to the Rust signature (idx, varid, bits, category). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Eq26AyXr7Ukip8PzLrynTk
| Commit: | 14a2fd5 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
DecompilationCache: Add top-level protobuf Serializable. Step 6 (final) of the DecompilationCache protobuf serialization effort. Ties together the per-step serialization built up in steps 1-5. New: angr/protos/decompilation_cache.proto with: - DecompilationCache: addr, errors, function_summary, clinic and codegen as embedded bytes (each manages its own format via its own Serializable), arg_vvars / ite_exprs as AilmentBlob, binop_operators / stackvar_max_sizes as repeated entry messages, notes as repeated DecompilationNoteEntry. - DecompilationParameters: closed schema for the 14 keys the user approved earlier. Pass-class refs go through the optimization- pass registry; options round-trip via PARAM_TO_OPTION lookup keyed on DecompilationOption.param. - DecompilationNote: small standalone message (key, name, content_json, level). - OpDescriptor: block_addr, stmt_idx, ins_addr, op. Implementation: decompilation_cache_serialize.py owns the serialize_cache / parse_cache logic. DecompilationCache subclasses Serializable and delegates serialize_to_cmessage / parse_from_cmessage to the helper module. DecompilationNote and OpDescriptor become Serializable in their own files; the JSON encoding the earlier steps used for these classes (in codegen and clinic) remains in place for the inline-fields case. Notably NOT serialized: cfg / variable_kb (decompilation inputs resolved from the parent Project at parse time) and the 4 typehoon-typed Python attributes (typehoon is out of scope until the Rust ailment port lands). Verified end-to-end on fauxware authenticate(): full cache round-trips to 152KB, 14 parameter keys preserved, codegen.text matches exactly, clinic graph (9 nodes) preserved. The cache-hit path was exercised by serializing the cache, parsing it back, installing the parsed cache into kb.decompilations, and re-running the Decompiler — second run hits the cache and produces an identical 362-char decompilation. This closes the feat/decompcache-serialization branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 86cffa9 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
Clinic: Add protobuf Serializable with AIL pickle bridge. Step 5 of the DecompilationCache protobuf serialization effort. Adds clinic.proto and clinic_serialize.py making Clinic round-trip through protobuf. Splits Clinic state into three buckets: - CLEAN: ~40 primitives, sets/lists of ints, dicts of primitives, and already-Serializable sub-objects (SimVariable variants in arg_list / externs, the SRDAModel held by reaching_definitions, StackItem, DataRefDesc). All round-tripped natively. - AIL-typed: the 5 networkx graphs of ailment Blocks (graph, cc_graph, unoptimized_graph, _ail_graph, _init_ail_graph), plus _blocks_by_addr_and_size, arg_vvars / _init_arg_vvars, func_args, and _type_hints (which carries key_definitions atoms whose VirtualVariable.category is an ailment enum). Each goes through AilmentBlob pickle during the bridging period. - Runtime back-refs: project / kb / function / variable_kb / _cfg / _handlers / _cache / typehoon / _spt are reattached at parse time from kwargs. parse_clinic bypasses Clinic.__init__ (which runs the whole decompilation pipeline) via __new__ + direct attribute population. ClinicMode / ClinicStage / _skip_stages are stored as int32 values matching the Python enums' .value so the schema doesn't track the frequently-evolving ClinicStage member list. StackItemType is a small stable proto enum mirror. optimization_pass_registry from step 1 handles peephole_optimizations and _typehoon_cls FQN round-tripping. func_ret_var is the bare-SimVariable("__retvar") sentinel and is recreated at parse rather than serialized (the base SimVariable class has no protobuf message). Verified on fauxware authenticate(): clinic round-trips to ~140KB (mostly the pickled AIL graphs), 9-node graph preserved, externs / arg_list / stack_items / data_refs / SRDAModel all equal, ClinicMode / ClinicStage / _skip_stages preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 3911ecd | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
codegen: Add table-driven AST serialization for all 34 CConstruct kinds. Step 4b of the DecompilationCache protobuf serialization effort. Introduces c_serialize.py: a table-driven (per-class) serialization helper that walks the C AST, assigns each CConstruct a unique uint32 node_id, and writes a flat list of CConstructNode cmessages. Children that are CConstructs are referenced by id, not embedded — this lets PositionMapping / cexterns / map_addr_to_label reference into the tree without duplicating subtrees and gives us a stable handle for restoring cross-tree references on parse. - SerializeContext / ParseContext encapsulate the id-assignment and resolution machinery; parse is lazy with memoization on _parsed (which would also handle any future sharing in the AST). - Per-subclass serializer/parser pairs registered via _register; c.py invokes register_all() at module load. - Tag dicts are sanitized to entries with str keys and json.dumps-able values; non-conforming entries are silently dropped. - SimType fields are JSON-encoded via SimType.to_json / from_json. - SimVariable fields are stored as "<ClassName>\\0<proto bytes>" so the polymorphic dispatch type tag round-trips with the payload. - Function references are stored as addresses only; reattached via kb.functions.function() at parse time. - The three ailment-coupled subclasses (CAILBlock, CUnsupportedStatement, CDirtyExpression) carry their ailment payload as an AilmentBlob (pickle bridge until the Rust port lands). - serialize_subtree / parse_subtree are convenience entry points that wrap a single CConstruct root in the Codegen envelope, for callers and tests that don't want a full codegen object. - Tighten CFunctionMsg.addr to optional uint64 so HasField works. Verified on fauxware authenticate(): 46 AST nodes across 13 distinct kinds round-trip with matching type counts and node identities. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 08ea83d | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
codegen.proto: Define schema for C AST + position maps + codegen wrapper. Step 4a of the DecompilationCache protobuf serialization effort. Schema only; Serializable methods come in 4b/4c/4d. Design highlights: - Indexed AST node table: every CConstruct instance gets a unique uint32 node_id assigned at serialize time; children are referenced by id rather than embedded inline so PositionMapping / cexterns / map_addr_to_label can point into the tree without duplicating subtrees and so cross-tree references round-trip cleanly. - 34 per-subclass payload messages + a polymorphic CConstructNode wrapper carrying (node_id, kind, tags, idx, optional CExpression cache fields, oneof body). - The three ailment-coupled subclasses (CAILBlock, CUnsupportedStatement, CDirtyExpression) carry their ailment payload as an AilmentBlob. - SimType-typed fields are stored as JSON strings via SimType.to_json. - SimVariable-typed fields are stored as already-serialized bytes (SimVariable is already Serializable). - Function references are stored as addresses only; callers reattach the Function from KB at parse time. - Position mappings reuse a single PositionMappingMsg / InstructionMappingMsg shape; map_ast_to_pos and map_addr_to_label have their own dedicated entry messages. - Codegen-level message carries text, all four position maps, cexterns, comments, notes, const_formats, and the full set of display options. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 5b4c041 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
SRDAModel: Add protobuf Serializable with pickle bridge for AIL slots. Step 3 of the DecompilationCache protobuf serialization effort. - Add AilmentBlob proto wrapper (format_version + bytes data) for carrying ailment-typed payloads through the schema while the ailment data classes are ported to Rust separately. format_version=1 is Python pickle; format_version=2 is reserved for the Rust serde encoding once the port lands. - Add angr.utils.ailment_blob.pack/unpack helpers using pickle.HIGHEST_PROTOCOL. Unknown format_versions are rejected. - Add srda_model.proto and make SRDAModel Serializable. CLEAN fields (all_vvar_definitions, all_tmp_definitions, phi_vvar_ids, phivarid_to_varids[_with_unknown], vvar_uses_by_loc) serialize natively; AIL-typed slots (func_graph, func_args, varid_to_vvar, all_vvar_uses, all_tmp_uses) go through AilmentBlob. arch is reattached from the parent Project at parse time via the arch= kwarg. defaultdict semantics are restored for all_vvar_uses, all_tmp_definitions, and all_tmp_uses on parse. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 45b8ed0 | |
|---|---|---|
| Author: | Fish Wang | |
| Committer: | Fish Wang | |
key_definitions: Add protobuf Serializable for atoms, codeloc, tags, Definition. Step 2 of the DecompilationCache protobuf serialization effort. Defines key_defs.proto and makes the following classes Serializable: - Atom hierarchy (Tmp, Register, VirtualVariable, MemoryLocation, GuardUse, ConstantSrc) with a polymorphic oneof. arch is dropped on serialize and reattached from the parent Project on parse via the arch= kwarg. VirtualVariable.oident (heterogeneous: int / tuple / None) is JSON-encoded; tuples re-tuplify on parse. MemoryLocation supports int / SpOffset / HeapAddress(int or Undefined); symbolic (claripy.ast.BV) addresses are explicitly rejected as they are not part of any persisted state targeted by this effort. - AILCodeLocation (frozen dataclass). - Tag hierarchy (Tag, FunctionTag, SideEffectTag, ParameterTag, LocalVariableTag, ReturnValueTag, InitialValueTag, UnknownSizeTag). Tag.metadata is JSON-encoded; non-JSON metadata is rejected. - Definition; only AILCodeLocation codelocs are supported (the more general CodeLocation hierarchy is not yet in scope). VirtualVariableCategory is mirrored locally in the proto so atom serialization does not depend on serializing the ailment IR. An import-time assertion catches drift between the mirror and the ailment IntEnum. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 6e835f9 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
CFGFast: Repair guessed jumptable targets; remove overlapped ones. (#6503) * CFGFast: Repair guessed jumptable targets; remove overlapped ones. - Track if jumptable targets are guessed or not. - For guessed jumptable targets, stop at the next referenced data location or the next jumptable address. * Increase the default limits.
| Commit: | 34b5b3d | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
CFGFast: Data awareness for MSVC x86 PEs. (#6355) * CFG: Improve data awareness. - Get pointer hints from PE relocation info. - Resolve pointer arrays to find new types of data. - Be more aggressive when scanning for wide strings. - Drop bad functions at the end of Stage 1 of CFGFast. * Parse MSVC 32-bit exception handling structs. * A new implementation. * Implement key function addrs cache in FunctionManager. Optimize parse_cxx_frame_handler3_data(). * EH4 scopetable parsing. * Fix the structure of FuncInfo. * TryBlockMapEntry and HandlerType. * More features. * More resilience. * drop_bad_functions: Skip non-trivially big functions. * Do not drop functions in Soot. * Ensure memory data is properly set even if it's discovered as pointers. * Fix inverted logic when filtering pointer hints. * Do not invoke drop_bad_functions() unless force_complete_scan or force_smart_scan is enabled. * Do not force memory data size to 0. * Filter out potentially decodable pointer locations. * Skip IMAGE_REL_BASED_ABSOLUTE. * Lint code and fix a test case. * Type check. * More type check. * Handle false functions created in the middle of other instructions. * CFGFast: Fix progressbar display. * Function.normalize(): Set bytestr for BlockNodes. * _remove_redundant_overlapping_blocks: Fix missing outside transitions in newly created functions. * Shrink blocks to avoid having blocks crossing function boundaries.
| Commit: | f02783d | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
Function: Record prototype source. (#6325) * Function: Record prototype source. Fix the issue in decompiler where the callee's prototype cannot be updated to the more accurate version (e.g., the prototype coming from decompiling the function) than the one that's generated at call sites. * Delay import. * Update some test cases. * Preserve function return type if the original prototype wasn't guessed. * Fix another test case. * Tweak * Type check.
| Commit: | d3bf694 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
CFG: Use hints from PE import/export tables. (#6276) * CFG: Use hints from PE import/export tables. Also: - Fix multiple issues causing incorrect sort for MemoryData. - Fix an issue causing overlapping code and memory data instances. * Do not extend memory data to max_size when fill_gaps is False. * Fix mismatches between seg list sort and memory data sort. * Resilience against loading pointers from unmapped regions.
| Commit: | 2815c1a | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
SpillingDiGraph: Use CFGEdgeData for serialization. (#6250)
| Commit: | d75c8ec | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
inst_addrs: Use InsAddrList instead of lists of ints. (#6247) * inst_addrs: Use InsAddrList instead of lists of ints. * Add test cases. * Implement InsAddrList.extend(). * Type check.
| Commit: | 4127f5d | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
CFGNode.proto: Make block_id repeated uint64. (#6225)
| Commit: | e497696 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
CFGBase: Reduce node loading during graph traversal. (#6220) * CFGBase: Reduce node loading during graph traversal. * Fix _is_tail_call_optimization. * Move block_addrs_with_return to CFGModel. * Fix cfg_fast_soot. * Lint and type check. * Update has_return during normalization.
| Commit: | 78799ac | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
CFGModel: Spilling CFG nodes to RtDb. (#6092) * Preliminary implementation of a spilling CFG graph. * Fix some test cases. * Fix another test case. * Fixes. * Lint code. * Implement InEdgeView and OutEdgeView. * Implement InDegreeView and OutDegreeView. * Fixes. * Use (Node.addr, Node.size) as key. * Fix test cases. * More fixes. * Fix CFGENode support. * Fix the remaining issues. * Get rid of SpillingCFGGraph.reverse(). * Some refactoring. * Oops * Fix perf issue. * Fix set size change error during key iteration. * Fix db_batch_size assignment. Fix some test cases. * SpillingCFGNodeDict.__setstate__: Initialize self._all_keys. * Getting rid of the nodes dictionary. * Fix logic in cfg_emulated.py * Multiple fixes. * Type annotation fix. * Fix missing edges after merging CFGNodes. * Fix more logic. * Add Soot CFGNodes to the CFG model. * Lint and type check. * Add USE_SPILLING_CFGNODE_DICT and CFGNode.dirty. * Oops * Lint code. * No more pickling of CFGNodes. * Fix no_ret being None. * Lint code. * Some refactor; Destroy the fallback mechanism. * Fix node dirty bug after deserialization.
| Commit: | c3fb109 | |
|---|---|---|
| Author: | Yibo Liu | |
| Committer: | GitHub | |
AngrDB: Support serialization for jump tables (#6118) * AngrDB: Support serialization for jump tables * Add test_jump_tables_roundtrip test case
| Commit: | 4f4c84e | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
AngrDb: Implement serialization for SimConstantVariable; Fix #5990. (#6056) * AngrDb: Implement serialization for SimConstantVariable; Fix #5990. * Fix db loading path. * Lint and type check.
| Commit: | cf1de5e | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
FunctionManager: Cache function names for faster lookup. (#6000) * FunctionManager: Cache function names for faster lookup. * FunctionParser: Serialize previous names. * Sort addresses only when they are all ints.
| Commit: | a31f3df | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
FunctionManager: Spill to external storage. (#5976) * FunctionManager: Spill to external storage. * Remove atexit registration. Reduce map size. * Introduce FuncNode in function graphs; Fix multiple issues with SpillingFunctionDict. * Implement Function.dirty. * A bit more optimization. * FunctionManager loads only meta data for functions when graphs are not accessed; Save .info for functions. * Only load meta data for Functions in more places. * Remove FunctionManager.block_map because it's never really used. * Retire blockaddr_to_function and replace it with blockaddr_to_funcaddr. * More optimizations and fixes. * More refactor and fixes. * More optimizations. * Fix the bug in lmdb spilling after raising MapFullError. * Introduce RuntimeDb in KB. Migrate SpillingFunctionsDict to use RuntimeDb. * Prioritize the basedir of the main executable for the runtime db path. * Cache non-returning function addrs, unknown-returning function addrs, and function block count in FunctionManager. * Bug fixes. * Fix a bug in FunctionParser. * CFGBase.make_functions: Copy over function metadata when creating functions in the first place. * Update MockFunctionManager. * Type check codenode.py and fix an RDA test case. * Fix serialization tests; Introduce KnowledgeBasePlugin.set_kb(); SpillingFunctionDict now derives from UserDict; Fix KB.name stored in KB._plugins; Fix FunctionDict.__setstate__ swapping Function objects and function addresses. * Update FactCollector to support FuncNode. * FunctionInfo: Update Function.dirty and perform type checks on keys and values. * Make function cache limit configurable. * Adjust FunctionInfo type check. * More fixes. * More updates to account for FuncNode in function graphs. * Update a test case. * Fix another test case (do not use the size of FuncNodes). * Fix Reassembler. * CFGBase.make_functions: Add a missing insertion to _updated_nonreturning_functions. * Update FunctionManager.rebuild_callgraph. * FunctionParser: Call destinations must be FuncNodes. * Serialize Function.is_default_name. * Minor fixes. * Fix CFunctionCall._is_target_ambiguous. * Mark evicted Function instances as evicted. * HashLookupAPIDeobfuscator: Take a list of function addresses instead of Function instances as arg. * CC_NAMES: Fix the bug of missing SimCCCdecl. * FunctionParser: Fix missing syscall function nodes. * HookNode: Take a SimProcedure instance instead of the class as the sim_procedure argument. * FunctionParser: Consider return-type edges when deserializing. * SimTypeCppFunction: Fix to_json() serialization crash. * FunctionParser: Fix missing return sites. * Function.is_{syscall,simprocedure,alignment,plt} settings should mark the function dirty. * RDA: Do not create blocks for FuncNodes or HookNodes. * Update a test case. * Fix issues with SimCppClass.to_json. * HookNode: Fix HookNode.__eq__. * Fix SootFunction. * Lint function_manager.py. * Lint and type check. * More docs; Spill Function.ran_cca. * RuntimeDb: Support specifying base dir using an environment variable. * Lint and fix test cases.
| Commit: | eb6871f | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
Remove pickle from StructuredCode, CFG, and Function graph serialization. (#5786) * Remove pickle from StructuredCode, CFG, and Function graph serialization. * More fixes; regenerate proto files. * Fix proto deserialization.
| Commit: | f09eeb7 | |
|---|---|---|
| Author: | Audrey Dutcher | |
| Committer: | GitHub | |
Serialize function prototype and cc (#5335)
| Commit: | a77b361 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
EnumsConv: Support Ijk_Sys_int. (#5152)
| Commit: | 085c718 | |
|---|---|---|
| Author: | Audrey Dutcher | |
| Committer: | GitHub | |
Aggressively add jumpkinds to the protobuf enum (#5119)
| Commit: | bd29144 | |
|---|---|---|
| Author: | Brian Caswell | |
| Committer: | GitHub | |
add MemoryDataSort.Alignment support to protobuf (#4927) * add MemoryDataSort.Alignment support to protobuf In #4878, MemoryDataSort.Alignment was added but it wasn't added in the backing protobuf files. This PR updates protobuf and regenerates the pb2 files with the latest protoc (28.2). This modifies the import per instructions in angr/protos/__init__.py * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * reformat after generation with `ruff` --------- Co-authored-by: Brian Caswell <bcaswell@microsoft.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
| Commit: | 8ef879f | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
CFGFast: Store full strings in MemoryData for overlapping string references. (#4223) * CFGFast: Store full strings in MemoryData for overlapping string references. * MemoryData.content can be None.
| Commit: | 25517f4 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
angrDb: Save instruction addresses for CFGNodes. (#3857) * angrDb: Save instruction addresses for CFGNodes. * Lint code
| Commit: | 148a147 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
Move .normalized to CFGModel. Close #3578. (#3579) * Move .normalized to CFGModel. Close #3578. * Regenerate cfg_pb2.py
| Commit: | 5ade392 | |
|---|---|---|
| Author: | Audrey Dutcher | |
| Committer: | GitHub | |
Add storage of decompiler const formatting in db (#3343) * Add storage of decompiler const formatting in db Also fix myriad angrdb issues * lint
| Commit: | b954398 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
Serializing variable names and codegens into angr DB (#2815) * Initial implementation for serializing variables. * Some placeholders. * More stuff * Support the storing and recovery of variable names in decompilation view. * Support storing and loading statement and expression comments. * Bug fix * Lint the code. * Remove a useless file.
| Commit: | c93d365 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
FLIRT support (#2692) * Preliminary FLIRT support. * Add the missing newline. * Get rid of the optional import of nampa. * Re-enable _IO_file_open. * Add build_sig.py * Add code for batch-loading FLIRT signatures. * Update build_sig.py * Support loading multiple FLIRT signatures into angr. * CompleteCallingConventions: Allow skipping signature-matched functions. * Unify the use of MemoryDataSort. Fix Function serialization. * oops * Lint the code. * Lint the code again.
| Commit: | c0a68b2 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
Use unsigned ints for addresses and sizes. (#2551) * Use unsigned ints for addresses and sizes.
| Commit: | 1b901f2 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
CFGFast: Handle exceptions. (#2067) * CFGFast: Handle exceptions. * Function.graph is missing exception edges. * Protos: Support exception edges. * Decompiler: Do not lose edge data. Hack in exception edges. * Clinic: Allow decompiling functions without exception edges.
| Commit: | 4c68259 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
angr database (#2034) * A preliminary implementation of angrdb. * Get a preliminary implementation working. - Switch from sqlite3 to sqlalchemy. - Implement serializers for Loader, CFG, and FunctionManager. - Fix a few issues in parsing and serializing knowledge plugins. * Fix CFBlanket initialization. * Support XRefs and some fixes. * Make sqlalchemy an optional dependency. * Make angrdb optional. * Add a test case for AngrDB. * Support dumping and loading comments. * Support dumping/loading labels. * Add an information table. Resiliency. More test cases. * Lint the code.
| Commit: | 535b8ee | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
Add elf-header to MemoryDataSort. Closes angr/angr-management#107. (#1677)
| Commit: | 9dafdb6 | |
|---|---|---|
| Author: | Fish | |
| Committer: | GitHub | |
Propagator (mostly-constant propagation) + XRefs analysis (#1352) * Add a basic constant propagation analysis. * Rename the analysis. Merge in the propagator analysis from ailment. Refactor a bit. * A preliminary xrefs analysis. * Add a xref manager. * Merge CodeReference into XRef. Remove CFGModel.references and replace it with the XRefManager. Some bug fixes. * Lint the code. * Get rid of XRefsState. * More linting.
| Commit: | a03c6a1 | |
|---|---|---|
| Author: | Fish | |
| Committer: | Fish | |
CFGFast: Do not remove function alignments by default.
| Commit: | 588cc79 | |
|---|---|---|
| Author: | Fish | |
| Committer: | Fish | |
Redesign memory data and references. Allow serialization and parsing of them.
| Commit: | 09c204e | |
|---|---|---|
| Author: | Fish | |
| Committer: | Fish | |
Implement CFGManager. Decouple CFGNodes from CFG.
| Commit: | e5f08b1 | |
|---|---|---|
| Author: | Fish | |
| Committer: | Fish | |
Store common properties onto edges directly. Also, the default statement ID is now DEFAULT_STATEMENT (-2) instead of the string "default" for consistency.
| Commit: | b380a15 | |
|---|---|---|
| Author: | Fish | |
| Committer: | Fish | |
Split CFG into a model and a view - step 3.
| Commit: | 609b3a9 | |
|---|---|---|
| Author: | Fish | |
| Committer: | Fish | |
Serialize and parse function graphs.
| Commit: | f4e147f | |
|---|---|---|
| Author: | Fish | |
| Committer: | Fish | |
Add a new message type Block.
| Commit: | 2caa458 | |
|---|---|---|
| Author: | Fish | |
| Committer: | Fish | |
Make Function serializable.