Skip to content

Latest commit

 

History

History
299 lines (228 loc) · 24.5 KB

File metadata and controls

299 lines (228 loc) · 24.5 KB

Sprachen: English | 简体中文 | 繁體中文 | 日本語 | 한국어 | Français | Deutsch | Español | Italiano | Русский | العربية

Java-Rekonstruktion für Android

← Dokumentationsübersicht

neverd mobile stellt lesbares Java aus APK, DEX und smali ausschließlich mit der integrierten NeverD-Engine wieder her. Eigenständig implementierte Leser teilen sich ein typisiertes Dalvik-Modell und einen Java-Generator mit begrenztem Arbeitsaufwand. Diese experimentelle CLI-Funktion verspricht keine vollständige Wiederherstellung beliebiger APKs. APK-Container und Java-Ausgabe sind nicht über das native C-SDK, Python-Plugin-SDK, den GUI-Loader oder neverd decompile --language verfügbar.

Das erzeugte Java ist eine Rekonstruktion des Bytecodes. Ursprüngliche Kommentare, Formatierung, Entscheidungen der ursprünglichen Quellsprache und entfernte Bezeichner sind nicht verfügbar; auch Kotlin-Bytecode ergibt Java. Ein erfolgreicher Lauf beweist keine semantische Gleichwertigkeit und garantiert nicht, dass sich jede Methode erneut kompilieren lässt. Die analysierte Anwendung wird bei diesem Ablauf nicht gestartet.

Schnellstart

Bauen Sie NeverD und wählen Sie ein neues Ausgabeverzeichnis:

neverd mobile app.apk -o recovered-app
neverd mobile classes.dex -o recovered-dex
neverd mobile MainActivity.smali -o recovered-class
neverd mobile decoded/smali -o recovered-java

Unter recovered-app/sources/ finden Sie die Java-Dateien. recovered-app/report.json enthält das Eingabeinventar und die Einschränkungen. Wenn Smali-Klassen aufeinander verweisen, ist die Übergabe eines Verzeichnisses vorzuziehen.

Laufzeitumgebungen einrichten

Komponente Voraussetzung Auswahl
NeverD Bauen Sie das Ziel neverd mit einer C++20-fähigen Toolchain. Der mobile Ablauf ist in die native CLI eingebaut und ruft keinen Python-Interpreter auf. Verteilen Sie die ausführbare Datei zusammen mit den nativen Bibliotheken, die Ihr Build benötigt. build/bin/neverd / PATH

Die Android-Wiederherstellung verwendet ausschließlich die integrierte C++20-Engine von NeverD und benötigt keine Python- oder Java-Laufzeit. Sie verarbeitet darstellbare gewöhnliche Deklarationen und Operationen aus DEX 035, 037–040 und smali. DEX 041, dynamische Aufrufe wie invoke-custom, einige Initialisierungspfade, unbekannte semantische Annotationen oder Operationen sowie in Java nicht darstellbare Bezeichner führen ausdrücklich zum Fehler. Die Annahme eines Dateiformats bedeutet nicht, dass alle seine Anweisungen und Deklarationen unterstützt werden.

Die Namensauflösung in Java unterscheidet zwischen Klassenkopf und Klassenrumpf und kann bekannte Namensverdeckungen innerhalb desselben Pakets auflösen; fehlen jedoch Deklarationen externer Oberklassen oder Interfaces, sodass sich Typnamen oder Verweise im erzeugten Java-Hilfscode nicht eindeutig zuordnen lassen, wird die Wiederherstellung ausdrücklich abgelehnt, wobei nur für java.lang.Object ohne vorliegende Deklaration angenommen wird, dass es keine vererbbaren Mitgliedstypen beiträgt. Gleitkommaliterale in smali werden direkt auf die einfache oder doppelte Zielgenauigkeit gerundet, wobei das resultierende Bitmuster erhalten bleibt.

