Escolar Documentos
Profissional Documentos
Cultura Documentos
com
implementar, sem ele você não pode alcançar a automação que torna o teste fuzz tão
bom. Os navegadores obtêm principalmente entradas com base em URLs (Universal
Resource Locators). Mergulhar em todas as complexidades envolvidas na construção
e análise de URL está fora do escopo deste capítulo. O mais importante é que a URL
informa ao navegador qual mecanismo usar para obter a entrada. Dependendo de
qual mecanismo é usado, a entrada deve ser fornecida de acordo.
BrowserFuzzfornece entradas para o navegador usando HTTP. É provável que
outros meios, como carregar a entrada e usar umArquivo://URL, funcionariam, mas
não foram investigados. Para entregar entradas via HTTP, o fuzzer implementa um
servidor HTTP rudimentar baseado no framework Twisted Python. O código relevante
é mostrado aqui:
13 do servidor de importação twisted.web, recurso 14 do
reator de importação twisted.internet
...
83 class FuzzServer(resource.Resource):
84 isLeaf = Verdadeiro
85 página = Nenhum
86 def render_GET(self, request): path =
87 request.postpath[0] if path ==
88 "favicon.ico":
89 request.setResponseCode(404) return
90 "Não encontrado"
91 self.page = generate_page() return
92 self.page
93
94 if __name__ == "__main__": 95
# Inicia o servidor HTTP server_thread = FuzzServer()
96 reactor.listenTCP(LISTEN_PORT, server.Site(server_thread))
97 threading.Thread(target=reactor.run, args=(False,)).start()
98
Como dito anteriormente, este servidor HTTP é bastante rudimentar. Ele só responde a
PEGUEsolicitações e tem muito pouca lógica para o que retornar. A menos que ofavicon. ico
arquivo é solicitado, o servidor sempre retorna uma página gerada, que ele salva para
mais tarde. No caso do ícone, um erro 404 é retornado para informar ao navegador que
esse arquivo não está disponível. Na parte principal do fuzzer, o servidor HTTP é iniciado
em seu próprio thread em segundo plano. Graças ao Twisted, nada mais precisa ser feito
para servir os insumos gerados.
Com um servidor HTTP funcionando, o fuzzer ainda precisa fazer mais uma coisa para
que as entradas sejam processadas automaticamente. Ele precisa instruir o navegador a
carregar páginas do URL correspondente. Automatizar este processo no Android é muito
fácil, graças aGerenciador de atividades.Simplesmente enviando um Intent usando o
souprograma de linha de comando, você pode iniciar o navegador simultaneamente
e dizer a ele de onde carregar o conteúdo. O trecho a seguir doexecute_test
funcionar dentroBrowserFuzzfaz isso.
194 Capítulo 6-Encontrando Vulnerabilidades com o Teste Fuzz
A linha 57 gera uma string de consulta baseada em tempo para solicitar. O tempo é
usado para garantir que o navegador solicitará uma nova cópia do conteúdo a cada vez,
em vez de reutilizar uma de seu cache. As linhas 58 a 63 realmente executam o
soucomando no dispositivo usando ADB.
A linha de comando completa queBrowserFuzzusos é bastante longo e complicado. Ele
usa ocomeçarsubcomando, que inicia umAtividade.Várias opções de Intenção seguem o
subcomando. Primeiro, a ação Intent (android.intent.action.VIEW) é especificado com o -uma
trocar. Esta ação específica permite que oGerenciador de atividades
decidir como lidar com a solicitação, que por sua vez decide com base nos dados
especificados com o -dtrocar.BrowserFuzzusa um URL HTTP que aponta de volta para o
servidor que foi iniciado, o que faz com queGerenciador de atividadespara iniciar o
navegador padrão. A seguir, o -eswitch fornece dados extras ao Chrome que definem
com.android. browser.application_idpara “uau”. Isso tem o efeito de abrir a requisição na
mesma aba do navegador ao invés de criar uma nova aba para cada execução. Isso é
particularmente importante porque criar toneladas de novas guias desperdiça memória e
torna a reinicialização de um navegador travado mais demorada. Além disso, é improvável
que reabrir casos de teste anteriores na reinicialização ajude a encontrar um bug porque
essas entradas já foram processadas uma vez. A parte final do comando especifica o
pacote que deve ser iniciado. Embora este fuzzer usecom.android.chrome,segmentar outros
navegadores também é possível. Por exemplo, o antigo navegador Android em um Galaxy
Nexus pode ser iniciado usando ocom.google.android.browser
nome do pacote em vez disso.
PorqueBrowserFuzzvisa testar muitas entradas automaticamente, a peça final do quebra-
cabeça de processamento de entrada é um loop trivial que executa testes repetidamente. Aqui
está o código:
45 def executar(auto):
46 while self.keep_going:
47 self.execute_test()
Teste de monitoramento
Passamos alguns segundos que dão ao Chrome tempo suficiente para processar nossa
entrada criada. O número aqui é bastante grande, mas isso é intencional. Processando grande
Matrizes digitadaspode levar um bom tempo, especialmente quando executado em um
dispositivo relativamente de baixa potência.
A próxima etapa é examinar o log do sistema para ver o que aconteceu. Novamente,
usamos oadb logcatcomando como mostrado aqui:
Revisão: '0'
pid: 28335, tid: 28349, name: ChildProcessMai >>>
com.android.chrome:sandboxed_process3 <<<
sinal 11 (SIGSEGV), código 1 (SEGV_MAPERR), endereço de falha 00000000
r0 00000000 r1 00000000 r2 c0000000 r3 00000000
r4 00000000 r5 00000000 r6 00000000 r7 00000000
r8 6ad79f28 r9 37a08091 sl 684e45d4 fp 6ad79f1c
ip 00000000 sp 6ad79e98 lr 00000000 computador 4017036c cpsr 80040010
Capítulo 6-Encontrando Vulnerabilidades com o Teste Fuzz 197
O Capítulo 5 discutiu algumas das muitas funções diferentes que a interface Universal
Serial Bus (USB) de um dispositivo Android pode expor. Cada função representa uma
superfície de ataque em si. Embora o acesso a essas funções exija acesso físico a um
dispositivo, as vulnerabilidades no código subjacente podem permitir o acesso ao
dispositivo apesar dos mecanismos de segurança existentes, como uma tela bloqueada ou
uma interface ADB desativada ou protegida. O impacto potencial inclui ler dados do
dispositivo, gravar dados no dispositivo, obter execução de código, reescrever partes do
firmware do dispositivo e muito mais. Esses fatos combinados tornam a superfície de
ataque USB um alvo interessante para testes de fuzz.
198 Capítulo 6-Encontrando Vulnerabilidades com o Teste Fuzz
Existem duas categorias principais de dispositivos USB: hosts e dispositivos. Embora alguns
dispositivos Android sejam capazes de se tornar um host, muitos não são. Quando um
dispositivo passa a se comportar como host, geralmente usando um cabo On-the-Go (OTG), diz-
se que está emmodo de host. Como o suporte ao modo host em dispositivos Android tem um
passado duvidoso, esta seção se concentra em fuzzingmodo de dispositivoServiços.
Devido aos vários modos possíveis em que uma interface USB pode estar, escolher
apenas um pode ser difícil. Por outro lado, alterar o modo de um dispositivo Android
geralmente altera as funções expostas. Ou seja, um modo expõe um determinado
conjunto de funções, mas outro modo expõe um conjunto diferente de funções. Isso
pode ser visto facilmente ao conectar um dispositivo ao USB. Ao fazer isso, uma
notificação normalmente aparecerá informando o modo atual e instruindo o usuário
a clicar para alterar as opções. Exatamente quais funções são suportadas varia
Capítulo 6-Encontrando Vulnerabilidades com o Teste Fuzz 199
de um de a notificação ao conectar
em um Nexus 4 com Android 4.4.
A partir da Figura 6-4, parece que não há muitos modos oferecidos por padrão no
Nexus 4. A verdade é que algumas outras funções são suportadas, como tethering USB,
mas elas devem ser explicitamente habilitadas ou definidas pela inicialização de maneiras
especiais. Este dispositivo está em sua configuração padrão e, portanto, “Dispositivo de
mídia (MTP)” é a função padrão exposta pelo dispositivo em seu estado de fábrica. Isso
por si só o torna o alvo de fuzz mais atraente.
Gerando entradas
Depois de selecionar uma função USB específica para direcionar, o próximo passo é
aprender o máximo possível sobre ela. Até agora, a única coisa conhecida é que o
dispositivo Android identifica essa função como “dispositivo de mídia (MTP)”.
Pesquisando a sigla MTP revela que significa Media Transfer Protocol. Uma breve
investigação explica que o MTP é baseado no Picture Transfer Protocol (PTP). Além
disso, a pesquisa por "fuzzing MTP" leva a uma ferramenta disponível publicamente
que implementa o MTP fuzzing. Olle Segerdahl desenvolveu esta ferramenta e a
lançou na conferência T2 Infosec de 2012 na Finlândia. A ferramenta está disponível
emhttps://github.com/ollseg/usb-device-fuzzing.git.O restante desta seção examina como
esse fuzzer gera e processa entradas.
200 Capítulo 6-Encontrando Vulnerabilidades com o Teste Fuzz
Ao dar uma olhada mais profunda na ferramenta usb-device-fuzzing de Olle, fica óbvio que
ele construiu sua estratégia de geração na popular ferramenta de manipulação de pacotes
Scapy. Essa é uma estratégia excelente porque o Scapy fornece muito do que é necessário para
gerar entrada de pacotes difusos. Ele permite que o desenvolvedor se concentre no protocolo
específico em mãos. Ainda assim, Olle teve que contar ao Scapy sobre a estrutura dos pacotes
MTP e o fluxo do protocolo. Ele também teve que implementar qualquer tratamento fora do
padrão, como relacionamentos entre campos de dados e comprimento.
O código para geração de pacotes está dentro doUSBFuzz/MTP.pyArquivo. Como de
costume, ele começa incluindo os componentes Scapy necessários. Olle então definiu dois
dicionários para armazenar os códigos de Operação e Resposta usados pelo MTP. Em
seguida, Olle definiu umRecipienteclasse e duas das Fases de Transação do MTP. Todas as
transações MTP são prefixadas por um contêiner para permitir que o serviço MTP saiba
como interpretar os dados a seguir. oRecipienteclasse, que é realmente descrita na
especificação PTP, está listada aqui:
Este objeto gera a estrutura de contêiner usada por PTP e MTP. Por ser construído
em Scapy, esta classe só precisa definirCampos_descrição. Diz ao Scapy como
construir o pacote que representa o objeto. Como visto no código-fonte, oRecipiente
pacote consiste em apenas quatro campos: um comprimento, um tipo, um código e
um identificador de transação. Seguindo essa definição oRecipiente
classe contém umpost_buildfunção. Ele lida com duas coisas. Primeiro, ele copia o
código e o identificador de transação da carga útil, que conterá um dos dois tipos de
pacotes discutidos a seguir. finalmente, opost_buildfunção atualiza oComprimento
campo com base no tamanho da carga fornecida.
Os próximos dois objetos que Olle definiu são osOperaçãoeRespostapacotes. Esses
pacotes são usados como carga útil paraRecipienteobjetos. Eles compartilham uma
estrutura comum e diferem apenas pelos códigos que são válidos noCódigocampo. O
trecho a seguir mostra o código relevante:
classe 127 Operação (Pacote):
128 nome = "Operação "
129 field_desc = [ LEShortEnumField("OpCode", 0, OpCodes),
Capítulo 6-Encontrando Vulnerabilidades com o Teste Fuzz 201
Esses dois pacotes representam os dois mais importantes dos quatro tipos de
transação MTP. Para transações de Operação, oCódigo de operaçãocampo é selecionado no
Códigos Opdicionário definido anteriormente. Da mesma forma, as transações de resposta usam
oResCodesdicionário.
Embora esses objetos descrevam os pacotes usados pelo fuzzer, eles não
implementam a geração de entrada inteiramente por conta própria. Olle implementa
o restante da geração de entrada noexemplos/mtp_fuzzer.pyArquivo. Segue o código
fonte.
31 trans = struct.unpack("I", os.urandom(4))[0] r =
32 struct.unpack("H", os.urandom(2))[0] opcode =
33 OpCodes.items()[r% len(OpCodes)][1] if opcode ==
34 OpCodes["CloseSession"]:
35 opcode = 0
36 cmd = Container()/fuzz(Operation(OpCode=opcode,
TransactionID=trans, SessionID=dev.current_session()))
Processando Entradas
27 enquanto Verdadeiro:
[...]
38 dev.send(cmd)
39 resposta = dev.read_response(trans)
Nas linhas 16 a 20, Olle abre uma sessão com o dispositivo MTP. Este processo consiste em
enviar umOperaçãopacote usando oOpenSessioncódigo de operação seguido pela leitura de um
Respostapacote. Conforme mostrado nas linhas 38 e 39, isso realmente é tudo o que é feito para
entregar insumos para processamento. A típica relação mestre-escravo USB entre o host e o
dispositivo facilita o processamento de entradas em comparação com outros tipos de fuzzing.
Com as entradas sendo processadas, a única coisa que resta é monitorar o sistema em busca de
mau comportamento.
Teste de monitoramento
O fuzzing da maioria dos dispositivos USB fornece relativamente poucos meios para monitorar o que
está acontecendo dentro do próprio dispositivo. Os dispositivos Android são diferentes a esse
respeito. É muito mais fácil usar mecanismos de monitoramento típicos no Android. Na verdade, os
métodos discutidos anteriormente neste capítulo funcionam muito bem. Ainda assim, conforme
mencionado na seção anterior “Desafios de Fuzzing USB”, o dispositivo pode redefinir o barramento
USB ou parar de responder. Estas situações requerem tratamento especial.
A ferramenta usb-device-fuzzing do Olle não faz nenhum monitoramento no próprio
dispositivo. Este fato não é surpreendente, pois ele não estava mirando em dispositivos Android
quando desenvolveu seu fuzzer. No entanto, Olle não mede esforços para monitorar o próprio
dispositivo do host. oDispositivo MTPclasse implementa um método chamadoEstá vivo
para manter o controle sobre se o dispositivo é responsivo. Nesse método,
Olle primeiro verifica se o dispositivo está ativo usando oBulkPipeclasse.
Capítulo 6-Encontrando Vulnerabilidades com o Teste Fuzz 203
Revisão: '0'
pid: 398, tid: 413, nome: MtpServer >>> android.process.media <<< sinal 11 (SIGSEGV),
código 1 (SEGV_MAPERR), falha addr 66f9f002
r0 5a3adb58 r1 66f92008 r2 66f9f000 r3 0000cff8
r4 66fa2dd8 r5 000033fb r6 5a3adb58 r7 00009820
r8 220b0ff6 r9 63ccbef0 sl 63ccc1c4 fp 63ccbef0
ip 63cc3a11 sp 6a8e3a8c lr 63cc3fc9 pc 63cc3d2a cpsr 000f0030
Olhando mais de perto mostrou que este foi um acidente inofensivo, mas o fato de que um
acidente aconteceu tão rapidamente indica que pode haver outros problemas à espreita.
204 Capítulo 6-Encontrando Vulnerabilidades com o Teste Fuzz
Deixamos fuzzing adicional contra o MtpServer, outros protocolos USB, dispositivos e assim por
diante para você, se estiver interessado. Em suma, esta seção mostra que mesmo a aplicação de
fuzzers públicos existentes pode encontrar bugs no Android.
Resumo
O capítulo foi completado com discussões aprofundadas de três fuzzers. Dois desses
fuzzers foram desenvolvidos especificamente para este capítulo. O último fuzzer era um
fuzzer público que era simplesmente direcionado a um dispositivo Android. Em cada caso,
o fuzzer levou à descoberta de problemas no código subjacente. Isso mostra que o fuzzing
é uma técnica eficaz para descobrir bugs e vulnerabilidades de segurança à espreita
dentro de dispositivos Android.
O próximo capítulo mostra como obter uma compreensão mais profunda de bugs e
vulnerabilidades por meio de depuração e análise de vulnerabilidade. A aplicação dos
conceitos permite que você colete resultados de fuzz para bugs de segurança, abrindo
caminho para transformá-los em exploits funcionais.
APÓS
CH 7
Depuração e A analisando
Vulna raivas
É muito difícil — possivelmente impossível — criar programas livres de bugs. Quer o objetivo
seja extinguir bugs ou explorá-los, a aplicação liberal de ferramentas e técnicas de depuração é
o melhor caminho para entender o que deu errado. Os depuradores permitem que os
pesquisadores inspecionem programas em execução, verifiquem hipóteses, verifiquem o fluxo
de dados, capturem estados de programas interessantes ou até modifiquem o comportamento
em tempo de execução. No setor de segurança da informação, os depuradores são essenciais
para analisar as causas da vulnerabilidade e julgar a gravidade dos problemas.
Este capítulo explora os vários recursos e ferramentas disponíveis para depuração no
sistema operacional Android. Ele fornece orientação sobre como configurar um ambiente
para obter a máxima eficiência durante a depuração. Usando algum código de exemplo e
uma vulnerabilidade real, você percorre o processo de depuração e vê como analisar
falhas para determinar sua causa raiz e capacidade de exploração.
205
206 Capítulo 7-Depuração e análise de vulnerabilidades
Procure documentação sobre o destino específico, protocolos que o destino usa, formatos de
arquivo que o destino oferece suporte e assim por diante. Em geral, quanto mais você souber,
maior a chance de um resultado bem-sucedido. Além disso, ter documentação facilmente
acessível durante a análise geralmente ajuda a superar dificuldades inesperadas rapidamente.
O código-fonte para o destino pode ser inestimável durante a análise. A leitura do código-
fonte geralmente é muito mais eficiente do que o código assembly de engenharia reversa, que
geralmente é muito tedioso. Além disso, o acesso ao código-fonte oferece a capacidade de
reconstruir o destino com símbolos. Conforme discutido na seção “Depurando com símbolos”
mais adiante neste capítulo, os símbolos possibilitam a depuração no nível do código-fonte. Se o
código-fonte para o próprio destino não estiver disponível, procure o código-fonte de produtos
concorrentes, trabalhos derivados ou precursores antigos. Embora eles provavelmente não
combinem com a montagem, às vezes você tem sorte. Programadores diferentes, mesmo com
estilos muito diferentes, tendem a abordar certos problemas da mesma maneira. No final, cada
pequena informação ajuda.
Os binários são úteis por dois motivos. Primeiro, os binários de alguns dispositivos
contêmsímbolos. Os símbolos fornecem informações valiosas sobre funções, como nomes
de funções, bem como nomes e tipos de parâmetros. Os símbolos preenchem a lacuna
entre o código-fonte e o código binário. Segundo, mesmo sem símbolos, os binários
fornecem um mapa para o programa. O uso de ferramentas de análise estática para fazer
engenharia reversa de binários gera uma riqueza de informações. Por exemplo, os
desmontadores reconstroem os dados e controlam o fluxo do binário. Eles facilitam a
navegação no programa com base no fluxo de controle, o que facilita a orientação no
depurador e a localização de locais interessantes do programa.
Os símbolos são mais importantes em sistemas baseados em ARM do que em sistemas x86.
Conforme discutido no Capítulo 9, os processadores ARM têm vários modos de execução. Além de
nomes e tipos, símbolos também são usados para codificar o modo de processador usado para
executar cada função. Além disso, os processadores ARM geralmente armazenam constantes readonly
usadas por uma função imediatamente após o próprio código da função. Os símbolos também são
usados para indicar onde estão esses dados. Esses tipos especiais de símbolos são particularmente
importantes durante a depuração. Os depuradores encontram problemas quando não têm acesso a
símbolos, especialmente ao exibir rastreamentos de pilha ou inserir pontos de interrupção. Por
exemplo, a instrução usada para instalar um ponto de interrupção difere entre os modos do
processador. Se o errado for usado, isso pode levar a uma falha do programa, a perda do ponto de
interrupção ou até mesmo a uma falha do depurador.
Capítulo 7-Depuração e análise de vulnerabilidades 207
UMAconjunto de ferramentasé uma coleção de ferramentas que são usadas para desenvolver um
produto. Normalmente, uma cadeia de ferramentas inclui um compilador, vinculador, depurador e
quaisquer bibliotecas de sistema necessárias. Simplificando, construir uma cadeia de ferramentas ou
escolher uma existente é o primeiro passo para construir seu código. Para os propósitos deste
capítulo, o depurador é o componente mais interessante. Como tal, você precisa escolher uma cadeia
de ferramentas viável de acordo.
Para Android, a entidade que cria um dispositivo específico seleciona a cadeia de
ferramentas durante o desenvolvimento. Como um pesquisador tentando depurar a saída do
compilador, a escolha afeta você diretamente. Cada cadeia de ferramentas representa um
instantâneo das ferramentas que contém. Em alguns casos, versões diferentes da mesma
cadeia de ferramentas são incompatíveis. Por exemplo, usar um depurador da versão A em um
binário produzido por um compilador da versão B pode não funcionar ou pode até causar o
travamento do depurador. Além disso, muitas cadeias de ferramentas têm vários bugs. Para
minimizar os problemas de compatibilidade, é recomendável usar a mesma cadeia de
ferramentas que o fabricante usou. Infelizmente, determinar exatamente qual cadeia de
ferramentas o fabricante usou pode ser difícil.
Nos ecossistemas Android e ARM Linux, há uma variedade de depuradores para
escolher. Isso inclui projetos de código aberto, bem como produtos comerciais. A
Tabela 7-1 descreve várias das ferramentas que incluem um depurador compatível
com ARM Linux.
208 Capítulo 7-Depuração e análise de vulnerabilidades
FERRAMENTA DESCRIÇÃO
IDA Pro IDA Pro é um produto desmontador comercial que inclui um servidor de
depuração remoto para Android.
Debootstrap Mantida pelo Projeto Debian, esta ferramenta permite executar o GNU
Debugger (GDB) em um dispositivo.
Linaro Linaro fornece cadeias de ferramentas para várias versões do Android desde o
Gingerbread.
RVDS A cadeia de ferramentas do compilador oficial do ARM é comercial, mas cópias de avaliação estão
disponíveis.
Fonte Anteriormente Sourcery G++, a cadeia de ferramentas da Mentor Graphics está disponível
nas edições de avaliação, comercial e Lite.
Android O Android Native Development Kit (NDK) oficial permite que os desenvolvedores de aplicativos
NDK incluam código nativo em seus aplicativos.
AOSP O repositório Android Open Source Project (AOSP) inclui uma cadeia de ferramentas
Pré-construído pré-criada que é usada para criar imagens de firmware AOSP.
O recurso de depuração mais simples fornecido pelo Android é o log do sistema. O acesso
ao log do sistema é feito executando ologcatutilitário no dispositivo. Também é acessível
através dologcatComando do dispositivo Android Debug Bridge (ADB). Apresentamos esse
recurso no Capítulo 2 e o usamos nos Capítulos 4 e 6 para observar vários eventos do
sistema. Monitorar o log do sistema coloca uma infinidade de feedback em tempo real,
incluindo exceções e despejos de memória, na frente e no centro. É altamente
recomendável monitorar o log do sistema sempre que você fizer algum teste ou
depuração em um dispositivo Android.
Registros do sistema
D/AndroidRuntime: Desligando a VM
W/dalvikvm: threadid=1: thread saindo com exceção não capturada
(grupo=0x4001e560)
E/AndroidRuntime: EXCEÇÃO FATAL: main
E/AndroidRuntime: java.lang.RuntimeException: Erro ao receber a intenção de transmissão
{ act=android.intent.action.MEDIA_MOUNTED dat=file:///sdcard/nosuchfile } em
com.motorola.usb.UsbService$1@40522c10 E/
AndroidRuntime: em android.app.LoadedApk$ReceiverDispatcher$Args.
corre
(CarregadoApk.java:722)
E/AndroidRuntime: em android.os.Handler.handleCallback(Handler.
java:587)
E/AndroidRuntime: em android.os.Handler.dispatchMessage(Handler.
java:92)
E/AndroidRuntime: em android.os.Looper.loop(Looper.java:130) em
E/AndroidRuntime:
android.app.ActivityThread.main(ActivityThread.java:3821) E/AndroidRuntime:
em java.lang.reflect.Method.invokeNative(Native
Método)
E/AndroidRuntime: em java.lang.reflect.Method.invoke(Method.
java:507)
E/AndroidRuntime: no
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
(ZygoteInit.java:839)
E/AndroidRuntime: no
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) E/AndroidRuntime:
em dalvik.system.NativeStart.main(Método Nativo)
E/AndroidRuntime: Causado por: java.lang.ArrayIndexOutOfBoundsException E/
AndroidRuntime: em java.util.ArrayList.get(ArrayList.java:313) em
E/AndroidRuntime: com.motorola.usb.UsbService.onMediaMounted
(UsbService.java:624)
E/AndroidRuntime: no
com.motorola.usb.UsbService.access$1100(UsbService.java:54) E/
AndroidRuntime: no
com.motorola.usb.UsbService$1.onReceive(UsbService.java:384) E/
AndroidRuntime: em android.app.LoadedApk$ReceiverDispatcher$Args.
corre
(CarregadoApk.java:709)
E/AndroidRuntime: . . . 9 mais
Lápides
Quando ocorre uma falha no código nativo no Android, o daemon do depurador prepara um
breve relatório de falha e o grava no log do sistema. Além disso,depuradotambém salva o
relatório de falha em um arquivo chamadolápide. Esses arquivos estão localizados no
210 Capítulo 7-Depuração e análise de vulnerabilidades
backtrace:
# 00 0001b060
computador /system/lib/libc.so (write+12) /system/lib/
# 01 0001fdd3
computador libc.so (__sflush+54) /system/lib/libc.so
# 02 0001fe61
computador (fflush+60) /system/lib/libc.so
# 03 00020cad
computador
# 04 00022291
computador /system/lib/libc.so
...
Depuração Remota
eles não têm interfaces amigáveis ao depurador. Como tal, é fácil ver por que a
depuração remota é preferida.
Usar o Eclipse para depurar um aplicativo Android é fácil e direto. O Android SDK
vem com vários aplicativos de amostra que ajudam você a se familiarizar com o
ambiente Eclipse. No entanto, um aplicativo simples “Hello World” está incluído
nos materiais deste capítulo no site do livro:www.wiley.com/go/
androidhackershandbook.Usamos este aplicativo para fins demonstrativos ao longo
desta seção. Para acompanhar, importe oOlá Mundoprojeto em seu espaço de
trabalho do Eclipse u
Área de trabalho.
mostrado na Fig
Para começar a depurar o aplicativo, clique no ícone Depurar como na barra de ferramentas
- aquele que se parece com um bug - para abrir a perspectiva Depurar. Como o próprio nome
indica, essa perspectiva é projetada especialmente para depuração. Ele exibe as visualizações
mais
em formação
sion tem lau
Como você pode ver, várias das visualizações exibidas não estão presentes na
perspectiva Java. Na verdade, as únicas visualizações comuns com a perspectiva Java são
as visualizações de estrutura de tópicos e de código-fonte. Na Figura 7-3, o depurador é
parado em um ponto de interrupção colocado na atividade principal. Isso fica evidente na
linha de código realçada e no quadro de pilha selecionado na exibição Depurar. Clicar nos
vários quadros de pilha nessa exibição exibe o código ao redor na exibição do código-
fonte. Clicar em quadros para os quais nenhum código-fonte está disponível exibe um
erro descritivo. A próxima seção descreve como exibir o código-fonte do Android
Framework durante a depuração.
Embora esse método seja direto, muitas coisas estão acontecendo sob o capô. O
Eclipse lida automaticamente com a criação de uma versão de depuração do aplicativo,
instalando o aplicativo no dispositivo, iniciando o aplicativo e anexando o depurador. A
depuração de aplicativos em um dispositivo Android normalmente requer o
android:depurável=truesinalizador a ser definido no manifesto do aplicativo, também conhecido
Capítulo 7-Depuração e análise de vulnerabilidades 215
Ocasionalmente, é útil ver como o código do aplicativo está interagindo com o Android
Framework. Por exemplo, você pode estar interessado em saber como o aplicativo está
sendo invocado ou como as chamadas para o Android Framework estão sendo
processadas. Felizmente, é possível exibir o código-fonte do Android Framework ao clicar
em quadros de pilha, assim como o código-fonte de um aplicativo é exibido.
A primeira coisa que você precisa para fazer isso é um repositório AOSP inicializado
corretamente. Para inicializar o AOSP corretamente, siga as instruções de compilação da
documentação oficial do Android localizada emhttp://source.android.com/source/building.html.
Ao usar um dispositivo Nexus, como recomendamos, preste atenção especial à
ramificação e à configuração do dispositivo que está sendo usado. Você pode
encontre esses detalhes emhttp://source.android.com/source/building-devices
. html.A etapa final para a inicialização é executar oalmoçocomando. Depois que o
repositório AOSP for inicializado corretamente, prossiga para a próxima etapa.
A próxima etapa envolve a construção de um caminho de classe para o Eclipse. No diretório
raiz do AOSP, execute ofazer idegencomando para construir oidegen.shroteiro. Quando a
compilação estiver concluída, você poderá encontrar o script nodesenvolvimento/ferramentas/idegen
diretório. Antes de executar o script, crie ocaminhos-excluídosarquivo no diretório de
nível superior. Exclua todos os diretórios no nível superior que você não deseja
incluir. Para facilitar esta etapa, um exemplocaminhos-excluídosarquivo, que inclui
apenas o código doestruturasdiretório, está incluído nos materiais que acompanham
este livro. Quando ocaminhos-excluídosarquivo está pronto, execute o
idegen.shroteiro. O seguinte trecho de sessão do shell mostra a saída de uma
execução bem-sucedida:
7-4 mostra Ec
atividadesobre
Depois de seguir as instruções nesta seção, você pode usar o Eclipse para percorrer o
código-fonte do Android Framework. No entanto, alguns códigos foram intencionalmente
excluídos do caminho de classe. Caso seja necessário exibir o código das classes excluídas,
modifique ascaminhos-excluídosArquivo. Da mesma forma, se você determinar que alguns
caminhos incluídos não são necessários para sua depuração
Capítulo 7-Depuração e análise de vulnerabilidades 217
venha com t