ProtoLoom
A schema-recovery tool that rebuilds usable Protocol Buffer definitions from compiled applications while preserving uncertainty.
Problem
Compiled software often retains enough Protocol Buffer structure to understand its data, even when the original .proto files are absent. Existing extraction work showed that useful fragments could be found, but I wanted an output that could be compiled, traced to evidence, and evaluated against known schemas.
The difficult part was not finding strings. It was deciding what the binary still proved. An optimizer may rename a class, inline a map factory, remove an enum association, or preserve a field number while erasing its source name. ProtoLoom was chosen as an exercise in recovering what survives without filling the gaps with plausible guesses.
Approach
The first implementation in August 2026 established three recovery paths. Embedded descriptors are the strongest case and can be decoded directly. Protobuf-lite metadata in Android DEX files requires interpreting generated code and compact message information. Native and Go binaries expose different descriptor and tag patterns. Evidence from these paths is reconciled into one internal schema model before any output is written.
Real applications changed the implementation quickly. Early comparisons exposed incorrect nesting, unresolved declared field types, synthetic presence oneofs, file-scope enums, repeated message elements, and package-name mismatches. Each correction followed evidence that remained in the compiled artifact. When the source identity did not remain, the tool kept the gap visible.
Architecture
Container readers identify APK, DEX, archive, ELF, Mach-O, and PE inputs. Extractors then collect descriptors, protobuf-lite metadata, Go tags, or Square Wire evidence. Decoders turn those records into messages, fields, enums, oneofs, and confidence notes. A reconciliation layer merges compatible evidence by package and qualified name.
The final layer emits .proto files, descriptor sets, JSON evidence, a Markdown report, and a static dashboard. It also compiles recovered schemas and performs payload round trips where a captured payload is available. The terminal interface uses the same saved recovery output, so browsing results does not require another extraction.
Validation
The benchmarks separate synthetic coverage from claims about shipping software. A pinned javalite matrix exercises scalars, packed fields, nested and repeated messages, maps, enums, oneofs, and proto3 optional presence across three runtime versions plus default and aggressive R8 builds. All five legs recover 13 of 13 fields with exact wire types and labels, but aggressive R8 lowers name recovery to 11 of 13, type fidelity to 9 of 13, and enum recovery to zero of two.
That reduction became one of the project’s most useful findings. Inspection recovered the obfuscated enum values, but not the original type name. Inferring the name from a value prefix would have produced a convincing result without binary evidence, so ProtoLoom leaves it unresolved.
The same rule was applied to real apps. Package normalization closed apparent gaps caused by compiled Java namespaces. Branch-state fixes closed failures caused by packed switches and conditional register clobbering. A JSON benchmark bug once flattened nested qualified names and understated Signal’s structural fidelity; descriptor-to-descriptor scoring had not been affected, and a collision fixture now covers the faulty fallback path.
Results
ProtoLoom now recovers compilable schemas from Android packages, native binaries, and Go programs without requiring a decompiler or AI service. The pinned javalite matrix reaches full field recall, precision, wire-type accuracy, label accuracy, structural fidelity, compilation, and payload round trips. Real-app runs cover eight hash-pinned APKs, including Bitwarden Authenticator, Mullvad, Gadgetbridge, Signal, and Molly.
The outcome I value most is the boundary the project makes explicit. Some missing structure is an engineering problem that better control-flow tracking can recover. Other structure is absent because compilation removed the final distinguishing signal. ProtoLoom treats those cases differently, which makes its recovered files useful without making them appear more certain than the binaries allow.