
Ein in Rust geschriebener nativer APK- und DEX-Decompiler
Der anfängliche Rust-DEX-Parser in src/native_dex.rs übernimmt Parsing-Logik aus
JADX v1.5.6, gepinnt auf Commit
28ff15e4ae69950aebea110a13e5ab895d234dfc.
JADX ist urheberrechtlich geschützt durch Skylot und seine Mitwirkenden; geltende
Android Open Source Project- und andere Upstream-Hinweise sind in NOTICE erhalten.
Die Referenzimplementierung ist das
DEX input plugin,
einschließlich DexReader, sections/DexHeader, sections/SectionReader,
sections/DexClassData und utils/Leb128.
RDX-Modifikationen übersetzen Parser-Logik nach Rust mit geprüftem Byte-Zugriff, expliziter Fehlerfortpflanzung und RDX-eigenen Klassen-/Member-Repräsentationen. Der native Source-Emitter ist neuer RDX-Code. Dies ist ein anfänglicher, partieller Parser und eine Native-Engine-Implementierung, kein vollständiger Port von JADX' Dekompilierungs- Pipeline und keine Behauptung gleichwertiger Ausgabeabdeckung.
Die folgenden Dateien sind unveränderte Kopien, die aus dem gepinnten Release heruntergeladen wurden:
8dada3edaf50dbc082c9a125058f25def75e625a).5c0b69a0f5298e0b329e33e860f7626f0c2c3891).Der vollständige Upstream-NOTICE bleibt erhalten, einschließlich historischer Hinweise zu gebündelten Bibliotheken und Icons. Die Beibehaltung bedeutet nicht, dass der Rust-Parser alle diese Bibliotheken oder Assets einbezieht. Die Java-Implementierung und ihre Laufzeitabhängigkeiten werden nicht mehr mitgeliefert.
Distributionen, die den angepassten Parser enthalten, müssen die geltende Lizenz und Hinweise beifügen. Änderungen, die von zusätzlichen Upstream-Dateien abgeleitet sind, sollten deren Hinweise beibehalten und diese Quellenzuordnung erweitern, während der Port wächst.
src/native_resources.rs bildet den Chunk-Dispatch, Namespace-, Element- und typisierten
Attribut-Parsing von gepinntem JADX v1.5.6
jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java
auf natives Rust ab. Sein String-Pool-Reader und begrenzter XML-Emitter sind RDX-Code.
Der Decoder validiert Input-/Chunk-/String-Grenzen, unterstützt UTF-8/UTF-16
Pools und verarbeitet gängige typisierte Android-Attributwerte ohne Java-Laufzeit.
Ressourcen-IDs bleiben numerisch: ARSC-Symbol-Lookup und Manifest-Enum-/Flag-Namen
sind noch nicht portiert. Dies ist nicht das vollständige Upstream-Ressourcen-Subsystem.
src/native_java/ ist RDX' konservative Rust-Registerwert-Lowering- und Java-
Emissionsschicht über dem angepassten DEX-Reader. Sie verarbeitet unterstützte typisierte Instruktionen, Vorwärtssprünge, einfache Schleifen und
Vorwärts-Switches mit expliziter Effektmaterialisierung und generierten Source-Mappings.
Array-/Typ-Opcode-Behandlung folgt der AOSP DEX instruction specification.
Es ist kein Port von JADX' CFG/SSA/Typinferenz-Pipeline und beansprucht nicht
deren Rekonstruktionsabdeckung. Nicht unterstützte Methoden behalten die native DEX-Ausgabe.
src/native_cfg.rs übernimmt den Split/Connect-Ansatz aus gepinntem JADX
BlockSplitter.java.
Die Rust-Implementierung arbeitet direkt auf geprüften DEX-Codeeinheiten, behält
Goto-Instruktionen und ursprüngliche Offsets bei, schließt Payload-Daten aus und
isoliert konservativ geschützte Instruktionen für exceptionale Kanten. Sie implementiert noch nicht
JADX' synthetische Blocktransformationen, SSA oder Regionskonstruktion. Dominator-
Analyse ist eine separate Stufe, die unten beschrieben wird.
Diese Stufe wird über ein separates Corpus-Audit bereitgestellt; der GUI-Source-Renderer
verwendet weiterhin das bestehende Registerwert-Lowering. Siehe
docs/jadx-port-plan.md für die verbleibenden Durchläufe.
src/native_dominators.rs übernimmt gepinntes
DominatorTree.java:
den iterativen Immediate-Dominator-Algorithmus von Cooper/Harvey/Kennedy, Predecessor-
Intersection und Dominance-Frontier-Walks. Rust-Modifikationen bewahren ursprüngliche
Block-IDs, verwenden iterative Reverse-Postorder-Traversierung, begrenzen Work-/Frontier-Speicher
und nutzen Tree-Intervalle für Dominance-Abfragen statt per-Block-Dominator-
Bitsets. Ein virtueller Entry-Predecessor behandelt Back-Edges zum Methoden-Entry.
Erreichbarkeit erfolgt vom tatsächlichen Methoden-Entry über normale und konservative
exceptionale Kanten; getrennte Handler-Blöcke werden als unerreichbar gemeldet.
Dies ist Dominator-Analyse, nicht der vollständige BlockProcessor-Transformationsdurchlauf.
src/native_ir.rs übernimmt das Instruktionsfamilien-Operandenmapping aus gepinntem
InsnDecoder.java.
Sein geprüfter Raw-DEX-Operanden-Reader folgt den AOSP-Instruktionsformaten und ist RDX-
Code. Er behält Offsets/Opcodes, geordnete Register-Reads und -Writes, Wortbreiten,
Literale, indizierte Referenzen und konservatives Throwing-Verhalten bei. Anders als Upstream
löst er noch keine Pool-Einträge auf, führt keine Call-Result-Merges durch und keine Typinferenz.
Invocation-Argumente bleiben geordnete Raw-Register-Wörter bis zur Signaturauflösung.
src/native_calls.rs löst nun Method-Pool-Einträge auf und gruppiert Receiver-/Argument-
Wörter nach ihren effektiven Prototypen, wobei dieselben gepinnten InsnDecoder-
Invoke-/Result-Konventionen befolgt werden. Es behandelt Wide-Argumente, Array-Owner, polymorphe
Sekundärprototypen und Filled Arrays und verknüpft benachbarte typisierte Move-Result-
Instruktionen. Custom Invokes lehnen explizit fehlende Call-Site-Metadaten ab.
Dies ist Signature Binding, nicht Virtual-Dispatch-Auflösung oder SSA.
Die Registerkategorien beschreiben Speicherbreiten-/Referenz-Constraints, nicht inferierte Java-Typen. CFG und Operanden-Dekodierung teilen sich einen Instruktionsbreiten-Decoder; der alte Source-Renderer bleibt separat, während diese Analyse-Pipeline aufgebaut wird.
src/native_dex_metadata.rs dekodiert kodierte Werte, Try/Catch-Handler-Listen und
gemeinsame Klassen-/Feld-/Methoden-/Parameter-Annotationssätze aus dem
AOSP DEX format.
Geprüfte Offsets, Allokations-/Work-Budgets, gemeinsamer Handler-Speicher und die Rust-
Repräsentationen sind RDX-Code. src/native_java/annotations.rs rendert gängige Java-
Annotationswerte und behält Typ-/Enum-Links und escapte Strings/Chars bei. Annotation-
Platzierung folgt gepinntem AnnotationGen.java.
Build-/Runtime-Annotationen werden angezeigt, auch auf Methoden mit DEX-Fallback-
Bodies. System-Annotationen bleiben Metadaten; Throws wird zusätzlich als throws-Klausel gerendert.
Nicht unterstützte Java-Werte werden explizit markiert. Annotation-Defaults und Debug-
Metadaten werden nicht vollständig rekonstruiert.
src/native_java/numeric.rs, strings.rs, liveness.rs und der Exception-
Renderer sind RDX-Implementierungen über der DEX-Instruktionssemantik. Ihre
konservativen Fallback-Grenzen und unabhängigen Rust-Verhaltens-Fixtures sind
dokumentiert in docs/native-engine.md und docs/validation.md. Sie führen keinen
Upstream-Java-Code aus oder betten ihn ein.
src/native_ssa.rs übernimmt Live-in-pruned Dominance-Frontier-Phi-Insertion und
Renaming aus gepinntem JADX
SSATransform.java.
Rust-Anpassungen verwenden iterative Traversierung, begrenzte Wortidentitäten und synthetische
Normal-Success-Blöcke, um Pre-Write-Exceptional-State zu bewahren. Letzteres ersetzt
Upstream-Post-Renaming-Try-Edge-Reparatur. Phi-Vereinfachung bleibt unportiert;
partielle Typinferenz wird unten beschrieben. native_call_values.rs hängt
bestehende Signatur-Constraints an SSA-Wörter. Es wird kein Upstream-Java ausgeführt.
src/native_types.rs übernimmt die Trennung von Assignment-/Use-Bound und die Propagations-
sequenz aus gepinntem JADX TypeInferenceVisitor.java
und TypeUpdate.java.
Die begrenzte Rust-Worklist, Wortpaar-Prüfungen, Literal-Alternativen und explizite
Unresolved-/Conflict-Ergebnisse sind RDX-Anpassungen. Dies ist partielle Inferenz:
Array-Element-Listener propagieren nun Load-Typen und Store-Constraints. Allgemeine
rückwärtsgerichtete Array-Inferenz, Reference Least Upper Bounds, Generics und Conversion-
Insertion bleiben unvollständig.
src/native_constructors.rs folgt SSA-Assignment-Ketten wie in gepinntem
ConstructorVisitor.java.
RDX prüft Allokationsdominanz und behält Origin und ursprünglichen invoked Owner bei.
Ein abweichender Owner wird nur dann für Retargeting markiert, wenn die Hierarchie beweist, dass er
ein Vorfahre des Allokationstyps ist. Verkettung durch einen bewiesenen Vorfahren auf
this folgt gepinntem ConstructorInsn.java. Diese Analyse entfernt oder verschiebt
keine Instruktionen, stellt keine Gültigkeit des Initialisierungszustands her und emittiert keine Konstruktoren.
Der begrenzte Nested-Allocation-Pfad in native_java/allocation_lowering.rs konsumiert nun
diese SSA-Konstruktorbindungen. Exakte Allokations-/Invoke-Identitäten und
eine RDX-Effect-Event-Prüfung gaten Shared-Capture-Java-Ausdrücke. Diese Integration
ist kein Port der vollständigen JADX-Region-/Codegenerierungs-Pipeline; Owner-Retarget-
Emission, Exception-Regionen und allgemeine Initialisierungszustandsverifikation bleiben
in diesem Pfad nicht unterstützt.
Array-Zuweisungsbeziehungen in native_hierarchy.rs folgen
JLS 4.10.3:
Referenz-Komponenten-Kovarianz, invariante primitive Komponenten und die standardmäßigen
Object/Cloneable/Serializable-Supertypen. Descriptor-Verschachtelung ist begrenzt; fehlende
externe Klassenbeziehungen bleiben unbekannt.
Die kleine Plattformhierarchie enthält außerdem verifizierte Interface-Kanten für Throwable / Serializable und SQLException / Iterable. Diese Fakten vermeiden falsch-negative Subtyp-Antworten aus dem vorherigen Exception-only- Parent-Graph; sie stellen keinen vollständigen Android-Plattform-Classpath dar.
Der begrenzte Allokationsdecoder erkennt ignorierte StringBuilder.append(String)-
Ergebnisse, geleitet durch das unverkettete Builder-Use-Muster in gepinntem
SimplifyVisitor.convertInvoke.
RDX behält tatsächliche Konstruktor-/Append-Aufrufe und exakte Effect-Traces bei; es führt nicht
die vollständige String-Konkatenations-Transformation von Upstream durch. Nur die exakte finale
Plattformklasse und Überladung mit ihrem dokumentierten Receiver-Return-Vertrag werden
akzeptiert; beliebige fluent-artige Methoden bleiben nicht unterstützt. Siehe
StringBuilder.append(String).
Klassen-invoke-super-Emission in native_java/method.rs folgt der Superclass-
Behandlung in gepinntem InsnGen.callSuper/getClassForSuperCall.
RDX beweist strikte Superclass-Abstammung unter Verwendung seiner begrenzten unveränderlichen Hierarchie,
anstatt zu verlangen, dass der DEX-Methoden-Owner dem direkten Parent entspricht. Es emittiert
super.method(...) und behält die ursprüngliche DEX-Signatur in Navigationsmetadaten bei.
Der Receiver muss weiterhin die aktuelle Instanz sein. Interface-Defaults, Qualified-Super-Aufrufe
der umschließenden Klasse und unvollständige/mehrdeutige Abstammung bleiben nicht unterstützt.
Klassen-/Interface-Dispatch-Unterscheidungen sind spezifiziert durch
AOSP's invoke-kind documentation.
Gepinntes JADX ConstructorVisitor.processInvoke entfernt die ursprüngliche
NEW_INSTANCE und ersetzt den Konstruktor-Invoke an Ort und Stelle; InsnGen emittiert dann
new Class(arguments). Relevante Upstream-Quellen:
RDX' natives allocation.rs behält seine striktere Ausdrucksrekonstruktion zuerst bei.
Nur für flache Fenster kann es geordnete Capture-Deklarationen stagen und new
an der Konstruktorposition platzieren, passend zum lesbaren Rekonstruktionsansatz von Upstream.
Anders als die breiteren Reorder-Klassifikationen von Upstream prüft RDX weiterhin
alle aufgezeichneten Cast-/Call-/Read-/String-Events in ihrer ursprünglichen Reihenfolge. Die beabsichtigte
Allokationsverlagerung kann Klasseninitialisierungs-, Linkage- und Allokationsfehler-Timing ändern; die Ausgabeabdeckung
belegt keine vollständige semantische Äquivalenz.
src/native_java/synchronized.rs übernimmt den Entry-/Body-/Monitor-Exit-Rekonstruktions-
ansatz von gepinntem jadx-core/src/main/java/jadx/core/dex/visitors/regions/maker/SynchronizedRegionMaker.java.
Die Rust-Implementierung fügt begrenzte CFG-Traversierung, dekodierte Register-Write- und
Exception-Coverage-Prüfungen, exakte Cleanup-Validierung und konservative Ablehnung von
verschachtelten/Multiple-Release/gemischten Exception-Formen hinzu. Sie ist eine partielle Implementierung,
kein vollständiger Port des Upstream-Region-Makers. Ursprüngliche SPDX-/Lizenzbedingungen
und Hinweise bleiben durch die obigen Dateien abgedeckt.
native_java/names.rs folgt der Trennung von ursprünglicher Identität und gültigen
Source-Aliasen in gepinntem JADX'
RenameVisitor.java,
insbesondere checkClassName und checkPackage. RDX verwendet sein bestehendes injektives
UTF-8-Hex-Alias-Schema statt JADX' konfigurierbarem Alias-Provider und globalem
Collision-Pass. Header, Konstruktoren, Typoperanden und Imports verwenden Aliase;
Source-Links behalten ursprüngliche DEX-Namen bei. Dies ist kein vollständiger RenameVisitor-Port.
Das Synchronized-Region-Subset behandelt zusätzlich ein nicht-werfendes Loop-Latch außerhalb des DEX-geschützten Intervalls und emittiert Schleifen vollständig innerhalb einer bewiesenen Monitor- Region. Es behält die Monitor-Region-Trennung des gepinnten Makers bei, während es Coverage für jede werfende Body-Instruktion außer dem bewiesenen Release verlangt.
native_java/finally_regions.rs verwendet den Duplicated-Cleanup-Erkennungsansatz
von gepinntem JADX' MarkFinallyVisitor.java.
Dies ist ein begrenztes Rust-Subset, kein vollständiger Visitor-Port: eine stabile Input-Void-
Cleanup-Invocation, eine normale Kopie, ein Catch-All-Rethrow und ein umschließender typisierter
Catch mit terminalen Pfaden. Es prüft ursprünglichen Per-Instruktions-Exception-Dispatch,
Control-Flow-Grenzen, Cleanup-Operanden und Source-Links vor der Emission.
Nicht unterstützte verschachtelte Layouts fallen weiterhin zurück.
Exakte Android-Framework-Exception-Metadaten basieren auf den Plattformdeklarationen: ActivityNotFoundException, RemoteException, und IBinder.transact.
Das Method-Snippet-UI und das Logging-Format in src/frida_snippet.rs folgen
JADX FridaAction.
Der Rust-Generator liest exakte DEX-Symbol-Deskriptoren, wählt immer die exakte
Überladung, verwendet positionale Argumentnamen und ruft diese erfasste Überladung auf.
Jedes Snippet ist innerhalb von Java.perform gescoped, sodass eingefügte Snippets nicht gegenseitig
ihre Method-Handles überschreiben können. Klassenweite und Feld-Snippets sind nicht implementiert.