Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
simplify — Виртуальная машина Android и деобфускатор | Kitploit
Инструменты/GitHubGitHub/calebfenton/simplify
Безопасность AndroidДинамический анализ (песочница)Обратная инженерияАнализ вредоносных программАнализ Бинарных Файлов
GitHubcalebfenton/simplify

simplify

Виртуальная машина Android и деобфускатор

Репозиторий
4.7k45515 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Simplify

Build Status Coverage Status Coverity Scan Build Status

Generic Android Deobfuscator

Simplify виртуально исполняет приложение, чтобы понять его поведение, а затем пытается оптимизировать код так, чтобы он вел себя идентично, но был понятнее для человека. Каждый тип оптимизации прост и универсален, поэтому не имеет значения, какой именно тип обфускации используется.

Before and After

Код слева — это декомпиляция обфусцированного приложения, а код справа — после деобфускации.

Lots of method calls, no clear meaning Wow, such literal, much meaning

Overview

Проект состоит из трех частей: smalivm, simplify и демонстрационное приложение.

  1. smalivm: Предоставляет песочницу виртуальной машины для выполнения методов Dalvik. После выполнения метода возвращается граф, содержащий все возможные значения регистров и классов для каждого пути выполнения. Он работает даже если некоторые значения неизвестны, например, при файловом и сетевом вводе/выводе. Например, любое условное выражение if или switch с неизвестным значением приводит к выполнению обеих ветвей.
  2. simplify: Анализирует графы выполнения из smalivm и применяет оптимизации, такие как распространение констант, удаление мертвого кода, устранение отражения и некоторые оптимизации "глазка". Они довольно просты, но при многократном совместном применении расшифровывают строки, устраняют отражение и сильно упрощают код. Он не переименовывает методы и классы.
  3. demoapp: Содержит простые, с подробными комментариями примеры использования smalivm в вашем собственном проекте. Если вы создаете что-то, что должно выполнять код Dalvik, загляните туда.

Usage

root@kitploit:~
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

Building

Для сборки требуется установленный Java Development Kit 8 (JDK).

Поскольку проект содержит подмодули для Android-фреймворков, клонируйте с --recursive:

root@kitploit:~
git clone --recursive https://github.com/CalebFenton/simplify.git

Или обновите подмодули в любое время с помощью:

root@kitploit:~
git submodule update --init --recursive

Затем, чтобы собрать единый jar-файл, содержащий все зависимости:

root@kitploit:~
./gradlew fatjar

Jar-файл Simplify будет находиться в simplify/build/libs/. Вы можете проверить его работу, упрощая предоставленное обфусцированное демонстрационное приложение. Вот как его запустить (возможно, потребуется изменить путь к simplify.jar):

root@kitploit:~
java -jar simplify/build/libs/simplify.jar -it "org/cf/obfuscated" -et "MainActivity" simplify/obfuscated-app.apk

Чтобы понять, что именно деобфусцируется, ознакомьтесь с README обфусцированного приложения.

Troubleshooting

Если Simplify не работает, попробуйте следующие рекомендации по порядку:

  1. Ограничьте выполнение только несколькими методами или классами, используя опцию -it.
  2. Если сбой происходит из-за превышения максимального количества посещений, попробуйте увеличить --max-address-visits, --max-call-depth и --max-method-visits.
  3. Попробуйте с ключом -v или -v 2 и сообщите о проблеме, приложив логи и хеш DEX или APK.
  4. Попробуйте еще раз, но не прерывайте зрительный контакт. Simplify чувствует страх.

Если сборка на Windows завершается ошибкой, похожей на:

Could not find tools.jar. Please check that C:\Program Files\Java\jre1.8.0_151 contains a valid JDK installation.

Это означает, что Gradle не может найти корректный путь к JDK. Убедитесь, что JDK установлен, задайте переменную окружения JAVA_HOME с путем к JDK и обязательно закройте и снова откройте командную строку, которую используете для сборки.

Contributing

Не стесняйтесь. Я считаю, что виртуальное выполнение и деобфускация — увлекательные задачи. Любой, кто интересуется, автоматически крут, и вклад приветствуется, даже если это просто исправление опечатки. Не стесняйтесь задавать вопросы в issues и отправлять pull request'ы.

Reporting Issues

Пожалуйста, приложите ссылку на APK или DEX и полную используемую команду. Это значительно облегчает воспроизведение (и, следовательно, исправление) вашей проблемы.

Если вы не можете поделиться образцом, пожалуйста, укажите хеш файла (SHA1, SHA256 и т.д.).

Optimization Strategies

Constant Propagation

Если операция помещает значение типа, которое может быть преобразовано в константу (например, строка, число или булево), эта оптимизация заменяет такую операцию на константу. Например:

root@kitploit:~
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

В этом примере зашифрованная строка расшифровывается и помещается в v0. Поскольку строки "константизируемы", move-result v0 можно заменить на const-string:

root@kitploit:~
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."

