
Android-Virtual-Maschine und Deobfuskator
Simplify führt eine App virtuell aus, um ihr Verhalten zu verstehen, und versucht dann, den Code so zu optimieren, dass er sich identisch verhält, aber für einen Menschen leichter zu verstehen ist. Jeder Optimierungstyp ist einfach und generisch, sodass es keine Rolle spielt, welche spezifische Art der Verschleierung verwendet wird.
Der Code auf der linken Seite ist eine Dekompilierung einer verschleierten App, und der Code auf der rechten Seite wurde entobfuskiert.
Das Projekt besteht aus drei Teilen: smalivm, simplify und der Demo-App.
if- oder switch-Bedingung mit unbekanntem Wert beide Zweige ausgeführt.usage: java -jar simplify.jar <input> [options]
deobfuscates a dalvik executable
-et,--exclude-types <pattern> Exclude classes and methods which include REGEX, eg: "com/android", applied after include-types
-h,--help Display this message
-ie,--ignore-errors Ignore errors while executing and optimizing methods. This may lead to unexpected behavior.
--include-support Attempt to execute and optimize classes in Android support library packages, default: false
-it,--include-types <pattern> Limit execution to classes and methods which include REGEX, eg: ";->targetMethod\("
--max-address-visits <N> Give up executing a method after visiting the same address N times, limits loops, default: 10000
--max-call-depth <N> Do not call methods after reaching a call depth of N, limits recursion and long method chains, default: 50
--max-execution-time <N> Give up executing a method after N seconds, default: 300
--max-method-visits <N> Give up executing a method after executing N instructions in that method, default: 1000000
--max-passes <N> Do not run optimizers on a method more than N times, default: 100
-o,--output <file> Output simplified input to FILE
--output-api-level <LEVEL> Set output DEX API compatibility to LEVEL, default: 15
-q,--quiet Be quiet
--remove-weak Remove code even if there are weak side effects, default: true
-v,--verbose <LEVEL> Set verbosity to LEVEL, default: 0
Zum Erstellen muss das Java Development Kit 8 (JDK) installiert sein.
Da dieses Projekt Submodule für Android-Frameworks enthält, klonen Sie entweder mit --recursive:
git clone --recursive https://github.com/CalebFenton/simplify.git
Oder aktualisieren Sie die Submodule jederzeit mit:
git submodule update --init --recursive
Um dann ein einzelnes JAR zu erstellen, das alle Abhängigkeiten enthält:
./gradlew fatjar
Das Simplify-JAR befindet sich in simplify/build/libs/. Sie können testen, ob es funktioniert, indem Sie die bereitgestellte verschleierte Beispiel-App vereinfachen. So führen Sie es aus (möglicherweise müssen Sie simplify.jar ändern):
java -jar simplify/build/libs/simplify.jar -it "org/cf/obfuscated" -et "MainActivity" simplify/obfuscated-app.apk
Um zu verstehen, was entobfuskiert wird, sehen Sie sich das README der verschleierten App an.
Wenn Simplify fehlschlägt, versuchen Sie diese Empfehlungen in der Reihenfolge:
-it.--max-address-visits, --max-call-depth und --max-method-visits.-v oder -v 2 und melden Sie das Problem mit den Protokollen und einem Hash des DEX oder APK.Wenn unter Windows erstellt wird und der Build mit einem Fehler ähnlich dem folgenden fehlschlägt:
Could not find tools.jar. Please check that C:\Program Files\Java\jre1.8.0_151 contains a valid JDK installation.
Das bedeutet, dass Gradle keinen gültigen JDK-Pfad finden kann. Stellen Sie sicher, dass das JDK installiert ist, setzen Sie die Umgebungsvariable JAVA_HOME auf Ihren JDK-Pfad und schließen und öffnen Sie die Eingabeaufforderung, die Sie zum Erstellen verwenden, erneut.
Seien Sie nicht schüchtern. Ich halte virtuelle Ausführung und Entobfuskation für faszinierende Probleme. Jeder, der interessiert ist, ist automatisch cool, und Beiträge sind willkommen, selbst wenn es nur darum geht, einen Tippfehler zu korrigieren. Stellen Sie gerne Fragen in den Issues und reichen Sie Pull Requests ein.
Bitte fügen Sie einen Link zum APK oder DEX sowie den vollständigen Befehl hinzu, den Sie verwenden. Das erleichtert die Reproduktion (und damit die Behebung) Ihres Problems erheblich.
Wenn Sie das Beispiel nicht teilen können, fügen Sie bitte den Datei-Hash (SHA1, SHA256 usw.) hinzu.
Wenn eine Operation einen Wert eines Typs platziert, der in eine Konstante umgewandelt werden kann, z. B. eine Zeichenkette, Zahl oder Boolean, ersetzt diese Optimierung diese Operation durch die Konstante. Beispiel:
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
# Decrypts to: "Tell me of your homeworld, Usul."
move-result v0
In diesem Beispiel wird eine verschlüsselte Zeichenkette entschlüsselt und in v0 platziert. Da Zeichenketten „konstantisierbar“ sind, kann move-result v0 durch ein const-string ersetzt werden:
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
const-string v0, "Tell me of your homeworld, Usul."