Die eingebaute C++-Engine erhält und prüft unterstützte Signature-Metadaten für Klassen, Felder und Methoden, einschließlich Typvariablen, Arrays, Wildcards, Typgrenzen und Namensverdeckung durch Methodentypvariablen. Die Typlöschung muss zur Identität der ursprünglichen DEX-Deklaration passen. Throws bleibt erhalten; nicht nachweisbare Ausnahmehierarchien werden abgelehnt. Generische Vererbung oder die Substitution von Mitgliedstypen, die Neuerzeugung von Brückenmethoden, generische Methodenaufrufe, parametrisierte innere Typen und die Zuordnung versteckter Konstruktorparameter bleiben ohne die erforderlichen Nachweise ausdrücklich nicht unterstützt.

Die leere, zur Laufzeit sichtbare Java-8-Markierung @java.lang.Deprecated bleibt an Klassen, Feldern, Methoden und Konstruktoren erhalten. Parameterannotationen, annotierte statische Initialisierer, andere Sichtbarkeitsstufen und Elementwerte etwa für since oder forRemoval werden abgelehnt. Die CI vergleicht nach der erneuten Kompilierung das Classfile-Attribut Deprecated und die Laufzeitannotationen getrennt, einschließlich nicht annotierter Kontrolldeklarationen und erzeugter Hilfsmethoden; die Hilfsmethoden zählen nicht zu den ursprünglichen Methoden.

DEX und Smali bewahren außerdem die Plattformannotation @android.annotation.SuppressLint an Klassen, Feldern, Methoden und Konstruktoren. Erforderlich sind Build-Sichtbarkeit und genau ein Zeichenkettenarray value; leere Arrays und Zeichenketten, Wiederholungen, Reihenfolge und maskierte Zeichenwerte bleiben erhalten. Parameterannotationen und annotierte statische Initialisierer bleiben nicht unterstützt. Die CI prüft mit dem Android SDK die mit CLASS gespeicherten Annotationen nach erneuter Kompilierung und vergleicht das Programmverhalten.

Die eingebaute Engine erhält außerdem die zur Laufzeit sichtbaren Metaannotationen @Retention, @Target, @Documented und @Inherited an unterstützten Annotationstypen und erzeugt ein echtes @interface. Dieser Teilumfang erlaubt keine Felder, Methoden, Typparameter oder verschachtelten Deklarationen. Unterstützt werden Annotationen auf oberster Ebene oder als statische Mitglieder mit nachgewiesenen Namen, Zugriffsrechten und Zuordnungen zur umschließenden Klasse; lokale und anonyme Gültigkeitsbereiche werden abgelehnt.

Leere Marker können an Klassen, Interfaces und Annotationstypen erhalten bleiben, wenn dieselbe analysierte Klassenmenge eine zugängliche, passende Markerdefinition enthält. Retention und Target müssen die konkrete Verwendung zulassen. Eine SOURCE-Deklaration kann rekonstruiert werden, eine in der Eingabe gespeicherte Verwendung wird jedoch abgelehnt. CLASS oder fehlende Retention erfordert DEX-Build-Sichtbarkeit (0), RUNTIME erfordert Laufzeitsichtbarkeit (1). Fehlende Retention bleibt von explizitem CLASS unterscheidbar, ebenso fehlendes Target von einem leeren Array; die Reihenfolge des Target-Arrays bleibt erhalten. Target-Werte sind auf Java 8 beschränkt; neuere Werte wie MODULE und RECORD_COMPONENT werden abgelehnt. @Inherited bleibt erhalten, ohne geerbte Verwendungen als direkte Annotationen auf Unterklassen zu kopieren.

Deklarationen von Annotationselementen und deren Standardwerte, nicht leere benutzerdefinierte Verwendungen, benutzerdefinierte Marker an Feldern/Methoden/Parametern, externe Annotationstypen, Container wiederholbarer Annotationen und kotlin.Metadata bleiben nicht unterstützt. Eine Markerdefinition wird als Klassendeklaration ohne Element- oder Hilfsmethoden ausgegeben und erhöht die Zahl wiederhergestellter Methoden nicht.

