
Инструмент автоматической обфускации для Android-приложений, работающий по принципу «чёрного ящика», поддерживающий продвинутые функции обфускации и имеющий модульную архитектуру, легко расширяемую новыми методами.
[!IMPORTANT] Этот проект архивирован и больше не поддерживается.
Ответы на некоторые наиболее частые вопросы можно найти в FAQ и разделе по устранению неполадок.

Инструмент обфускации Android-приложений методом «чёрного ящика».
Obfuscapk — это модульный инструмент на Python для обфускации Android-приложений без необходимости
исходного кода, поскольку apktool используется
для декомпиляции исходного apk-файла и сборки нового приложения после применения некоторых
методов обфускации к декомпилированному коду smali, ресурсам и манифесту. Обфусцированное
приложение сохраняет ту же функциональность, что и исходное, но различия
под капотом иногда делают новое приложение очень отличным от исходного
(например, для антивирусного ПО, основанного на сигнатурах).
Obfuscapk добавляет поддержку
Android App Bundle (файлов aab) с помощью
BundleDecompiler (см.
#121). Чтобы воспользоваться этой новой
функцией, загрузите последнюю версию BundleDecompiler, доступную
здесь,
сохраните её как BundleDecompiler.jar в каталоге, включённом в PATH (например, в Ubuntu
/usr/local/bin или /usr/bin) и убедитесь, что у файла установлен флаг исполняемого.
[!IMPORTANT] BundleDecompiler пока не работает в Windows, поэтому обфускация app bundle не поддерживается Obfuscapk на платформе Windows. Кроме того, поддержка app bundle всё ещё находится на ранней стадии разработки, поэтому если вы столкнулись с какими-либо проблемами или хотите помочь нам улучшить, пожалуйста, ознакомьтесь с разделом участия в разработке.
Более подробная информация об Obfuscapk содержится в статье "Obfuscapk: An open-source black-box obfuscation tool for Android apps". Вы можете процитировать статью следующим образом:```BibTeX @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 спроектирован так, чтобы быть модульным и легко расширяемым, поэтому он построен на
[системе плагинов](https://github.com/tibonihoo/yapsy). Следовательно, каждый обфускатор —
это плагин, наследующий от абстрактного
[базового класса](https://github.com/ClaudiuGeorgiu/Obfuscapk/blob/master/src/obfuscapk/obfuscator_category.py)
и должен реализовывать метод `obfuscate`. Когда инструмент начинает обработку нового
файла приложения Android, он создаёт
[объект обфускации](https://github.com/ClaudiuGeorgiu/Obfuscapk/blob/master/src/obfuscapk/obfuscation.py)
для хранения всей необходимой информации (например, местоположения декомпилированного кода `smali`)
и внутреннего состояния операций (например, списка уже использованных обфускаторов).
Затем объект обфускации передаётся в качестве параметра в метод `obfuscate` всем
активным плагинам/обфускаторам (последовательно) для обработки и модификации. Список и
порядок активных плагинов задаётся через [параметры командной строки](#-использование).
Инструмент легко расширяется новыми обфускаторами: достаточно добавить исходный код,
реализующий технику обфускации, и метаданные плагина (файл
`<имя-обфускатора>.obfuscator`) в каталог
[`src/obfuscapk/obfuscators`](https://github.com/ClaudiuGeorgiu/Obfuscapk/tree/master/src/obfuscapk/obfuscators)
(в качестве начального примера возьмите простой существующий обфускатор, например
[`Nop`](https://github.com/ClaudiuGeorgiu/Obfuscapk/blob/master/src/obfuscapk/obfuscators/nop/nop.py)).
Инструмент автоматически обнаружит новый плагин, поэтому никакой дополнительной
настройки не требуется (новый плагин будет обрабатываться так же, как и все остальные
плагины, включённые в инструмент).
## ❱ Установка
Есть два способа получить рабочую копию Obfuscapk на своём компьютере: либо
[с помощью Docker](#docker-образ), либо [непосредственно из исходного кода](#из-исходников)
в среде `Python 3`. В обоих случаях первым делом нужно получить локальную
копию этого репозитория. Откройте терминал в каталоге, где хотите сохранить
проект, и склонируйте репозиторий:```Shell
$ git clone https://github.com/ClaudiuGeorgiu/Obfuscapk.git
Это рекомендуемый способ установки Obfuscapk, поскольку единственное требование — наличие установленной последней версии Docker:```Shell $ docker --version Docker version 20.10.21, build baeda1f
#### Официальный образ Docker Hub
[официальный образ Docker Obfuscapk](https://hub.docker.com/r/claudiugeorgiu/obfuscapk)
доступен на Docker Hub (автоматически собирается из этого репозитория):```Shell
$ # Download the Docker image.
$ docker pull claudiugeorgiu/obfuscapk
$ # Give it a shorter name.
$ docker tag claudiugeorgiu/obfuscapk obfuscapk
Если вы загрузили официальный образ из Docker Hub, то инструмент готов к использованию, поэтому переходите к инструкциям по использованию. В противном случае выполните следующую команду в ранее созданной директории Obfuscapk/src/ (папка, содержащая Dockerfile) для сборки Docker-образа:```Shell
$ # 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 .
Когда образ Docker готов, выполните быстрый тест, чтобы убедиться, что всё установлено правильно:```Shell
$ docker run --rm -it obfuscapk --help
usage: python3 -m obfuscapk.cli [-h] -o OBFUSCATOR [-w DIR] [-d OUT_APK_OR_AAB]
...
Obfuscapk теперь готов к использованию, см. инструкции по использованию для получения дополнительной информации.
Убедитесь, что у вас установлена последняя версия
apktool,
apksigner
и zipalign и они доступны из командной строки:```Shell
$ apktool
Apktool v2.9.0 - a tool for reengineering Android apk files
...
```Shell
$ apksigner
Usage: apksigner <command> [options]
apksigner --version
apksigner --help
...
$ zipalign
Zip alignment utility
Copyright (C) 2009 The Android Open Source Project
...
Для поддержки обфускации app bundles также необходим BundleDecompiler, поэтому загрузите последнюю доступную версию отсюда, сохраните её как BundleDecompiler.jar в директории, включённой в PATH (например, в Ubuntu, /usr/local/bin или /usr/bin) и убедитесь, что у него установлен флаг исполняемого файла.
Для использования BundleDecompiler и apktool также необходима свежая версия Java. zipalign и apksigner включены в Android SDK. Расположение исполняемых файлов также можно указать через следующие переменные окружения: APKTOOL_PATH, BUNDLE_DECOMPILER_PATH, APKSIGNER_PATH и ZIPALIGN_PATH (например, в Ubuntu, выполните export APKTOOL_PATH=/custom/location/apktool перед запуском Obfuscapk в том же терминале).
Помимо вышеуказанных инструментов, единственным требованием этого проекта является рабочая установка Python 3 (не ниже 3.7) (вместе с его менеджером пакетов pip).
Выполните следующие команды в главной директории проекта (Obfuscapk/) для установки необходимых зависимостей:```Shell
$ # 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
После установки всех требований выполните быстрый тест, чтобы убедиться, что всё работает корректно:```Shell
$ 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 теперь готов к использованию, см. инструкции по использованию для получения дополнительной информации.
Начиная с этого момента, Obfuscapk будет рассматриваться как исполняемый файл, доступный как obfuscapk,
поэтому вам нужно адаптировать команды в зависимости от того, как вы установили инструмент:
Docker image: локальный каталог, содержащий приложение для обфускации, должен быть смонтирован в /workdir в контейнере (например, текущий каталог "${PWD}"), поэтому команда:
$ obfuscapk [params...]
становится:
$ docker run --rm -it -u $(id -u):$(id -g) -v "${PWD}":"/workdir" obfuscapk [params...]
Из исходников: каждая инструкция должна выполняться из каталога Obfuscapk/src/
(или путем добавления каталога Obfuscapk/src/ в переменную окружения PYTHONPATH)
и команда:
$ obfuscapk [params...]
становится:
$ python3 -m obfuscapk.cli [params...]
Давайте начнем с просмотра справочного сообщения:```Shell $ 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>
Существует два обязательных параметра: `<APK_OR_BUNDLE_FILE>` — путь (относительный или абсолютный) к apk-файлу или файлу app bundle для обфускации, и список названий техник обфускации, которые нужно применить (указывается с помощью опции `-o`, которую можно использовать несколько раз, например `-o Rebuild -o NewAlignment -o NewSignature`). Другие необязательные аргументы:
* `-w DIR` используется для задания рабочего каталога, в котором будут сохраняться промежуточные файлы (созданные `apktool`). Если не указан, в том же каталоге, что и входное приложение, создается каталог с именем `obfuscation_working_dir`. Это может быть полезно для отладки, но если это не нужно, можно задать временный каталог (например, `-w /tmp/`).
* `-d OUT_APK_OR_AAB` используется для задания пути к результирующему файлу: apk-файлу, созданному в процессе обфускации (например, `-d /home/user/Desktop/obfuscated.apk` или `-d /home/user/Desktop/obfuscated.aab`). Если не указан, итоговый обфусцированный файл будет сохранен внутри рабочего каталога. Примечание: существующие файлы будут перезаписаны без предупреждения.
* `-i` — флаг для игнорирования известных сторонних библиотек в процессе обфускации, чтобы использовать меньше ресурсов, повысить производительность и снизить риск ошибок. [Список библиотек](https://github.com/ClaudiuGeorgiu/Obfuscapk/blob/master/src/obfuscapk/resources/libs_to_ignore.txt) для игнорирования адаптирован из проекта [LiteRadar](https://github.com/pkumza/LiteRadar).
* `-p` — флаг для отображения индикаторов выполнения во время операций обфускации. При использовании инструмента в пакетных операциях/автоматических сборках удобно отключать индикаторы выполнения, в противном случае этот флаг следует включить, чтобы видеть ход обфускации.
* `-k VT_API_KEY` необходим только при использовании обфускатора `VirusTotal`, чтобы задать API-ключ для взаимодействия с Virus Total.
* `--keystore-file KEYSTORE_FILE`, `--keystore-password KEYSTORE_PASSWORD`, `--key-alias KEY_ALIAS` и `--key-password KEY_PASSWORD` могут использоваться для указания пользовательского хранилища ключей (необходимо для подписи apk). Если используется `--keystore-file`, также должны быть указаны `--keystore-password` и `--key-alias`, а `--key-password` нужен только если выбранный ключ имеет другой пароль, не совпадающий с паролем хранилища. По умолчанию (когда `--keystore-file` не указан) для операций подписи используется [хранилище ключей, входящее в состав Obfuscapk](https://github.com/ClaudiuGeorgiu/Obfuscapk/blob/master/src/obfuscapk/resources/obfuscation_keystore.jks).
* `--ignore-packages-file IGNORE_PACKAGES_FILE` — путь к файлу, содержащему имена пакетов, которые следует игнорировать. Все классы внутри этих пакетов не будут обфусцированы при использовании данной опции. Файл должен содержать по одному имени пакета на строку, как показано в примере ниже:
```
com.mycompany.dontobfuscate
com.mycompany.ignore
...
```
* `--use-aapt2` — флаг для использования опции aapt2 при пересборке приложения с помощью `apktool`.
Теперь рассмотрим простой рабочий пример, чтобы увидеть, как работает Obfuscapk:```Shell
$ # original.apk is a valid Android apk file.
$ obfuscapk -o RandomManifest -o Rebuild -o NewAlignment -o NewSignature original.apk
При выполнении вышеуказанной команды происходят следующие действия:
так как рабочая директория не была указана, в том же месте, где находится original.apk, создаётся новая рабочая директория (obfuscation_working_dir) (это может быть полезно для проверки файлов smali/манифеста/ресурсов в случае ошибок)
выполняются некоторые проверки, чтобы убедиться, что все необходимые файлы/исполняемые файлы доступны и готовы к использованию
начинается собственно процесс обфускации: указанные обфускаторы выполняются (по порядку) один за другим, пока не останется ни одного обфускатора или пока не возникнет ошибка
при запуске первого обфускатора original.apk декомпилируется с помощью apktool, и результаты сохраняются в рабочей директории
так как первый обфускатор — RandomManifest, записи в декомпилированном Android-манифесте произвольно переупорядочиваются (без нарушения структуры xml)
обфускатор Rebuild просто пересобирает приложение (теперь с изменённым манифестом) с помощью apktool, и, поскольку выходной файл не указан, получившийся apk-файл сохраняется в ранее созданной рабочей директории
обфускатор NewAlignment использует инструмент для выравнивания полученного apk-файла
Как видно из предыдущего примера, обфускаторы Rebuild, NewAlignment и NewSignature всегда необходимы для завершения операции обфускации, чтобы собрать конечный обфусцированный apk. Это не фактические техники обфускации, но они нужны в процессе сборки, поэтому они включены в список обфускаторов для сохранения модульности общей архитектуры.
Не работает так, как ожидалось? См. FAQ и устранение неполадок.
Обфускаторы, входящие в Obfuscapk, можно разделить на разные категории в зависимости от выполняемых ими операций:
Тривиальные: как следует из названия, эта категория включает простые операции (которые не сильно изменяют исходное приложение), например, подписание apk-файла новой подписью.
Переименование: операции, изменяющие имена используемых идентификаторов (классов, полей, методов).
Шифрование: упаковка зашифрованного кода/ресурсов и их расшифровка во время выполнения приложения. При запуске Obfuscapk автоматически генерирует случайный секретный ключ (длиной 32 символа, используя буквы ASCII и цифры), который будет использоваться для шифрования.
Код: все операции, связанные с изменением декомпилированного исходного кода.
Ресурсы: операции с файлами ресурсов (например, изменение манифеста).
Прочее
Обфускаторы, в настоящее время входящие в состав Obfuscapk, кратко представлены ниже (в алфавитном порядке). Подробнее см. в исходном коде проекта.
[!TIP] Не все перечисленные ниже обфускаторы соответствуют реальным техникам обфускации (например,
Rebuild,NewAlignment,NewSignatureиVirusTotal), но они реализованы как обфускаторы, чтобы сохранить модульность архитектуры и упростить расширение новыми функциями.
Использует рефлексию для вызова опасных API Android Framework. Чтобы определить, принадлежит ли метод Android Framework, Obfuscapk обращается к отображению, обнаруженному Backes et al.
📄 Исходный код AdvancedReflection
Вставка мусорного кода. В данном случае мусорный код состоит из арифметических вычислений и инструкции ветвления, зависящей от результата этих вычислений, созданной таким образом, что ветвление никогда не выполняется.
📄 Исходный код ArithmeticBranch
Шифрование файлов ресурсов (assets).
📄 Исходный код AssetEncryption
Этот метод изменяет граф потока управления, не влияя на семантику кода: добавляются новые методы, которые вызывают исходные. Например, вызов метода m1 будет заменён новым методом-обёрткой m2, который при вызове вызывает исходный метод m1.
📄 Исходный код CallIndirection
Изменение имени пакета и переименование классов (даже в файле манифеста).
📄 Исходный код ClassRename
Шифрование константных строк в коде.
📄 Исходный код ConstStringEncryption
Удаление отладочной информации.
📄 Исходный код DebugRemoval
Переименование полей.
📄 Исходный код FieldRename
Для данного метода вставляется инструкция
goto, указывающая на конец метода, и другая инструкцияgoto, указывающая на инструкцию после первойgoto; это изменяет граф потока управления, добавляя два новых узла.
📄 Исходный код Goto
Шифрование нативных библиотек.
📄 Исходный код LibEncryption
Использует возможность перегрузки методов языка программирования Java, чтобы присвоить одинаковые имена разным методам, но с разными аргументами. Для уже существующего метода этот метод создаёт новый пустой метод с тем же именем и аргументами, но также добавляет новые случайные аргументы. Затем тело нового метода заполняется случайными арифметическими инструкциями.
📄 Исходный код MethodOverload
Переименование методов.
📄 Исходный код MethodRename
Повторное выравнивание приложения.
📄 Исходный код NewAlignment
Повторная подпись приложения новой пользовательской подписью.
📄 Исходный код NewSignature
Вставка мусорного кода. Nop, сокращение от no-operation (нет операции), — это специальная инструкция, которая ничего не делает. Этот метод просто вставляет случайные инструкции
nopв каждую реализацию метода.
📄 Исходный код Nop
Произвольное переупорядочивание записей в файле манифеста.
📄 Исходный код RandomManifest
Пересборка приложения.
📄 Исходный код Rebuild
Этот метод анализирует существующий код в поисках вызовов методов приложения, игнорируя вызовы Android framework (см.
AdvancedReflection). Если он находит инструкцию с подходящим вызовом метода (т.е. не конструкторы, публичная видимость, достаточное количество свободных регистров и т.д.), такой вызов перенаправляется на пользовательский метод, который вызовет исходный метод с помощью Reflection API.
📄 Исходный код Reflection
Этот метод заключается в изменении порядка базовых блоков в коде. Когда обнаружена инструкция ветвления, условие инвертируется (например, ветвление, если меньше, становится ветвление, если больше или равно), и целевые базовые блоки переупорядочиваются соответствующим образом. Кроме того, он также случайным образом переставляет код, злоупотребляя инструкциями
goto.
📄 Исходный код Reorder
Шифрование строк в ресурсах (только тех, которые вызываются в коде).
📄 Исходный код ResStringEncryption
Отправка исходного и обфусцированного приложения в Virus Total. Вы должны указать ключ API VT (см. опцию
-k).
📄 Исходный код VirusTotal
Вы можете свободно использовать этот код в соответствии с MIT License.
Это программное обеспечение было разработано в исследовательских целях в Лаборатории компьютерной безопасности (CSecLab), расположенной в DIBRIS, Университет Генуи.
zipalignобфускатор NewSignature подписывает вновь созданный apk-файл пользовательским сертификатом, содержащимся в
keystore, входящем в состав Obfuscapk
(хотя можно указать другой keystore с помощью параметра --keystore-file)
когда все обфускаторы выполнены без ошибок, результирующий обфусцированный apk-файл можно найти в obfuscation_working_dir/original_obfuscated.apk, подписанный, выровненный и готовый к установке на устройство/эмулятор