
O framework de instrumentação binária Redexer para bytecode Dalvik
Redexer é uma ferramenta de reengenharia que manipula binários de aplicativos Android. Essa ferramenta é capaz de analisar um arquivo DEX em uma estrutura de dados na memória; inferir com quais parâmetros o aplicativo usa certas permissões (nomeamos esse recurso de RefineDroid); modificar e desanalisar essa estrutura de dados para produzir um arquivo DEX de saída (nomeamos esses recursos de Dr. Android, que significa Dalvik Rewriting for Android).
Esta ferramenta é testada sob OCaml 4.09.0 e Ruby 1.8.6(7), então você precisa instalá-los (ou versões superiores).
Para manipular uma assinatura SHA-1 (hash) no formato DEX, utilizamos a biblioteca OCaml SHA via ocamlfind/findlib, um gerenciador de bibliotecas OCaml. A maneira mais fácil de instalar ambos é usando OPAM, um gerenciador de pacotes OCaml, que possui ambos os pacotes---OPAM ocamlfind e OPAM sha.
Você também pode compilar e/ou instalar ambos os pacotes diretamente. Se estiver usando uma máquina Linux, pode encontrar facilmente as distribuições.
Caso contrário, por exemplo, usando um Mac, você precisa compilá-los por conta própria.
Você pode encontrar os códigos-fonte originais aqui.
Compile executando make, e vincule o diretório resultante ao diretório raiz site-lib do ocamlfind; ou sudo make install.
Se estiver usando um PC, você precisa instalar ocamlfind/findlib e FlexDLL primeiro. Certifique-se de que suas variáveis de ambiente estejam configuradas corretamente da seguinte forma:
OCAMLLIB=C:\OCaml\lib
CAML_LD_LIBRARY_PATH=%OCAMLLIB%\stublibs
FLEXLINKFLAGS=-L%MinGW%\lib -L%MinGW%\lib\gcc\mingw32\N.N.N
Pacotes OPAM:
Android SDK (ou fontes)
Para desempacotar e reempacotar arquivos apk, usamos apktool, uma ferramenta de reengenharia APK de código aberto.
Como ele usa aapt, Android Asset Packaging Tool,
você precisa instalar o Android SDK ou as fontes. Além disso, usamos
zipalign, que também vem do Android SDK, para otimizar aplicativos reescritos.
Você pode definir caminhos para as ferramentas base do Android adicionando o seguinte ao seu perfil:
ANDROID_HOME=$HOME/android-sdk # seu próprio caminho aqui!
export ANDROID_HOME
PATH=$PATH:$ANDROID_HOME/tools
PATH=$PATH:$ANDROID_HOME/platform-tools
PATH=$PATH:$ANDROID_HOME/build-tools/19.0.0 # número da versão instalada
export PATH
Os scripts principais são escritos em Ruby e requerem RubyGems, um gerenciador de pacotes Ruby, e Nokogiri, uma biblioteca XML para manipular arquivos de manifesto.
Se você quiser ver gráficos (ex: grafo de chamadas, grafo de fluxo de controle, árvore de dominância, etc.), você precisa instalar graphviz dot.
Para compilar o redexer, basta make! Você pode ver o binário redexer no nível superior.
$ make (clean)
Antes de usar a ferramenta, cabe ao usuário instalar o arquivo de plataforma mais recente para o apktool. Por exemplo, você precisa fazer
$ java -jar tools/apktool.jar if [arquivo de plataforma adequado]
Você também pode gerar documentos de API em formato html.
$ make api
Você pode ver todas as opções que a ferramenta oferece:
$ ruby scripts/cmd.rb -h
$ ruby scripts/cmd.rb --help
Assim como o dexdump no Android SDK, o redexer permite visualizar o conteúdo interno do arquivo dex fornecido em formato YAML.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd unparse [--to blah.yml]
Esta opção despeja instruções para um método especificado.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd dump_method --mtd cls.mtd
Este recurso serve para testar os módulos de análise e despejo do redexer. Ele provavelmente gera um arquivo dex idêntico.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd id [--to blah.dex]
Você também pode ver estatísticas básicas sobre o arquivo dex, por exemplo, # instr.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd info
Esta opção imprime todos os nomes de classes definidos no arquivo dex.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd classes
Pode ser útil para pesquisar bibliotecas de terceiros específicas, por exemplo,
$ ruby scripts/cmd.rb target.(apk|dex) --cmd classes | egrep 'apache'
Esta opção imprime o uso da API no arquivo dex.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd api [--sdk android.]
$ ruby scripts/cmd.rb target.(apk|dex) --cmd api --sdk com.facebook.
Você não tem curiosidade sobre como alguns opcodes são raramente usados em bytecodes Dalvik? Ele mostrará o histograma de todos os opcodes, ou você pode consultar com que frequência um opcode exato é usado no aplicativo fornecido.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd opstat [--op opcode1,opcode2,...]
Por exemplo,
$ ruby scripts/cmd.rb ~/apps/top24/com.whatsapp.apk --cmd opstat
$ ruby scripts/cmd.rb ~/apps/top24/com.whatsapp.apk --cmd opstat --op div-int/lit16,nop
Esta opção realiza análise de resolução de Intent baseada em propagação, e imprime as transições entre classes Activity.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd intent
Esta opção gera um arquivo pdf que descreve um grafo de chamadas do arquivo fornecido. Se você não especificar o nome do pdf, cg.pdf será usado.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd cg [--to blah.pdf] [--no-pdf]
Esta opção gera um arquivo pdf que mostra um grafo de fluxo de controle do método fornecido. Acrescente um nome de método a um nome de classe com ponto: class_name.method_name
$ ruby scripts/cmd.rb target.(apk|dex) --cmd cfg --mtd cls.mtd [--to blah.pdf] [--no-pdf]
Esta opção é semelhante ao recurso acima, exceto que descreve a árvore de dominância (post).
$ ruby scripts/cmd.rb target.(apk|dex) --cmd (p)dom --mtd cls.mtd [--to blah.pdf] [--no-pdf]
Esta opção realiza uma análise clássica de fluxo de dados reverso.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd live --mtd cls.mtd
Esta opção realiza uma análise clássica de fluxo de dados direto.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd const --mtd cls.mtd
Esta opção realiza uma análise clássica de fluxo de dados direto.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd reach --mtd cls.mtd
Esta opção encontra dependência de classes.
$ ruby scripts/cmd.rb target.(apk|dex) --cmd dependants --mtd cls.mtd
Esta opção imprime o nome da atividade inicial do apk fornecido.
$ ruby scripts/cmd.rb target.apk --cmd launcher
Esta opção informa quais componentes estão expostos para fora.
$ ruby scripts/cmd.rb target.apk --cmd exported
Estas opções imprimem componentes básicos do Android declarados no manifesto.
$ ruby scripts/cmd.rb target.apk --cmd [activity | service | provider | receiver]
Esta opção explora definições de layout em recursos e imprime visualizações personalizadas (custom views).
$ ruby scripts/cmd.rb target.apk --cmd custom_views
Esta opção explora definições de layout em recursos e imprime elementos Fragment.
$ ruby scripts/cmd.rb target.apk --cmd fragments
Esta opção explora definições de layout em recursos e imprime Botões, juntamente com seu id (ou texto), bem como o método de callback (se existir).
$ ruby scripts/cmd.rb target.apk --cmd buttons
Esta opção imprime as permissões que o apk usa.
$ ruby scripts/cmd.rb target.apk --cmd permissions
Esta opção imprime qual versão do SDK o apk requer.
$ ruby scripts/cmd.rb target.apk --cmd sdk
Se você não quiser desempacotar o arquivo apk, na verdade, você pode fazer o mesmo com uma combinação de comandos:
$ aapt dump badging target.apk | grep 'targetSdkVersion' | tr -dc 0-9.\\n
Esta opção geraria um arquivo dex que imprime uma mensagem simples. Esse arquivo dex é feito apenas usando as APIs do redexer.
$ ruby scripts/cmd.rb --cmd hello
Verifique seu conteúdo interno.
$ dexdump -d results/classes.dex
Se estiver interessado, você pode testar esse arquivo dex da seguinte forma. Assuma que o caminho para ANDROID_SDK está definido.
// cria um jar temporário adequado para a Dalvik VM
$ aapt add temp.jar results/classes.dex
// (opcional) se você não criou um avd, crie um.
$ android create avd -n myAVD1 -t android-8
// inicie seu emulador
$ emulator -avd myAVD1 &
// envie o jar temporário
$ adb push temp.jar /data
// conecte ao shell adb
$ adb shell
// finalmente, execute o dex
# /system/bin/dalvikvm -Xbootclasspath:/system/framework/core.jar \
-classpath /data/temp.jar Hello
Hello, DEX
#
Esta é uma variante do recurso de reescrita. Usando este recurso, você pode registrar
o comportamento de aplicativos de pontos de vista específicos. O arquivo dex pré-construído
para a biblioteca de logging é fornecido: data/logging.dex. Se você quiser adicionar
mais recursos ou utilitários, compile-o da seguinte forma:
$ cd logging
$ gradle copyDex
$ cd ..
Em seguida, use o seguinte comando:
$ ruby scripts/cmd.rb target.apk --cmd logging
O trim.py pode capturar as sequências de chamada-retorno do aplicativo instrumentado. (Você deve primeiro instrumentar o aplicativo em teste usando o redexer.)
Se esses logs forem curtos o suficiente, i.e., o telefone (ou emulador) puder armazenar todas as informações na memória, você pode usar o modo offline do script:
$ ./scripts/trim.py -d
Note que todos os parâmetros da linha de comando serão passados para adb logcat, e
por padrão, org.umd.logging:I *:S é passado para filtrar logs irrelevantes.
Se os logs transbordarem, você deve usar o modo online:
$ ./scripts/trim.py
O script captura a interrupção de tecla, então você pode finalizar o logging via Ctrl+C.
Em ambos os modos, os logs são salvos em log.txt e exibidos na tela de uma vez. Assim, após coletar os logs, você pode precisar mover esse arquivo, por exemplo:
$ mv log.txt app.scenario.txt
O recurso de logging acima é geral, pois você pode especificar o que registrar
no nível de método. (Veja o módulo logging para mais detalhes.)
No entanto, isso às vezes é muito detalhado e pode induzir degradação de desempenho.
Este recurso foi projetado para registrar apenas interações do usuário. Usando este recurso,
você pode capturar apenas eventos relacionados à interface do usuário (UI). Similarmente, o arquivo dex pré-construído
para a biblioteca de logging é fornecido: data/logging-ui.dex. Se você quiser modificar
a verbosidade das informações de UI, compile-o da seguinte forma:
$ cd logging-ui
$ gradle copyDex
$ cd ..
Em seguida, use o seguinte comando:
$ ruby scripts/cmd.rb target.apk --cmd logging_ui
A biblioteca de logging é herdada do serviço android a11y, que requer
consentimento explícito do usuário. Assim, após instalar o apk reescrito, vá para
Settings/Accessibility e ative o serviço UI Logging.
(Esta etapa pode ser vista como similar a ativar o modo de depuração do dispositivo.)
No logcat, as mensagens com tags org.umd.logging_ui.* são interações
entre o usuário e o aplicativo em teste.
Esta opção encontra caminhos de transição de componentes em direção a chamadas de método alvo.
$ ruby scripts/cmd.rb target.apk --cmd directed
Você pode especificar métodos alvo a serem invocados em data/directed.txt
Esses caminhos de transição de componentes são usados para direcionar aplicativos a testar vulnerabilidades de segurança em bibliotecas de terceiros. Mais detalhes são descritos no seguinte artigo:
* Brahmastra: Driving Apps to Test the Security of Third-Party Components.
R. Bhoraskar, et al., In 23rd Usenix Security Symposium (Security '14).
O withTimeout.rb pode construir um arquivo de skip para um aplicativo automaticamente. Este script executa cmd.rb com um tempo limite específico, usado para limitar o tempo gasto instrumentando qualquer classe individual. Esta é uma solução temporária para a classe ocasional que fica presa em um loop durante a instrumentação. Quando este script encontra uma classe que falha, ele a adiciona ao arquivo de skip e continua de onde parou. Uma vez que withTimeout tenha terminado, haverá um arquivo chamado [nome do apk]-skip.txt no diretório de dados, que pode ser usado para construir um aplicativo totalmente instrumentado para esse apk. Para usar withTimeout, basta chamar
$ ruby scripts/withTimeout.rb TIMEOUT COMMANDS
Onde TIMEOUT é a duração do tempo limite desejado em segundos (300 é recomendado) e COMMANDS são todas as entradas regulares da linha de comando que você passaria para scripts/cmd.rb para o apk.