Die CI verarbeitet projekteigene Java-8-Testfälle mit D8 und NeverD, kompiliert sämtlichen erzeugten Java-Code erneut und vergleicht die vollständigen Signature-Metadaten, Reflection-Ergebnisse und das Verhalten. Diese Prüfungen belegen keine vollständige Wiederherstellung realer Anwendungen.

Linux und macOS

cmake --build build --target neverd

./build/bin/neverd mobile app.apk -o recovered-app

Pfade mit Leerzeichen müssen in Anführungszeichen stehen.

Windows PowerShell

& .\build\bin\neverd.exe mobile .\app.apk -o .\recovered-app

Bei Builds mit mehreren Konfigurationen kann die ausführbare Datei unter build/bin/Release/ liegen. Beachten Sie die üblichen Bereitstellungsanforderungen der nativen Bibliotheken dieses Builds.

Unterstützte Eingaben und Grenzen

Die folgende Eingabetabelle beschreibt die Rekonstruktion. Die später beschriebenen Abfragemodi verwenden einen engeren Validierungsumfang.

Eingabe Verhalten Wichtige Grenze
.apk Das gesamte ZIP validieren und anschließend alle classes.dex, classes2.dex und weiteren nummerierten DEX-Dateien im Archivwurzelverzeichnis gemeinsam analysieren Nur Code; keine Dekodierung von Ressourcen oder Manifest
.dex DEX 035 oder 037–040 mit dem integrierten Leser prüfen und analysieren DEX 041 und nicht unterstützte Deklarationen oder Operationen scheitern; umbenannte oder abgeschnittene Dateien sind kein gültiger Bytecode
.smali Die übergebene Klasse analysieren Referenzierte benachbarte Klassen werden nicht implizit geladen
Smali-Verzeichnis .smali-Dateien rekursiv sammeln und gemeinsam analysieren Verschachtelte Klassen und abhängige Smali-Wurzelverzeichnisse in das Eingabeverzeichnis aufnehmen

Wenn ein dekodierter APK-Verzeichnisbaum sowohl smali/ als auch smali_classes2/ enthält, übergeben Sie deren gemeinsames übergeordnetes Verzeichnis. Nur .smali-Dateien gelangen zum Backend, doch zuvor wird der gesamte übergebene Baum validiert und kopiert; große, nicht benötigte Assets zählen somit ebenfalls gegen die Eingabegrenzen. Ein kompaktes Verzeichnis mit ausschließlich den relevanten Smali-Wurzelverzeichnissen reduziert den Aufwand.

Split-APKs sind getrennte Eingaben. Jedes APK mit DEX-Inhalt kann einzeln verarbeitet werden, dieser Befehl führt jedoch keinen APK-Satz zusammen. Reine Ressourcen-Splits scheitern, weil sie kein DEX im Archivwurzelverzeichnis enthalten. .aab, .apks, .xapk, .odex, .oat und .vdex werden nicht als mobile Eingaben akzeptiert.

APK-Ressourcen, AndroidManifest.xml, Assets, JNI-/native Bibliotheken und zur Laufzeit heruntergeladener Code werden nicht als Java rekonstruiert. Extrahieren Sie eine native .so separat und verwenden Sie neverd decompile library.so -o library.c. Verschlüsselte oder gepackte Nutzlasten müssen für diesen statischen Ablauf bereits als gewöhnliches DEX/Smali vorliegen; Entpacken von Schutzschichten, Anbindung an ein Gerät und Umgehung von Schutzmechanismen sind nicht Teil des Ablaufs.

Schnelles Klasseninventar

neverd mobile app.apk --list-classes
neverd mobile classes.dex --list-classes --class-prefix com.example
neverd mobile app.apk --list-classes --class-prefix Lcom/example/ --json
neverd mobile app.apk --list-classes -o classes.txt

