Important
Ce projet est archivé et n'est plus maintenu.
Certaines des questions les plus courantes trouvent leur réponse dans la FAQ et le dépannage.
Un outil d'obscurcissement de boîte noire pour les applications Android.
Obfuscapk est un outil Python modulaire permettant d'obscurcir les applications Android sans avoir besoin de leur code source, car apktool
est utilisé pour décompiler le fichier apk original et pour créer une nouvelle application, après avoir appliqué certaines techniques d'obscurcissement sur le code, les ressources et le manifeste smali
décompilés. L'application obscurcie conserve les mêmes fonctionnalités que l'originale, mais les différences sous le capot rendent parfois la nouvelle application très différente de l'originale (par exemple, pour un logiciel antivirus basé sur les signatures).
Obfuscapk ajoute la prise en charge des Android App Bundles (fichiers aab) en utilisant BundleDecompiler (voir #121). Pour utiliser cette nouvelle fonctionnalité, téléchargez la dernière version de BundleDecompiler disponible ici, enregistrez-la sous BundleDecompiler.jar
dans un répertoire inclus dans PATH
(par exemple, dans Ubuntu, /usr/local/bin
ou /usr/bin
) et créez assurez-vous que l'indicateur exécutable est défini.
Important
BundleDecompiler ne fonctionne pas encore sous Windows, donc l'obscurcissement des bundles d'applications n'est pas pris en charge par Obfuscapk sur la plate-forme Windows. De plus, la prise en charge des app bundles en est encore à ses débuts, donc si vous rencontrez des problèmes ou si vous souhaitez nous aider à nous améliorer, veuillez consulter la contribution.
Plus de détails sur Obfuscapk peuvent être trouvés dans l'article « Obfuscapk : Un outil d'obscurcissement de boîte noire open source pour les applications Android ». Vous pouvez citer l'article comme suit :
@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 est conçu pour être modulaire et facile à étendre, il est donc construit à l'aide d'un système de plugins. Par conséquent, chaque obfuscateur est un plugin qui hérite d'une classe de base abstraite et doit implémenter la méthode obfuscate
. Lorsque l'outil commence à traiter un nouveau fichier d'application Android, il crée un objet d'obfuscation pour stocker toutes les informations nécessaires (par exemple, l'emplacement du code smali
décompilé) et l'état interne des opérations (par exemple, la liste des obfuscateurs déjà utilisés). . Ensuite, l'objet d'obfuscation est transmis, en tant que paramètre à la méthode obfuscate
, à tous les plugins/obfuscateurs actifs (dans l'ordre) pour être traité et modifié. La liste et l'ordre des plugins actifs sont spécifiés via les options de ligne de commande.
L'outil est facilement extensible avec de nouveaux obfuscateurs : il suffit d'ajouter le code source implémentant la technique d'obscurcissement et les métadonnées du plugin (un fichier <obfuscator-name>.obfuscator
) dans le répertoire src/obfuscapk/obfuscators
(prenez un simple obfuscateur existant comme Nop
comme exemple de départ). L'outil détectera automatiquement le nouveau plugin, aucune configuration supplémentaire n'est donc nécessaire (le nouveau plugin sera traité comme tous les autres plugins fournis avec l'outil).
Il existe deux manières d'obtenir une copie de travail d'Obfuscapk sur votre propre ordinateur : soit en utilisant Docker, soit en utilisant directement le code source dans un environnement Python 3
. Dans les deux cas, la première chose à faire est d'obtenir une copie locale de ce référentiel, ouvrez donc un terminal dans le répertoire où vous souhaitez enregistrer le projet et clonez le référentiel :
$ git clone https://github.com/ClaudiuGeorgiu/Obfuscapk.git
C'est la manière suggérée d'installer Obfuscapk, puisque la seule condition requise est d'avoir installé une version récente de Docker :
$ docker --version
Docker version 20.10.21, build baeda1f
L'image Docker officielle d'Obfuscapk est disponible sur Docker Hub (construite automatiquement à partir de ce référentiel) :
$ # Download the Docker image.
$ docker pull claudiugeorgiu/obfuscapk
$ # Give it a shorter name.
$ docker tag claudiugeorgiu/obfuscapk obfuscapk
Si vous avez téléchargé l'image officielle depuis Docker Hub, vous êtes prêt à utiliser l'outil alors allez-y et vérifiez les instructions d'utilisation, sinon exécutez la commande suivante dans le répertoire Obfuscapk/src/
précédemment créé (le dossier contenant le Dockerfile
) pour construire le Image Docker :
$ # 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 .
Lorsque l'image Docker est prête, faites un test rapide pour vérifier que tout a été correctement installé :
$ docker run --rm -it obfuscapk --help
usage: python3 -m obfuscapk.cli [-h] -o OBFUSCATOR [-w DIR] [-d OUT_APK_OR_AAB]
...
Obfuscapk est maintenant prêt à être utilisé, consultez les instructions d'utilisation pour plus d'informations.
Assurez-vous d'avoir une version récente d' apktool
, apksigner
et zipalign
installée et disponible depuis la ligne de commande :
$ 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
...
Pour prendre en charge l'obscurcissement des bundles d'applications, vous avez également besoin de BundleDecompiler, alors téléchargez la dernière version disponible à partir d'ici, enregistrez-la sous BundleDecompiler.jar
dans un répertoire inclus dans PATH
(par exemple, dans Ubuntu, /usr/local/bin
ou /usr/bin
) et assurez-vous que l'indicateur exécutable est défini.
Pour utiliser BundleDecompiler et apktool
vous avez également besoin d'une version récente de Java. zipalign
et apksigner
sont inclus dans le SDK Android. L'emplacement des exécutables peut également être spécifié via les variables d'environnement suivantes : APKTOOL_PATH
, BUNDLE_DECOMPILER_PATH
, APKSIGNER_PATH
et ZIPALIGN_PATH
(par exemple, dans Ubuntu, exécutez export APKTOOL_PATH=/custom/location/apktool
avant d'exécuter Obfuscapk dans le même terminal).
Outre les outils ci-dessus, la seule exigence de ce projet est une installation fonctionnelle Python 3
(au moins 3.7
) (avec son gestionnaire de packages pip
).
Exécutez les commandes suivantes dans le répertoire principal du projet ( Obfuscapk/
) pour installer les dépendances nécessaires :
$ # 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
Une fois les prérequis installés, effectuez un test rapide pour vérifier que tout fonctionne correctement :
$ 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 est maintenant prêt à être utilisé, consultez les instructions d'utilisation pour plus d'informations.
Désormais, Obfuscapk sera considéré comme un exécutable disponible sous obfuscapk
, vous devrez donc adapter les commandes en fonction de la manière dont vous avez installé l'outil :
Image Docker : un répertoire local contenant l'application à obscurcir doit être monté dans /workdir
dans le conteneur (par exemple, le répertoire courant "${PWD}"
), donc la commande :
$ obfuscapk [params...]
devient :
$ docker run --rm -it -u $( id -u ) : $( id -g ) -v " ${PWD} " : " /workdir " obfuscapk [params...]
Depuis les sources : chaque instruction doit être exécutée depuis le répertoire Obfuscapk/src/
(ou en ajoutant le répertoire Obfuscapk/src/
à la variable d'environnement PYTHONPATH
) et la commande :
$ obfuscapk [params...]
devient :
$ python3 -m obfuscapk.cli [params...]
Commençons par regarder le message d'aide :
$ 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 >
Il y a deux paramètres obligatoires : <APK_OR_BUNDLE_FILE>
, le chemin (relatif ou absolu) vers le fichier apk ou app bundle à obscurcir et la liste des noms des techniques d'obscurcissement à appliquer (spécifiées avec une option -o
qui peut être utilisée plusieurs fois). fois, par exemple, -o Rebuild -o NewAlignment -o NewSignature
). Les autres arguments facultatifs sont les suivants :
-w DIR
est utilisé pour définir le répertoire de travail où enregistrer les fichiers intermédiaires (générés par apktool
). S'il n'est pas spécifié, un répertoire nommé obfuscation_working_dir
est créé dans le même répertoire que l'application d'entrée. Cela peut être utile à des fins de débogage, mais si ce n'est pas nécessaire, il peut être défini dans un répertoire temporaire (par exemple, -w /tmp/
).
-d OUT_APK_OR_AAB
est utilisé pour définir le chemin du fichier de destination : le fichier apk généré par le processus d'obscurcissement (par exemple, -d /home/user/Desktop/obfuscated.apk
ou -d /home/user/Desktop/obfuscated.aab
). S'il n'est pas spécifié, le fichier final obscurci sera enregistré dans le répertoire de travail. Remarque : les fichiers existants seront écrasés sans aucun avertissement.
-i
est un indicateur permettant d'ignorer les bibliothèques tierces connues pendant le processus d'obscurcissement, d'utiliser moins de ressources, d'augmenter les performances et de réduire le risque d'erreurs. La liste des bibliothèques à ignorer est adaptée du projet LiteRadar.
-p
est un indicateur permettant d'afficher des barres de progression pendant les opérations d'obscurcissement. Lorsque vous utilisez l'outil dans des opérations par lots/constructions automatiques, il est pratique de désactiver les barres de progression, sinon cet indicateur doit être activé pour voir la progression de l'obscurcissement.
-k VT_API_KEY
est nécessaire uniquement lors de l'utilisation de l'obfuscateur VirusTotal
, pour définir la clé API à utiliser lors de la communication avec Virus Total.
--keystore-file KEYSTORE_FILE
, --keystore-password KEYSTORE_PASSWORD
, --key-alias KEY_ALIAS
et --key-password KEY_PASSWORD
peuvent être utilisés pour spécifier un magasin de clés personnalisé (nécessaire pour la signature de l'apk). Si --keystore-file
est utilisé, --keystore-password
et --key-alias
doivent également être spécifiés, tandis que --key-password
n'est nécessaire que si la clé choisie a un mot de passe différent de celui du magasin de clés. Par défaut (lorsque --keystore-file
n'est pas spécifié), un magasin de clés fourni avec Obfuscapk est utilisé pour les opérations de signature.
--ignore-packages-file IGNORE_PACKAGES_FILE
est un chemin vers un fichier qui inclut les noms de packages à ignorer. Toutes les classes de ces packages ne seront pas obscurcies lorsque cette option est utilisée. Le fichier doit avoir un nom de package par ligne, comme indiqué dans l'exemple ci-dessous :
com.mycompany.dontobfuscate
com.mycompany.ignore
...
--use-aapt2
est un indicateur permettant d'utiliser l'option aapt2 lors de la reconstruction d'une application avec apktool
.
Considérons maintenant un exemple simple pour voir comment fonctionne Obfuscapk :
$ # original.apk is a valid Android apk file.
$ obfuscapk -o RandomManifest -o Rebuild -o NewAlignment -o NewSignature original.apk
Lors de l'exécution de la commande ci-dessus, voici ce qui se passe en coulisse :
puisqu'aucun répertoire de travail n'a été spécifié, un nouveau répertoire de travail ( obfuscation_working_dir
) est créé au même emplacement que original.apk
(cela peut être utile pour inspecter les smali
fichiers/manifestes/ressources en cas d'erreurs)
certaines vérifications sont effectuées pour s'assurer que tous les fichiers/exécutables nécessaires sont disponibles et prêts à être utilisés
le processus d'obfuscation proprement dit commence : les obfuscateurs spécifiés sont exécutés (dans l'ordre) un par un jusqu'à ce qu'il ne reste plus d'obfuscateur ou jusqu'à ce qu'une erreur soit rencontrée
lors de l'exécution du premier obfuscateur, original.apk
est décompilé avec apktool
et les résultats sont stockés dans le répertoire de travail
puisque le premier obfuscateur est RandomManifest
, les entrées du manifeste Android décompilé sont réorganisées de manière aléatoire (sans casser les structures xml
)
Rebuild
obfuscator reconstruit simplement l'application (maintenant avec le manifeste modifié) à l'aide apktool
, et comme aucun fichier de sortie n'a été spécifié, le fichier apk résultant est enregistré dans le répertoire de travail créé auparavant.
L'obfuscateur NewAlignment
utilise l'outil zipalign
pour aligner le fichier apk résultant
L'obfuscateur NewSignature
signe le fichier apk nouvellement créé avec un certificat personnalisé contenu dans un magasin de clés fourni avec Obfuscapk (bien qu'un magasin de clés différent puisse être spécifié avec le paramètre --keystore-file
)
lorsque tous les obfuscateurs ont été exécutés sans erreur, le fichier apk obfusqué résultant peut être trouvé dans obfuscation_working_dir/original_obfuscated.apk
, signé, aligné et prêt à être installé dans un appareil/émulateur
Comme vu dans l'exemple précédent, les obfuscateurs Rebuild
, NewAlignment
et NewSignature
sont toujours nécessaires pour terminer une opération d'obscurcissement, afin de créer l'apk obscurci final. Ce ne sont pas de véritables techniques d'obfuscation, mais elles sont nécessaires dans le processus de construction, elles sont donc incluses dans la liste des obfuscateurs pour garder l'architecture globale modulaire.
Cela ne fonctionne pas comme prévu ? Voir FAQ et dépannage.
Les obfuscateurs inclus dans Obfuscapk peuvent être divisés en différentes catégories, en fonction des opérations qu'ils effectuent :
Trivial : comme son nom l'indique, cette catégorie regroupe des opérations simples (qui ne modifient pas beaucoup l'application d'origine), comme signer le fichier apk avec une nouvelle signature.
Renommer : opérations qui changent les noms des identifiants utilisés (classes, champs, méthodes).
Chiffrement : empaqueter le code/les ressources chiffrées et les déchiffrer lors de l'exécution de l'application. Lorsque Obfuscapk démarre, il génère automatiquement une clé secrète aléatoire (32 caractères, utilisant des lettres et des chiffres ASCII) qui sera utilisée pour le cryptage.
Code : toutes les opérations qui impliquent la modification du code source décompilé.
Ressources : opérations sur les fichiers ressources (comme modifier le manifeste).
Autre
Les obfuscateurs actuellement fournis avec Obfuscapk sont brièvement présentés ci-dessous (par ordre alphabétique). Veuillez vous référer au code source du projet pour plus de détails.
Conseil
Tous les obfuscateurs ci-dessous ne correspondent pas à de véritables techniques d'obscurcissement (par exemple, Rebuild
, NewAlignment
, NewSignature
et VirusTotal
), mais ils sont implémentés en tant qu'obfuscateurs pour garder l'architecture modulaire et facile à étendre avec de nouvelles fonctionnalités.
Utilise la réflexion pour appeler les API dangereuses du framework Android. Pour savoir si une méthode appartient au Framework Android, Obfuscapk fait référence au mapping découvert par Backes et al.
? Code source de réflexion avancée
Insérez le code indésirable. Dans ce cas, le code indésirable est composé de calculs arithmétiques et d'une instruction de branchement en fonction du résultat de ces calculs, conçue de telle manière que le branchement n'est jamais effectué.
? Code source de la branche arithmétique
Chiffrez les fichiers d'actifs.
? Code source d'AssetEncryption
Cette technique modifie le graphe de flux de contrôle sans impacter la sémantique du code : elle ajoute de nouvelles méthodes qui invoquent celles d'origine. Par exemple, un appel à la méthode m1 sera remplacé par une nouvelle méthode wrapper m2 , qui, lorsqu'elle est invoquée, appelle la méthode d'origine m1 .
? Code source d'appelIndirection
Modifiez le nom du package et renommez les classes (même dans le fichier manifeste).
? Code source de ClasseRenommer
Chiffrez les chaînes constantes dans le code.
? Code source de ConstStringEncryption
Supprimez les informations de débogage.
? Code source de DebugRemoval
Renommez les champs.
? Code source de FieldRename
Étant donné une méthode, il insère une instruction
goto
pointant vers la fin de la méthode et une autregoto
pointant vers l'instruction après la premièregoto
; il modifie le graphe de flux de contrôle en ajoutant deux nouveaux nœuds.
? Aller au code source
Chiffrez les bibliothèques natives.
? Code source de LibEncryption
Il exploite la fonctionnalité de surcharge du langage de programmation Java pour attribuer le même nom à différentes méthodes mais en utilisant des arguments différents. Étant donné une méthode déjà existante, cette technique crée une nouvelle méthode void avec le même nom et les mêmes arguments, mais elle ajoute également de nouveaux arguments aléatoires. Ensuite, le corps de la nouvelle méthode est rempli d’instructions arithmétiques aléatoires.
? Code source de surcharge de méthode
Renommez les méthodes.
? MéthodeRenommer le code source
Réalignez l'application.
? Code source du nouvel alignement
Signez à nouveau l'application avec une nouvelle signature personnalisée.
? Code source de la nouvelle signature
Insérez le code indésirable. Nop, abréviation de no-opération , est une instruction dédiée qui ne fait rien. Cette technique insère simplement des instructions
nop
aléatoires dans chaque implémentation de méthode.
? Pas de code source
Réorganisez de manière aléatoire les entrées dans le fichier manifeste.
? Code source du Manifeste aléatoire
Reconstruisez l'application.
? Reconstruire le code source
Cette technique analyse le code existant à la recherche d'invocations de méthodes de l'application, en ignorant les appels au framework Android (voir
AdvancedReflection
). S'il trouve une instruction avec une invocation de méthode appropriée (c'est-à-dire aucune méthode de constructeur, visibilité publique, suffisamment de registres libres, etc.), cette invocation est redirigée vers une méthode personnalisée qui invoquera la méthode d'origine à l'aide des API Reflection.
? Code source de réflexion
Cette technique consiste à changer l'ordre des blocs de base dans le code. Lorsqu'une instruction de branchement est trouvée, la condition est inversée (par exemple, branchement s'il est inférieur à , devient branchement s'il est supérieur ou égal à ) et les blocs de base cibles sont réorganisés en conséquence. De plus, il réorganise également le code de manière aléatoire en abusant des instructions
goto
.
? Réorganiser le code source
Chiffrez les chaînes dans les ressources (uniquement celles appelées dans le code).
? Code source de ResStringEncryption
Envoyez l'original et l'application masquée à Virus Total. Vous devez fournir la clé API VT (voir l'option
-k
).
? Code source de VirusTotal
Vous êtes libre d'utiliser ce code sous la licence MIT.
Ce logiciel a été développé à des fins de recherche au Computer Security Lab (CSecLab), hébergé au DIBRIS, Université de Gênes.