Dead Code Removal

Код считается мертвым, если его удаление не может изменить поведение приложения. Самый очевидный случай — если код недостижим, например, if (false) { // dead }). Если код достижим, он может считаться мертвым, если он не влияет ни на какое состояние вне метода, то есть не имеет побочных эффектов. Например, код может не влиять на возвращаемое значение метода, не изменять переменные класса и не выполнять ввод/вывод. Это сложно определить при статическом анализе. К счастью, smalivm не нужно быть умным. Он просто тупо выполняет все, что может, и предполагает наличие побочных эффектов, если не уверен. Рассмотрим пример из раздела о распространении констант:

root@kitploit:~
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."

В этом коде invoke-static больше не влияет на возвращаемое значение метода, и предположим, что он не делает ничего странного, например, не записывает байты в файловую систему или сетевой сокет, поэтому у него нет побочных эффектов. Его можно просто удалить.

root@kitploit:~
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
const-string v0, "Tell me of your homeworld, Usul."

Наконец, первый const-string присваивает значение регистру, но это значение никогда не используется, то есть присваивание мертво. Его также можно удалить.

root@kitploit:~
const-string v0, "Tell me of your homeworld, Usul."

Ура!

Unreflection

Одна из основных проблем статического анализа Java — это отражение. Невозможно узнать аргументы для методов отражения без тщательного анализа потоков данных. Существуют умные хитроумные способы, но smalivm делает это простым выполнением кода. Когда он обнаруживает вызов отражённого метода, например:

root@kitploit:~
invoke-virtual {v0, v1, v2}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;

Он может узнать значения v0, v1 и v2. Если он уверен в значениях, он может заменить вызов Method.invoke() на фактический вызов метода без отражения. То же самое относится к поиску отражённых полей и классов.

Peephole

Для всего, что не вписывается четко в какую-либо категорию, существуют optimizations "глазка". Сюда входит удаление бесполезных операций check-cast, замена вызовов Ljava/lang/String;-><init> на const-string и так далее.

Deobfuscation Example

Before Optimization

root@kitploit:~
.method public static test1()I
    .locals 2

    new-instance v0, Ljava/lang/Integer;
    const/4 v1, 0x1
    invoke-direct {v0, v1}, Ljava/lang/Integer;-><init>(I)V

    invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I
    move-result v0

    return v0
.end method

Всё, что он делает — это v0 = 1.

After Constant Propagation

root@kitploit:~
.method public static test1()I
    .locals 2

    new-instance v0, Ljava/lang/Integer;
    const/4 v1, 0x1
    invoke-direct {v0, v1}, Ljava/lang/Integer;-><init>(I)V

    invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I
    const/4 v0, 0x1

    return v0
.end method

move-result v0 заменяется на const/4 v0, 0x1. Это происходит потому, что существует только одно возможное возвращаемое значение для intValue()I, и тип возврата может быть сделан константой. Аргументы v0 и v1 однозначны и не изменяются. То есть для всех возможных путей выполнения в intValue()I существует консенсус значений. Другие типы значений, которые могут быть преобразованы в константы:

  • числа — const/4, const/16 и т.д.
  • строки — const-string
  • классы — const-class

After Dead Code Removal

root@kitploit:~
.method public static test1()I
    .locals 2

    const/4 v0, 0x1

    return v0
.end method

Поскольку код выше const/4 v0, 0x1 не влияет на состояние вне метода (нет побочных эффектов), его можно удалить без изменения поведения. Если бы был вызов метода, который что-то записывает в файловую систему или сеть, его нельзя было бы удалить, потому что он влияет на состояние вне метода. Или если бы test()I принимала изменяемый аргумент, например LinkedList, любые инструкции, обращающиеся к нему, не могли бы считаться мертвыми.

Другие примеры мертвого кода:

  • неиспользуемые присваивания — присвоение значений регистрам без их последующего использования
  • недостижимые инструкции — if (false) { dead_code(); }

License

Этот инструмент доступен под двойной лицензией: коммерческой, подходящей для закрытых проектов, и лицензией GPL, которая может использоваться в открытом программном обеспечении.

В зависимости от ваших потребностей вы должны выбрать одну из них и следовать ее политике. Подробности политики и соглашений для каждого типа лицензии доступны в файлах LICENSE.COMMERCIAL и LICENSE.GPL.

Further Reading

  • Dalvik Virtual Execution with SmaliVM
  • Guillot, Yoann, and Alexandre Gazet. "Automatic Binary Deobfuscation." Journal in Computer Virology 6.3 (2010): 261-76
  • Unicorn - The ultimate CPU emulator
  • Babak Yadegari, Saumya Debray. "Symbolic Execution of Obfuscated Code"
  • Success stories:
    • Android Dynamic Class Loading with "AES/CFB/NoPadding" encryption. Take a peek before & after. Tool used: #simplify. #Android #obfuscation #classencryption #dex
    • Decrypting Malware String Encryption
Скачать инструмент