Wichtig
Dieses Projekt ist archiviert und wird nicht mehr gepflegt.
Einige der häufigsten Fragen werden in den FAQ und Fehlerbehebung beantwortet.
Ein Black-Box-Verschleierungstool für Android-Apps.
Obfuscapk ist ein modulares Python-Tool zum Verschleiern von Android-Apps, ohne deren Quellcode zu benötigen, da apktool
zum Dekompilieren der ursprünglichen APK-Datei und zum Erstellen einer neuen Anwendung verwendet wird, nachdem einige Verschleierungstechniken auf den dekompilierten smali
Code, die Ressourcen und das Manifest angewendet wurden. Die verschleierte App behält die gleiche Funktionalität wie die ursprüngliche, aber die Unterschiede unter der Haube führen manchmal dazu, dass sich die neue Anwendung stark vom Original unterscheidet (z. B. bei signaturbasierter Antivirensoftware).
Obfuscapk fügt Unterstützung für Android App Bundles (AAB-Dateien) mithilfe von BundleDecompiler hinzu (siehe Nr. 121). Um diese neue Funktion zu nutzen, laden Sie die neueste Version von BundleDecompiler herunter, die hier verfügbar ist, speichern Sie sie als BundleDecompiler.jar
in einem in PATH
enthaltenen Verzeichnis (z. B. in Ubuntu /usr/local/bin
oder /usr/bin
) und erstellen Sie sie Stellen Sie sicher, dass das Flag „Ausführbare Datei“ gesetzt ist.
Wichtig
BundleDecompiler funktioniert noch nicht unter Windows, daher wird die Verschleierung von App-Bundles von Obfuscapk auf der Windows-Plattform nicht unterstützt. Außerdem befindet sich die App-Bundle-Unterstützung noch in der frühen Entwicklungsphase. Wenn Sie also auf Probleme stoßen oder uns bei der Verbesserung helfen möchten, lesen Sie bitte „Mitwirken“.
Weitere Details zu Obfuscapk finden Sie im Artikel „Obfuscapk: Ein Open-Source- Black-Box-Obfuscation-Tool für Android-Apps“. Sie können den Beitrag wie folgt zitieren:
@article { aonzo2020obfuscapk ,
title = " Obfuscapk: An open-source black-box obfuscation tool for Android apps " ,
journal = " SoftwareX " ,
volume = " 11 " ,
pages = " 100403 " ,
year = " 2020 " ,
issn = " 2352-7110 " ,
doi = " https://doi.org/10.1016/j.softx.2020.100403 " ,
url = " https://www.sciencedirect.com/science/article/pii/S2352711019302791 " ,
author = " Simone Aonzo and Gabriel Claudiu Georgiu and Luca Verderame and Alessio Merlo " ,
keywords = " Android, Obfuscation, Program analysis "
}
Obfuscapk ist modular und leicht erweiterbar konzipiert und basiert daher auf einem Plugin-System. Folglich ist jeder Obfuscator ein Plugin, das von einer abstrakten Basisklasse erbt und die Methode obfuscate
implementieren muss. Wenn das Tool mit der Verarbeitung einer neuen Android-Anwendungsdatei beginnt, erstellt es ein Verschleierungsobjekt, um alle erforderlichen Informationen (z. B. den Speicherort des dekompilierten smali
-Codes) und den internen Status der Vorgänge (z. B. die Liste der bereits verwendeten Verschleierungsfunktionen) zu speichern. . Anschließend wird das Obfuskationsobjekt als Parameter an die obfuscate
-Methode an alle aktiven Plugins/Obfuscators (nacheinander) übergeben, um sie zu verarbeiten und zu ändern. Die Liste und die Reihenfolge der aktiven Plugins wird über Befehlszeilenoptionen festgelegt.
Das Tool ist leicht mit neuen Obfuscators erweiterbar: Es reicht aus, den Quellcode, der die Obfuscator-Technik implementiert, und die Plugin-Metadaten (eine <obfuscator-name>.obfuscator
Datei) im Verzeichnis src/obfuscapk/obfuscators
hinzuzufügen (nehmen Sie einen einfachen vorhandenen Obfuscator wie Nop
als Ausgangsbeispiel). Das Tool erkennt das neue Plugin automatisch, sodass keine weitere Konfiguration erforderlich ist (das neue Plugin wird wie alle anderen mit dem Tool gebündelten Plugins behandelt).
Es gibt zwei Möglichkeiten, eine Arbeitskopie von Obfuscapk auf den eigenen Computer zu bekommen: entweder durch die Verwendung von Docker oder durch die direkte Verwendung des Quellcodes in einer Python 3
-Umgebung. In beiden Fällen müssen Sie zunächst eine lokale Kopie dieses Repositorys erstellen. Öffnen Sie also ein Terminal in dem Verzeichnis, in dem Sie das Projekt speichern möchten, und klonen Sie das Repository:
$ git clone https://github.com/ClaudiuGeorgiu/Obfuscapk.git
Dies ist die empfohlene Methode zur Installation von Obfuscapk, da die einzige Voraussetzung darin besteht, eine aktuelle Version von Docker installiert zu haben:
$ docker --version
Docker version 20.10.21, build baeda1f
Das offizielle Obfuscapk-Docker-Image ist auf Docker Hub verfügbar (wird automatisch aus diesem Repository erstellt):
$ # Download the Docker image.
$ docker pull claudiugeorgiu/obfuscapk
$ # Give it a shorter name.
$ docker tag claudiugeorgiu/obfuscapk obfuscapk
Wenn Sie das offizielle Image von Docker Hub heruntergeladen haben, können Sie das Tool verwenden. Lesen Sie sich also zunächst die Gebrauchsanweisungen durch. Andernfalls führen Sie den folgenden Befehl im zuvor erstellten Obfuscapk/src/
-Verzeichnis (dem Ordner mit der Dockerfile
) aus, um das zu erstellen Docker-Image:
$ # Make sure to run the command in Obfuscapk/src/ directory.
$ # It will take some time to download and install all the dependencies.
$ docker build -t obfuscapk .
Wenn das Docker-Image fertig ist, führen Sie einen kurzen Test durch, um zu überprüfen, ob alles korrekt installiert wurde:
$ docker run --rm -it obfuscapk --help
usage: python3 -m obfuscapk.cli [-h] -o OBFUSCATOR [-w DIR] [-d OUT_APK_OR_AAB]
...
Obfuscapk ist jetzt einsatzbereit. Weitere Informationen finden Sie in der Gebrauchsanweisung.
Stellen Sie sicher, dass eine aktuelle Version von apktool
, apksigner
und zipalign
installiert und über die Befehlszeile verfügbar ist:
$ apktool
Apktool v2.9.0 - a tool for reengineering Android apk files
...
$ apksigner
Usage: apksigner < command > [options]
apksigner --version
apksigner --help
...
$ zipalign
Zip alignment utility
Copyright (C) 2009 The Android Open Source Project
...
Um die Verschleierung von App-Bundles zu unterstützen, benötigen Sie auch BundleDecompiler. Laden Sie also die neueste verfügbare Version hier herunter, speichern Sie sie als BundleDecompiler.jar
in einem in PATH
enthaltenen Verzeichnis (z. B. in Ubuntu /usr/local/bin
oder /usr/bin
) und Stellen Sie sicher, dass das Flag „Ausführbare Datei“ gesetzt ist.
Um BundleDecompiler und apktool
nutzen zu können, benötigen Sie außerdem eine aktuelle Version von Java. zipalign
und apksigner
sind im Android SDK enthalten. Der Speicherort der ausführbaren Dateien kann auch über die folgenden Umgebungsvariablen angegeben werden: APKTOOL_PATH
, BUNDLE_DECOMPILER_PATH
, APKSIGNER_PATH
und ZIPALIGN_PATH
(z. B. führen Sie in Ubuntu export APKTOOL_PATH=/custom/location/apktool
aus, bevor Sie Obfuscapk im selben Terminal ausführen).
Abgesehen von den oben genannten Tools ist die einzige Voraussetzung für dieses Projekt eine funktionierende Python 3
Installation (mindestens 3.7
) (zusammen mit dem Paketmanager pip
).
Führen Sie die folgenden Befehle im Hauptverzeichnis des Projekts ( Obfuscapk/
) aus, um die erforderlichen Abhängigkeiten zu installieren:
$ # Make sure to run the commands in Obfuscapk/ directory.
$ # The usage of a virtual environment is highly recommended.
$ python3 -m venv venv
$ source venv/bin/activate
$ # Install Obfuscapk's requirements.
$ python3 -m pip install -r src/requirements.txt
Führen Sie nach der Installation der Anforderungen einen kurzen Test durch, um zu überprüfen, ob alles ordnungsgemäß funktioniert:
$ cd src/
$ # The following command has to be executed always from Obfuscapk/src/ directory
$ # or by adding Obfuscapk/src/ directory to PYTHONPATH environment variable.
$ python3 -m obfuscapk.cli --help
usage: python3 -m obfuscapk.cli [-h] -o OBFUSCATOR [-w DIR] [-d OUT_APK_OR_AAB]
...
Obfuscapk ist jetzt einsatzbereit. Weitere Informationen finden Sie in der Gebrauchsanweisung.
Von nun an wird Obfuscapk als ausführbare Datei betrachtet, die als obfuscapk
verfügbar ist. Daher müssen Sie die Befehle entsprechend der Installation des Tools anpassen:
Docker-Image : Ein lokales Verzeichnis, das die zu verschleiernde Anwendung enthält, muss in /workdir
im Container gemountet werden (z. B. das aktuelle Verzeichnis "${PWD}"
), also der Befehl:
$ obfuscapk [params...]
wird:
$ docker run --rm -it -u $( id -u ) : $( id -g ) -v " ${PWD} " : " /workdir " obfuscapk [params...]
Aus der Quelle : Jede Anweisung muss aus dem Obfuscapk/src/
-Verzeichnis (oder durch Hinzufügen Obfuscapk/src/
-Verzeichnisses zur PYTHONPATH
Umgebungsvariablen) und dem folgenden Befehl ausgeführt werden:
$ obfuscapk [params...]
wird:
$ python3 -m obfuscapk.cli [params...]
Schauen wir uns zunächst die Hilfemeldung an:
$ obfuscapk --help
obfuscapk [-h] -o OBFUSCATOR [-w DIR] [-d OUT_APK_OR_AAB] [-i] [-p] [-k VT_API_KEY]
[--keystore-file KEYSTORE_FILE] [--keystore-password KEYSTORE_PASSWORD]
[--key-alias KEY_ALIAS] [--key-password KEY_PASSWORD] [--use-aapt2]
< APK_OR_BUNDLE_FILE >
Es gibt zwei obligatorische Parameter: <APK_OR_BUNDLE_FILE>
, den Pfad (relativ oder absolut) zur APK- oder App-Bundle-Datei, die verschleiert werden soll, und die Liste mit den Namen der anzuwendenden Verschleierungstechniken (angegeben mit der Option -o
, die mehrfach verwendet werden kann). mal, z. B. -o Rebuild -o NewAlignment -o NewSignature
). Die anderen optionalen Argumente lauten wie folgt:
-w DIR
wird verwendet, um das Arbeitsverzeichnis festzulegen, in dem die Zwischendateien (generiert von apktool
) gespeichert werden sollen. Wenn nicht angegeben, wird ein Verzeichnis mit dem Namen obfuscation_working_dir
im selben Verzeichnis wie die Eingabeanwendung erstellt. Dies kann für Debugging-Zwecke nützlich sein, aber wenn es nicht benötigt wird, kann es auf ein temporäres Verzeichnis gesetzt werden (z. B. -w /tmp/
).
-d OUT_APK_OR_AAB
wird verwendet, um den Pfad der Zieldatei festzulegen: die durch den Verschleierungsprozess generierte APK-Datei (z. B. -d /home/user/Desktop/obfuscated.apk
oder -d /home/user/Desktop/obfuscated.aab
). Wenn nicht angegeben, wird die endgültige verschleierte Datei im Arbeitsverzeichnis gespeichert. Hinweis: Vorhandene Dateien werden ohne Vorwarnung überschrieben.
-i
ist ein Flag zum Ignorieren bekannter Bibliotheken von Drittanbietern während des Verschleierungsvorgangs, um weniger Ressourcen zu verbrauchen, die Leistung zu steigern und das Fehlerrisiko zu verringern. Die Liste der zu ignorierenden Bibliotheken wurde aus dem LiteRadar-Projekt übernommen.
-p
ist ein Flag zum Anzeigen von Fortschrittsbalken während der Verschleierungsvorgänge. Wenn Sie das Tool in Batch-Vorgängen/automatischen Builds verwenden, ist es praktisch, die Fortschrittsbalken zu deaktivieren. Andernfalls sollte dieses Flag aktiviert sein, um den Verschleierungsfortschritt anzuzeigen.
-k VT_API_KEY
wird nur benötigt, wenn der VirusTotal
Obfuscator verwendet wird, um den API-Schlüssel festzulegen, der bei der Kommunikation mit Virus Total verwendet werden soll.
--keystore-file KEYSTORE_FILE
, --keystore-password KEYSTORE_PASSWORD
, --key-alias KEY_ALIAS
und --key-password KEY_PASSWORD
können verwendet werden, um einen benutzerdefinierten Keystore anzugeben (erforderlich für die APK-Signierung). Wenn --keystore-file
verwendet wird, müssen auch --keystore-password
und --key-alias
angegeben werden, während --key-password
nur erforderlich ist, wenn der ausgewählte Schlüssel ein anderes Passwort als das Keystore-Passwort hat. Standardmäßig (wenn --keystore-file
nicht angegeben ist) wird ein mit Obfuscapk gebündelter Keystore für die Signierungsvorgänge verwendet.
--ignore-packages-file IGNORE_PACKAGES_FILE
ist ein Pfad zu einer Datei, die zu ignorierende Paketnamen enthält. Alle Klassen in diesen Paketen werden nicht verschleiert, wenn diese Option verwendet wird. Die Datei sollte einen Paketnamen pro Zeile haben, wie im folgenden Beispiel gezeigt:
com.mycompany.dontobfuscate
com.mycompany.ignore
...
--use-aapt2
ist ein Flag für die Verwendung der Option aapt2 beim Neuerstellen einer App mit apktool
.
Betrachten wir nun ein einfaches Arbeitsbeispiel, um zu sehen, wie Obfuscapk funktioniert:
$ # original.apk is a valid Android apk file.
$ obfuscapk -o RandomManifest -o Rebuild -o NewAlignment -o NewSignature original.apk
Wenn Sie den obigen Befehl ausführen, geschieht Folgendes im Hintergrund:
Da kein Arbeitsverzeichnis angegeben wurde, wird ein neues Arbeitsverzeichnis ( obfuscation_working_dir
) am selben Ort wie original.apk
erstellt (dies kann nützlich sein, um im Fehlerfall die smali
Dateien/Manifest/Ressourcen zu überprüfen).
Es werden einige Prüfungen durchgeführt, um sicherzustellen, dass alle benötigten Dateien/ausführbaren Dateien verfügbar und einsatzbereit sind
Der eigentliche Verschleierungsprozess beginnt: Die angegebenen Verschleierer werden (in der Reihenfolge) einer nach dem anderen ausgeführt, bis kein Verschleierer mehr vorhanden ist oder bis ein Fehler auftritt
Beim Ausführen des ersten Obfuscators wird original.apk
mit apktool
dekompiliert und die Ergebnisse im Arbeitsverzeichnis gespeichert
Da der erste Obfuscator RandomManifest
ist, werden die Einträge im dekompilierten Android-Manifest zufällig neu angeordnet (ohne die xml
Strukturen zu beschädigen).
Rebuild
Obfuscator erstellt einfach die Anwendung (jetzt mit dem geänderten Manifest) mithilfe von apktool
neu. Da keine Ausgabedatei angegeben wurde, wird die resultierende APK-Datei im zuvor erstellten Arbeitsverzeichnis gespeichert
NewAlignment
Obfuscator verwendet das zipalign
Tool, um die resultierende APK-Datei auszurichten
NewSignature
Obfuscator signiert die neu erstellte APK-Datei mit einem benutzerdefinierten Zertifikat, das in einem mit Obfuscapk gebündelten Keystore enthalten ist (obwohl ein anderer Keystore mit dem Parameter --keystore-file
angegeben werden kann).
Wenn alle Verschleierer fehlerfrei ausgeführt wurden, befindet sich die resultierende verschleierte APK-Datei im obfuscation_working_dir/original_obfuscated.apk
, signiert, ausgerichtet und bereit zur Installation auf einem Gerät/Emulator
Wie im vorherigen Beispiel zu sehen ist, werden die Verschleierungsfunktionen Rebuild
, NewAlignment
und NewSignature
immer benötigt, um einen Verschleierungsvorgang abzuschließen und die endgültige verschleierte APK zu erstellen. Dabei handelt es sich nicht um eigentliche Verschleierungstechniken, sie werden jedoch im Build-Prozess benötigt und sind daher in der Liste der Verschleierungsfunktionen enthalten, um die Gesamtarchitektur modular zu halten.
Funktioniert nicht wie erwartet? Siehe FAQ und Fehlerbehebung.
Die in Obfuscapk enthaltenen Obfuskatoren können je nach den von ihnen ausgeführten Operationen in verschiedene Kategorien unterteilt werden:
Trivial : Wie der Name schon sagt, umfasst diese Kategorie einfache Vorgänge (die die ursprüngliche Anwendung kaum verändern), wie das Signieren der APK-Datei mit einer neuen Signatur.
Umbenennen : Operationen, die die Namen der verwendeten Bezeichner (Klassen, Felder, Methoden) ändern.
Verschlüsselung : Verschlüsselter Code/verschlüsselte Ressourcen packen und während der App-Ausführung entschlüsseln. Wenn Obfuscapk startet, generiert es automatisch einen zufälligen geheimen Schlüssel (32 Zeichen lang, mit ASCII-Buchstaben und Ziffern), der zur Verschlüsselung verwendet wird.
Code : alle Vorgänge, die die Änderung des dekompilierten Quellcodes beinhalten.
Ressourcen : Vorgänge an den Ressourcendateien (z. B. Ändern des Manifests).
Andere
Die derzeit mit Obfuscapk gebündelten Obfuscators werden im Folgenden kurz vorgestellt (in alphabetischer Reihenfolge). Weitere Informationen finden Sie im Quellcode des Projekts.
Tipp
Nicht alle unten aufgeführten Obfuskatoren entsprechen echten Verschleierungstechniken (z. B. Rebuild
, NewAlignment
, NewSignature
und VirusTotal
), aber sie werden als Obfuskatoren implementiert, um die Architektur modular zu halten und eine einfache Erweiterung um neue Funktionen zu ermöglichen.
Verwendet Reflection, um gefährliche APIs des Android Framework aufzurufen. Um herauszufinden, ob eine Methode zum Android Framework gehört, greift Obfuscapk auf das von Backes et al. entdeckte Mapping zurück.
? AdvancedReflection-Quellcode
Junk-Code einfügen. In diesem Fall besteht der Junk-Code aus arithmetischen Berechnungen und einer vom Ergebnis dieser Berechnungen abhängigen Verzweigungsanweisung, die so gestaltet ist, dass die Verzweigung niemals durchgeführt wird.
? ArithmeticBranch-Quellcode
Asset-Dateien verschlüsseln.
? AssetEncryption-Quellcode
Diese Technik ändert den Kontrollflussgraphen, ohne die Codesemantik zu beeinträchtigen: Sie fügt neue Methoden hinzu, die die ursprünglichen aufrufen. Beispielsweise wird ein Aufruf der Methode m1 durch eine neue Wrapper-Methode m2 ersetzt, die beim Aufruf die ursprüngliche Methode m1 aufruft.
? CallIndirection-Quellcode
Ändern Sie den Paketnamen und benennen Sie Klassen um (auch in der Manifestdatei).
? ClassRename-Quellcode
Verschlüsseln Sie konstante Zeichenfolgen im Code.
? ConstStringEncryption-Quellcode
Debug-Informationen entfernen.
? DebugRemoval-Quellcode
Felder umbenennen.
? FieldRename-Quellcode
Bei einer gegebenen Methode fügt es eine
goto
-Anweisung ein, die auf das Ende der Methode zeigt, und eine weiteregoto
Anweisung, die auf die Anweisung nach dem erstengoto
zeigt. Es ändert das Kontrollflussdiagramm, indem es zwei neue Knoten hinzufügt.
? Gehe zum Quellcode
Verschlüsseln Sie native Bibliotheken.
? LibEncryption-Quellcode
Es nutzt die Überladungsfunktion der Programmiersprache Java aus, um verschiedenen Methoden denselben Namen zuzuweisen, jedoch unterschiedliche Argumente zu verwenden. Bei einer bereits vorhandenen Methode erstellt diese Technik eine neue void-Methode mit demselben Namen und denselben Argumenten, fügt jedoch auch neue zufällige Argumente hinzu. Anschließend wird der Hauptteil der neuen Methode mit zufälligen arithmetischen Anweisungen gefüllt.
? MethodOverload-Quellcode
Methoden umbenennen.
? MethodeQuellcode umbenennen
Richten Sie die Anwendung neu aus.
? NewAlignment-Quellcode
Signieren Sie die Anwendung erneut mit einer neuen benutzerdefinierten Signatur.
? NewSignature-Quellcode
Junk-Code einfügen. Nop, die Abkürzung für „no-operation“ , ist eine dedizierte Anweisung, die nichts bewirkt. Diese Technik fügt einfach zufällige
nop
-Anweisungen in jede Methodenimplementierung ein.
? Nein, Quellcode
Einträge in der Manifestdatei nach dem Zufallsprinzip neu anordnen.
? RandomManifest-Quellcode
Erstellen Sie die Anwendung neu.
? Quellcode neu erstellen
Diese Technik analysiert den vorhandenen Code auf der Suche nach Methodenaufrufen der App und ignoriert dabei die Aufrufe des Android-Frameworks (siehe
AdvancedReflection
). Wenn eine Anweisung mit einem geeigneten Methodenaufruf gefunden wird (z. B. keine Konstruktormethoden, öffentliche Sichtbarkeit, genügend freie Register usw.), wird dieser Aufruf an eine benutzerdefinierte Methode umgeleitet, die die ursprüngliche Methode mithilfe der Reflection-APIs aufruft.
? Reflection-Quellcode
Diese Technik besteht darin, die Reihenfolge der Grundblöcke im Code zu ändern. Wenn eine Verzweigungsanweisung gefunden wird, wird die Bedingung invertiert (z. B. Verzweigung, wenn kleiner als , wird Verzweigung, wenn größer oder gleich als ), und die Zielbasisblöcke werden entsprechend neu angeordnet. Darüber hinaus wird der Code unter Missbrauch
goto
-Anweisungen zufällig neu angeordnet.
? Quellcode neu anordnen
Verschlüsseln Sie Zeichenfolgen in Ressourcen (nur diejenigen, die im Code aufgerufen werden).
? ResStringEncryption-Quellcode
Senden Sie das Original und den verschleierten Antrag an Virus Total. Sie müssen den VT-API-Schlüssel angeben (siehe Option
-k
).
? VirusTotal-Quellcode
Es steht Ihnen frei, diesen Code unter der MIT-Lizenz zu verwenden.
Diese Software wurde zu Forschungszwecken im Computer Security Lab (CSecLab) am DIBRIS der Universität Genua entwickelt.