Diese Abfrage liest Klassenidentitäten, ohne Methodenrümpfe zu dekodieren oder Java zu erzeugen. Sie benötigt weder ein Vorbereitungsverzeichnis noch eine externe Laufzeit. Die Textausgabe enthält je Zeile einen exakten DEX-Deskriptor, in der Reihenfolge des ZIP-Verzeichnisses und danach der DEX-Definitionen. --class-prefix akzeptiert ein Deskriptorpräfix oder ein Paketpräfix mit Punkten; es prüft ein wörtliches Präfix und keine Paketgrenze. Doppelte Klassendefinitionen, auch über DEX-Dateien hinweg, führen ausdrücklich zum Fehler. Das gilt auch für Klassenidentitäten, die sich nicht verlustfrei als UTF-8 darstellen lassen.

Ohne -o schreibt die Abfrage nach stdout. Im Abfragemodus bezeichnet -o eine neue Datei, kein Rekonstruktionsverzeichnis. Bestehende Dateien bleiben unverändert. Ergebnisse werden gepuffert, bis alle ausgewählten DEX-Dateien erfolgreich geprüft sind; eine später auftretende fehlerhafte DEX-Datei verhindert daher jede teilweise Veröffentlichung. --json enthält die Anzahl der passenden und aller Klassen, die DEX-Anzahl und validation_scope: "dex-envelope-and-class-identities".

Alle ZIP-Namen, Header, Bereiche und angegebenen Ressourcenlimits werden geprüft. Nur classes.dex und nummerierte classesN.dex im Wurzelverzeichnis werden dekomprimiert und per CRC geprüft; die Integrität anderer Ressourceninhalte bleibt ungeprüft. Jeder DEX behält die Prüfungen von Header, SHA-1, Adler-32, Map-Grenzen und referenzierten Klassenmetadaten bei. Methodenrümpfe und nicht referenzierte Metadaten werden nicht validiert. Dies ist eine Inventarabfrage, keine Integritätsprüfung des gesamten Archivs und kein Nachweis einer Java-Rekonstruktion. DEX 041 sowie Abschnitte für Methoden-Handles und benutzerdefinierte Aufrufstellen bleiben nicht unterstützt. Der übliche vollständige Rekonstruktionspfad validiert weiterhin alle Nutzdaten des Archivs.

--timeout, --max-files und --max-bytes gelten. Das Klassenlimit zählt vor dem Filtern alle Definitionen über sämtliche DEX-Dateien; nicht ausgewählte ZIP-Einträge zählen weiterhin für die Archivlimits. iOS-Optionen und smali-Eingaben sind für die Inventaroperation nicht zulässig.

Abfragen von Codereferenzen

Direkte Instruktionsoperanden ohne Java-Erzeugung suchen:

neverd mobile app.apk --find-refs string --query 'login failed' --json
neverd mobile classes.dex --find-refs type --query 'Lcom/example/Service;' --exact
neverd mobile app.apk --find-refs method --query '->connect(' --owner 'Lcom/example/Client;'
neverd mobile app.apk --find-refs field --query 'Lcom/example/State;->ready:Z' --exact -o refs.jsonl

Der Abgleich sucht wörtliche Teilzeichenfolgen und unterscheidet Groß- und Kleinschreibung. --exact vergleicht das vollständige Ziel: Zeichenketteninhalt, Typdeskriptor, Methodenidentität wie Lpkg/Type;->name(I)V oder Feldidentität wie Lpkg/Type;->name:I. --owner beschränkt den Zielbesitzer von Methoden- oder Feldreferenzen auf einen exakten Deskriptor. Die Methode, welche die Referenz enthält, wird dadurch nicht gefiltert. Leere Suchtexte, smali-Eingaben und gemischte Abfrage-/Rekonstruktionsoptionen sind nicht unterstützt; Regex-Metazeichen gelten als gewöhnliche wörtliche Zeichen.

