
Máquina virtual Android e desofuscador
O Simplify executa virtualmente um aplicativo para entender seu comportamento e então tenta otimizar o código para que se comporte de forma idêntica, mas seja mais fácil para um humano entender. Cada tipo de otimização é simples e genérico, portanto não importa qual tipo específico de ofuscação é usado.
O código à esquerda é uma descompilação de um aplicativo ofuscado, e o código à direita foi desofuscado.
Há três partes no projeto: smalivm, simplify e o aplicativo de demonstração.
if ou switch com um valor desconhecido resulta em ambos os ramos sendo seguidos.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
A compilação requer a instalação do Java Development Kit 8 (JDK).
Como este projeto contém submodulos para frameworks Android, clone com --recursive:
git clone --recursive https://github.com/CalebFenton/simplify.git
Ou atualize os submodulos a qualquer momento com:
git submodule update --init --recursive
Então, para construir um único jar que contém todas as dependências:
./gradlew fatjar
O jar do Simplify estará em simplify/build/libs/. Você pode testar se está funcionando simplificando o aplicativo de exemplo ofuscado fornecido. Aqui está como executá-lo (você pode precisar alterar simplify.jar):
java -jar simplify/build/libs/simplify.jar -it "org/cf/obfuscated" -et "MainActivity" simplify/obfuscated-app.apk
Para entender o que está sendo desofuscado, veja o README do Aplicativo Ofuscado.
Se o Simplify falhar, tente estas recomendações, em ordem:
-it.--max-address-visits, --max-call-depth e --max-method-visits.-v ou -v 2 e relate o problema com os logs e um hash do DEX ou APK.Se estiver compilando no Windows e a compilação falhar com um erro semelhante a:
Could not find tools.jar. Please check that C:\Program Files\Java\jre1.8.0_151 contains a valid JDK installation.
Isso significa que o Gradle não consegue encontrar um caminho adequado do JDK. Certifique-se de que o JDK está instalado, defina a variável de ambiente JAVA_HOME para o caminho do JDK e certifique-se de fechar e reabrir o prompt de comando usado para compilar.
Não seja tímido. Eu acho que execução virtual e desofuscação são problemas fascinantes. Qualquer um interessado é automaticamente legal e contribuições são bem-vindas, mesmo que seja apenas para corrigir um erro de digitação. Sinta-se à vontade para fazer perguntas nas issues e enviar pull requests.
Por favor, inclua um link para o APK ou DEX e o comando completo que você está usando. Isso torna muito mais fácil reproduzir (e assim corrigir) o seu problema.
Se você não puder compartilhar a amostra, por favor inclua o hash do arquivo (SHA1, SHA256, etc).
Se uma operação coloca um valor de um tipo que pode ser transformado em uma constante, como uma string, número ou booleano, esta otimização substituirá essa operação pela constante. Por exemplo:
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
Neste exemplo, uma string criptografada é descriptografada e colocada em v0. Como strings são "constantizáveis", o move-result v0 pode ser substituído por um const-string:
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."