Standardmäßig wird je Vorkommen ein kompaktes JSON-Objekt ausgegeben (JSON Lines). --json liefert einen Bericht mit Zählern und einem Array references. Jede Zeile enthält dex_entry, die vollständige umgebende method, pc_code_units (16-Bit-Einheiten ab der ersten Instruktion der Methode), opcode, kind, target_index (DEX-lokal) und target. Alle Vorkommen bleiben erhalten, einschließlich gemeinsam genutzten Codes, der mehreren Methodendefinitionen zugeordnet wird. Zeichenkettenzeilen enthalten auch die exakten Einheiten target_utf16; target ist null, wenn ein isoliertes Surrogat eine verlustfreie UTF-8-Ausgabe verhindert. Andere Identitäten müssen als UTF-8 darstellbar sein.

Der Scanner verwendet die Instruktionsgrenzen, Operandenprüfungen, Payload-Verarbeitung und Kontrollflussprüfungen des Rekonstruktionslesers. Immediate-Werte sowie switch-/array-Payload-Daten können keine Referenzen werden. Jeder definierte Coderumpf wird geprüft, auch wenn kein Ziel passt, bevor code_scan_complete: true gesetzt wird. defined_method_count schließt native und abstrakte Deklarationen ein; scanned_method_count zählt Definitionen mit Rumpf und scanned_code_item_count unterschiedliche physische Rümpfe je DEX. matching_pool_entries zählt passende Ziele, auch nicht referenzierte.

validation_scope: "dex-code-references" umfasst den DEX-Rahmen, Identifikatortabellen, die Klassen-/Member-Zuordnung sowie verarbeitete Code-, Ausnahme- und Debug-Daten. Annotationen, statische kodierte Werte, reine Deklarationsverwendungen und nicht referenzierte Metadaten liegen außerhalb dieser Abfrage. Sie ist weder Java-Rekonstruktion noch ART-Verifier. Nicht unterstützter Code und fehlerhafte verarbeitete Daten führen ausdrücklich zum Fehler. Die APK-Validierung hat dieselbe Grenze ausgewählter Nutzdaten wie das Klasseninventar; die Integrität nicht ausgewählter Ressourcen bleibt ungeprüft.

Die Ergebnisse aller ausgewählten DEX-Dateien werden vor der Veröffentlichung gepuffert, einschließlich der Prüfung auf DEX-übergreifend doppelte Klassen. Das optionale -o bezeichnet eine neue Datei. --max-files begrenzt die Gesamtzahlen von Klassendefinitionen, Methodendefinitionen und Ergebnisvorkommen jeweils separat sowie ZIP-Einträge. --max-bytes begrenzt Eingabe, aufbewahrte Abfragedaten, Arbeitsspeicher je Rumpf und Ausgabe (mit konservativen Zuschlägen für die JSON-Vergrößerung). Das sind Operationsbudgets; der Prozess-RSS umfasst zusätzlich Eingabepuffer, Allokator-Overhead und Laufzeit. Die üblichen Zeit- und Arbeitsbudgets gelten ebenfalls.

Optionen und Vorrang

neverd mobile app.apk -o recovered-app --platform=android \
  --timeout=600 --max-files=30000 --max-bytes=4294967296 --json
Option Standard Bedeutung
-o PATH Für Rekonstruktion erforderlich Neues Rekonstruktionsverzeichnis; in beiden Abfragemodi optionale neue Ausgabedatei
--list-classes Aus APK-/DEX-Klassenidentitäten ohne Java-Rekonstruktion abfragen
--class-prefix PREFIX Alle Klassen Wörtliches Deskriptorpräfix oder Präfix mit Punkten; erfordert --list-classes
--find-refs KIND Aus Direkte Instruktionsreferenzen auf Zeichenketten, Typen, Methoden oder Felder abfragen
--query TEXT Für Referenzen erforderlich Wörtliche Teilzeichenfolge der Zielidentität
--exact Aus Vollständige Zielidentität der Referenz abgleichen
--owner DESCRIPTOR Beliebiger Besitzer Exakter Zielbesitzer für Methoden-/Feldabfragen
--platform=auto|android auto Android ausdrücklich auswählen oder die Plattform aus der Eingabe ableiten
--timeout N 300 Positives Analysezeitbudget in Sekunden
--max-files N 20000 Positive Grenze für Einträge, einschließlich angelegter Verzeichnisse
--max-bytes N 2147483648 Positive Bytegrenze für Eingabe, extrahierte Daten und endgültige Ausgabe
--json Aus Einen Bericht als JSON ausgeben; Referenzabfragen liefern sonst JSON Lines

Eine vom Standard abweichende --arch-Auswahl, --artifact, --metadata-only und ein von null verschiedenes --max-func gehören zu iOS und werden für Android abgelehnt; explizites --arch=auto ist zulässig.

Für Eingaben, entpackte Daten und endgültige Ausgaben gelten weiterhin die Datei- und Bytebudgets. Die integrierten Leser und der Generator prüfen zusätzlich Arbeitsaufwand und verstrichene Zeit. Das Erhöhen eines Limits schaltet andere Grenzen nicht ab.

Ausgabestruktur und JSON-Bericht

recovered-app/
  sources/                       wiederhergestellte Java-Pakete und Klassen
  metadata/android-methods.json  Methodenabdeckung der integrierten Engine
  report.json                    versioniertes Inventar und Grenzen

Temporäre Eingaben werden entfernt. Verschachtelte Klassen können die Quelldatei ihrer äußeren Klasse teilen; die Anzahl der Java-Dateien entspricht daher nicht der DEX-Klassenanzahl. Generierte Methoden können eine Java-Verteilerschleife verwenden. Sie führen weder die ursprüngliche DEX aus noch rufen sie diese über eine Laufzeitbrücke auf.

Der integrierte Bericht enthält android_method_recovery; derselbe Inhalt steht in metadata/android-methods.json, und jede ursprüngliche Methode bleibt im Inventar. Es gilt method_count = recovered_method_count + projected_method_count + declaration_only_method_count + unrecovered_method_count. Ein fehlender projected_method_count bedeutet null; unrecovered_method_count bleibt vor der Veröffentlichung null. Ursprüngliche native- und abstract-Methoden erhalten den Status declaration-only und zählen nicht als wiederhergestellte Rümpfe.

Eine begrenzte Teilmenge benannter lokaler Klassen ohne erfasste äußere Variablen kann in ihrer exakt zugeordneten statischen Methode ausgegeben werden. Voraussetzungen sind eine gewöhnliche Methode mit Skalartypen, eine feldlose Klasse direkt unter Object, ein tatsächlicher parameterloser Konstruktor, skalare Instanzmethoden und nachgewiesene Objektverwendungen ohne Entweichen aus dem unterstützten Bereich. Anonyme Klassen, Variablenerfassung, nicht unterstützte Modifizierer und unbelegte Verwendungen führen weiterhin ausdrücklich zum Fehler.

Die lokalen Methoden und ihre umschließende Methode erhalten source-projected mit projection_kind: "named-method-local"; die Abdeckung bleibt partial, auch wenn der äußere Ablauf success meldet. Die binären Namen und Zugriffsflags nach erneuter Kompilierung sind noch nicht verifiziert. Da der Java-Compiler einen anderen binären Namen wählen kann, hält class_source_bindings ursprüngliche Klasse, exakte umschließende Methode, Quellpfad und lokalen Namen mit binary_name_status: "unverified" fest.

generated_source_helpers führt zusätzliche Methoden mit den exakten Typen throw-helper, constant-helper, default-constructor und field-initializer auf. Der letzte Typ bezeichnet einen zusätzlich erzeugten <clinit>, der im ursprünglichen Methodenbestand nicht vorhanden war. Diese zusätzlichen Methoden zählen nicht zur ursprünglichen Gesamtzahl. Erfolgreiche Kompilierung oder eine einzelne Namensübereinstimmung belegen keine vollständige Wiederherstellung. Das folgende gekürzte Beispiel enthält keine projizierten Methoden:

{
  "schema_version": 1,
  "status": "success",
  "platform": "android",
  "source": "app.apk",
  "input_kind": "apk",
  "backend": {
    "name": "neverd",
    "version": "1",
    "execution": "builtin"
  },
  "input_code_files": [
    "classes.dex",
    "classes2.dex"
  ],
  "dex_count": 2,
  "smali_count": 0,
  "java_source_count": 2,
  "java_sources": [
    "sources/example/Main.java",
    "sources/example/Peer.java"
  ],
  "logs": [],
  "android_method_recovery": {
    "schema_version": 1,
    "status": "recovered",
    "class_count": 2,
    "method_count": 6,
    "recovered_method_count": 5,
    "declaration_only_method_count": 1,
    "unrecovered_method_count": 0
  }
}

input_kind ist apk, dex, smali oder smali-directory. input_code_files enthält Namen der eingegebenen Bytecode-Dateien oder Smali-Pfade, während java_sources und logs relativ zum Ausgabewurzelverzeichnis angegeben werden. source ist der Basisname der Eingabe. Tatsächliche Berichte enthalten weitere Rekonstruktionsgrenzen; behalten Sie diese bei, wenn Sie Ergebnisse an andere Werkzeuge weitergeben.

Prüfen Sie bei automatisierter Verarbeitung den Exit-Code des Prozesses, bevor Sie status auswerten. Wenn Sie stdout umleiten, speichern Sie den Bericht außerhalb des neuen Ausgabeverzeichnisses:

neverd mobile app.apk -o recovered-app --json > recovery-result.json

Die native CLI liefert bei Erfolg null und bei Wiederherstellungsfehlern einen Wert ungleich null. Mit --json enthalten behandelte Fehler schema_version, status: "error" und error. Argumentprüfung, Startfehler nativer Programme oder Bibliotheken und Unterbrechungen können ausschließlich auf stderr erscheinen. Prüfen Sie zuerst den Exitstatus.

Fehlerbehandlung und Problembehebung

Die Veröffentlichung ist transaktional: Vorhandene Ausgaben bleiben erhalten, fehlgeschlagene temporäre Ergebnisse werden entfernt. Nicht unterstützte Operationen, ungeklärte Registerflüsse, nicht darstellbare Deklarationen, fehlerhafte Ausnahmebehandlung und ausgeschöpfte Budgets lassen die integrierte Ausführung scheitern, statt fehlende Methodenrümpfe zu veröffentlichen. Eine erfolgreiche Wiederherstellung beweist keine semantische Gleichheit.

Symptom Maßnahme
DEX, Anweisung, Deklaration oder Initialisierung nicht unterstützt Diagnose und unterstützten Umfang prüfen
Ungültige Eingabe oder doppelte Klasse Bytecode oder Klassenmenge korrigieren; nicht unterstützte Rümpfe werden nicht stillschweigend ausgelassen
Zeit- oder Arbeitsbudget überschritten Eingabe verkleinern oder --timeout, --max-files und --max-bytes an verfügbare Ressourcen anpassen
Ausgabe bereits vorhanden Neues Ausgabeverzeichnis wählen

Verifikation und Supporttiefe

Python dient nur den folgenden Entwicklungstests; die integrierte mobile Wiederherstellung läuft in der nativen C++20-CLI.

cmake --build build --target check-neverd-mobile
ctest --test-dir build -L NeverDMobileTests --output-on-failure
python3 scripts/test_mobile_android_internal.py --d8 PATH --neverd build/bin/neverd

Komponenten- und CLI-Tests prüfen das Parsen, Ausgabeverträge und die Bereinigung bei Fehlern. Der interne Ausführungsvergleich benötigt ein JDK (java und javac) und D8, um unabhängige DEX/APK-Beispiele zu erstellen und wiederhergestelltes Java zu kompilieren und auszuführen. Dies sind Testabhängigkeiten, keine Laufzeitvoraussetzungen der integrierten Wiederherstellung. Führen Sie ihn mit dem aktuellen Build aus und prüfen Sie die Ergebnisse, bevor Sie einen Fall als verifiziert bezeichnen. Erfolgreiche Beispiele belegen keine vollständige Wiederherstellung beliebiger Anwendungen.

Der zugehörige iOS-Ablauf steht in der Mobilübersicht.