Como evitar a engenharia reversa de um arquivo APK?


764

Estou desenvolvendo um aplicativo de processamento de pagamentos para Android e quero impedir que um hacker acesse recursos, ativos ou código-fonte do arquivo APK .

Se alguém alterar a extensão .apk para .zip, poderá descompactá-la e acessar facilmente todos os recursos e ativos do aplicativo. Usando o dex2jar e um descompilador Java, eles também poderão acessar o código-fonte. É muito fácil fazer engenharia reversa de um arquivo APK do Android - para obter mais detalhes, consulte Pergunta sobre estouro de pilha Engenharia reversa de um arquivo APK para um projeto .

Eu usei a ferramenta Proguard fornecida com o Android SDK. Quando faço a engenharia reversa de um arquivo APK gerado usando um keystore assinado e o Proguard, recebo o código ofuscado.

No entanto, os nomes dos componentes do Android permanecem inalterados e alguns códigos, como valores-chave usados ​​no aplicativo, permanecem inalterados. Conforme a documentação do Proguard, a ferramenta não pode ofuscar os componentes mencionados no arquivo Manifest.

Agora minhas perguntas são:

  1. Como posso impedir completamente a engenharia reversa de um APK do Android? Isso é possível?
  2. Como posso proteger todos os recursos, ativos e código-fonte do aplicativo para que os hackers não possam invadir o arquivo APK de forma alguma?
  3. Existe uma maneira de tornar o hacking mais difícil ou até impossível? O que mais posso fazer para proteger o código fonte no meu arquivo APK?

120
Parece que você pode estar usando "segurança por obscuridade" se o seu esquema de processamento de pagamentos depender da operação do segredo restante do cliente.
precisa

43
Você já pensou em escrever as partes importantes do código em C / C ++ e adicioná-las como uma biblioteca compilada? Eles podem ser desmontados no código de montagem, mas a engenharia reversa de uma grande biblioteca de montagem é extremamente demorada.
Leo


60
Bem-vindo à questão fundamental da criação de qualquer ativo digital. Os hackers podem chegar ao nível de instruções da máquina; portanto, se um computador puder ler o arquivo, ele poderá ser aberto / copiado por hackers, sem ofuscação ou DRM, poderá parar completamente um determinado hacker. Se você precisar de segurança, verifique se as chaves privadas nunca estão na fonte e saiba no estágio de design que apenas o isolamento (hardware remoto e / ou dedicado) pode protegê-las.
Keith

16
Observe que, dependendo do que o seu aplicativo de processamento de pagamentos faz, pode haver uma política regulatória e legal que afeta o seu aplicativo e pode expô-lo a penalidades severas: consulte a conformidade com o PCI, começando com pcicomplianceguide.org/pcifaqs.php#11 .
bloopletech

Respostas:


372

 1. Como posso evitar completamente a engenharia reversa de um APK Android? Isso é possível?

AFAIK, não há nenhum truque para evitar completamente a engenharia reversa.

E também muito bem dito por @inazaruk: Tudo o que você faz com seu código, um invasor em potencial é capaz de alterá-lo da maneira que achar mais viável . Basicamente, você não pode proteger seu aplicativo contra modificações. E qualquer proteção que você colocar lá pode ser desativada / removida.

 2. Como posso proteger todos os recursos, ativos e código fonte do aplicativo para que os hackers não possam invadir o arquivo APK de nenhuma maneira?

Você pode fazer truques diferentes para dificultar os hackers. Por exemplo, use ofuscação (se for código Java). Isso geralmente diminui significativamente a engenharia reversa.

 3. Existe uma maneira de tornar o hacking mais difícil ou até impossível? O que mais posso fazer para proteger o código fonte no meu arquivo APK?

Como todo mundo diz, e como você provavelmente sabe, não há 100% de segurança. Mas o ponto de partida para o Android, incorporado pelo Google, é o ProGuard. Se você tiver a opção de incluir bibliotecas compartilhadas , poderá incluir o código necessário em C ++ para verificar o tamanho dos arquivos, a integração etc. Se precisar adicionar uma biblioteca nativa externa à pasta da biblioteca do APK em cada compilação, use-a pela sugestão abaixo.

Coloque a biblioteca no caminho da biblioteca nativa, cujo padrão é "libs" na pasta do projeto. Se você construiu o código nativo para o destino 'armeabi' , coloque-o em libs / armeabi . Se foi construído com armeabi-v7a , coloque-o em libs / armeabi-v7a.

<project>/libs/armeabi/libstuff.so

1
Para transação de pagamento que usei o padrão ISO 8585, agora o esquema para esse padrão está no par de valores-chave usando a coleção HashMap de Java e, quando faço engenharia reversa no apk, recebo todo o esquema. É possível evitar o esquema exposto por engenharia reversa. Sua última sugestão de bibliotecas de compartilhamento pode ser útil nesse caso? Doy, você tem links para que eu possa ter acesso às bibliotecas de compartilhamento no Android.
sachin003

4
que tal criptografar suas strings no código e descriptografá-las em tempo de execução? Se você fizer a descriptografia em um servidor remoto, como outras pessoas sugeriram, não terá o problema de que a chave de descriptografia esteja nas fontes.
Kschkem

Sim, a criptografia é uma maneira, mas não é certo que não seja hackeado. Se eu estiver criptografando String para descriptografá-las, preciso de um ID exclusivo no código. e se alguém conseguir descompilar, será muito fácil obter o ID exclusivo.
Bhavesh Patadiya

por que você adicionou coisas editadas ? é tudo regular.
Mohammed Azharuddin Shaikh

@hotveryspicy: sim, agora removi a marca "editada" de answer.i editei minha resposta porque ele queria saber mais sobre como as bibliotecas de compartilhamento são úteis neste caso.
Bhavesh Patadiya

126

AFAIK, você não pode proteger os arquivos no diretório / res mais do que eles estão protegidos no momento.

No entanto, existem etapas que você pode executar para proteger seu código-fonte, ou pelo menos o que ele faz se não tudo.

  1. Use ferramentas como o ProGuard. Isso ofuscará seu código e dificultará a leitura quando descompilado, se não impossível.
  2. Mova as partes mais críticas do serviço para fora do aplicativo e entre em um serviço da Web, oculto por trás de uma linguagem do lado do servidor, como PHP. Por exemplo, se você tiver um algoritmo que levou um milhão de dólares para escrever. Obviamente, você não quer que as pessoas roubem o aplicativo. Mova o algoritmo e faça com que ele processe os dados em um servidor remoto e use o aplicativo para simplesmente fornecê-los. Ou use o NDK para gravá-los nativamente em arquivos .so, que têm muito menos probabilidade de serem descompilados do que apks. Eu não acho que um descompilador para arquivos. So exista a partir de agora (e mesmo que existisse, não seria tão bom quanto os descompiladores Java). Além disso, como @nikolay mencionado nos comentários, você deve usar SSL ao interagir entre o servidor e o dispositivo.
  3. Ao armazenar valores no dispositivo, não os armazene em um formato bruto. Por exemplo, se você tem um jogo e está armazenando a quantidade de moeda do jogo que o usuário possui em SharedPreferences. Vamos assumir que são 10000moedas. Em vez de salvar 10000diretamente, salve-o usando um algoritmo como ((currency*2)+1)/13. Então, em vez de 10000, você salva 1538.53846154nas SharedPreferences. No entanto, o exemplo acima não é perfeito e você terá que trabalhar para encontrar uma equação que não perca dinheiro com erros de arredondamento etc.
  4. Você pode fazer algo semelhante para tarefas do lado do servidor. Agora, por exemplo, vamos usar seu aplicativo de processamento de pagamentos. Digamos que o usuário precise efetuar um pagamento $200. Em vez de enviar um arquivo bruto$200 valor para o servidor, envie uma série de valores menores, predefinidos, que totalizem $200. Por exemplo, tenha um arquivo ou tabela no servidor que iguale palavras com valores. Então, digamos que Charliecorresponde a $47e Johnpara $3. Portanto, em vez de enviar $200, você pode enviar Charliequatro vezes eJohnquatro vezes. No servidor, interprete o que eles significam e adicione-o. Isso impede que um hacker envie valores arbitrários ao seu servidor, pois não sabe qual palavra corresponde a qual valor. Como medida adicional de segurança, você também pode ter uma equação semelhante ao ponto 3 e alterar as palavras-chave a cada nnúmero de dias.
  5. Por fim, você pode inserir código-fonte inútil aleatório no seu aplicativo, para que o hacker procure uma agulha no palheiro. Insira classes aleatórias contendo trechos da Internet ou apenas funções para calcular coisas aleatórias, como a sequência de Fibonacci. Verifique se essas classes são compiladas, mas não são usadas pela funcionalidade real do aplicativo. Adicione o suficiente dessas classes falsas, e o hacker terá dificuldade em encontrar seu código real.

Em suma, não há como proteger seu aplicativo 100%. Você pode dificultar, mas não é impossível. Seu servidor da Web pode estar comprometido, o hacker pode descobrir suas palavras-chave monitorando vários valores de transação e as palavras-chave que você envia para ele, o hacker pode percorrer minuciosamente a fonte e descobrir qual código é falso.

Você só pode lutar, mas nunca vencer.


136
Em vez de fazer truques com os valores que você envia para o servidor, use SSL e valide adequadamente o certificado do servidor. Segurança pela obscuridade é geralmente uma má ideia.
Nikolay Elenkov

48
você pode inserir código-fonte inútil aleatório no seu aplicativo . Isso também não pode ajudar. Isso apenas inchará seu aplicativo, além de dificultar a manutenção.
Anirudh Ramanathan

4
Você também pode usar o código inútil e enviar os dados para o servidor que os descartará. Segurança falsa, talvez, mas um pé no saco para o potencial hacker, certo?
Benoit Duffez

19
Se o seu algoritmo vale um milhão de dólares, o fato de não haver decompilador de .soarquivos não significa que não consigo ler o assembly :) Muitos deles caem na mesma armadilha, ofuscando em vez de se proteger adequadamente. A ofuscação só funciona se não valer a pena o tempo de um invasor, por isso, se você desenvolver algo sobre essas técnicas, é melhor esperar que elas não fiquem populares; caso contrário, você está ferrado, porque de repente sua base de código é inatingível. precisa de grandes mudanças.
Phoshi

23
Não entendo por que essa resposta tem uma pontuação tão alta. 3. e 4. por um lado, são simplesmente bobos e não representam nenhuma segurança.
Matti Virkkunen

117

Em nenhum momento da história da computação, foi possível impedir a engenharia reversa de software quando você fornece uma cópia de trabalho para o invasor. Além disso, com toda a probabilidade, nunca será possível .

Com isso entendido, há uma solução óbvia: não conte seus segredos para o atacante. Embora você não possa proteger o conteúdo do seu APK, o que você pode proteger é qualquer coisa que não distribua. Normalmente, este é um software do servidor usado para coisas como ativação, pagamentos, aplicação de regras e outros bits interessantes de código. Você pode proteger ativos valiosos não distribuindo-os no APK. Em vez disso, configure um servidor que responda às solicitações do seu aplicativo "use" os ativos (o que isso possa significar) e envie o resultado de volta ao aplicativo. Se esse modelo não funcionar para os ativos que você tem em mente, convém repensar sua estratégia.

Além disso, se seu objetivo principal é evitar a pirataria de aplicativos : nem se incomode. Você já gastou mais tempo e dinheiro com esse problema do que qualquer medida antipirataria jamais poderia salvar você. O retorno do investimento para resolver esse problema é tão baixo que não faz sentido sequer pensar nisso.


21
O primeiro parágrafo é a melhor resposta. Se o invasor controlar o hardware, ele sempre poderá derrotar o software de alguma forma. Tudo o que realmente precisa ser protegido deve permanecer no hardware que você controla, é simples assim. E o parágrafo final, sobre o ROI, também está no local.
Daniel Pryden

88

Primeira regra de segurança do aplicativo: qualquer máquina na qual um invasor obtenha acesso físico ou eletrônico irrestrito agora pertence ao invasor, independentemente de onde ele esteja ou do que você pagou por ele.

Segunda regra de segurança do aplicativo: qualquer software que deixe os limites físicos dentro dos quais um invasor não pode penetrar agora pertence ao invasor, independentemente de quanto tempo você gastou para codificá-lo.

Terceira regra: qualquer informação que deixe os mesmos limites físicos que um invasor não pode penetrar agora pertence ao invasor, por mais valioso que seja para você.

Os fundamentos da segurança da tecnologia da informação são baseados nesses três princípios fundamentais; o único computador verdadeiramente seguro é aquele trancado em um cofre, dentro de uma gaiola de Farraday, dentro de uma gaiola de aço. Existem computadores que passam a maior parte de suas vidas de serviço exatamente nesse estado; uma vez por ano (ou menos), eles geram as chaves privadas para autoridades de certificação raiz confiáveis ​​(na frente de uma série de testemunhas com câmeras gravando cada centímetro da sala em que estão localizadas).

Agora, a maioria dos computadores não é usada nesses tipos de ambientes; eles estão fisicamente abertos, conectados à Internet por um canal de rádio sem fio. Em resumo, eles são vulneráveis, assim como o software deles. Portanto, eles não são confiáveis. Há certas coisas que os computadores e seus softwares precisam saber ou fazer para serem úteis, mas deve-se tomar cuidado para garantir que eles nunca saibam ou façam o suficiente para causar danos (pelo menos não danos permanentes fora dos limites daquela máquina única) )

Você já sabia tudo isso; é por isso que você está tentando proteger o código do seu aplicativo. Mas, aí está o primeiro problema; ferramentas de ofuscação podem tornar o código uma bagunça para um ser humano tentar cavar, mas o programa ainda precisa ser executado; isso significa que o fluxo lógico real do aplicativo e os dados que ele usa não são afetados pela ofuscação. Com um pouco de tenacidade, um invasor pode simplesmente ocultar o código, e isso nem é necessário em certos casos em que o que ele está vendo não pode ser outra coisa senão o que ele está procurando.

Em vez disso, você deve tentar garantir que um invasor não possa fazer nada com seu código, não importa o quão fácil seja para ele obter uma cópia clara dele. Isso significa que não há segredos codificados, porque esses segredos não são secretos assim que o código sai do edifício em que você o desenvolveu.

Esses valores-chave que você codificou permanentemente devem ser removidos do código-fonte do aplicativo. Em vez disso, eles devem estar em um dos três lugares; memória volátil no dispositivo, o que é mais difícil (mas ainda não impossível) para um invasor obter uma cópia offline do; permanentemente no cluster de servidores, ao qual você controla o acesso com mão de ferro; ou em um segundo armazenamento de dados não relacionado ao seu dispositivo ou servidores, como um cartão físico ou nas memórias do usuário (o que significa que eventualmente estará na memória volátil, mas não precisa ser por muito tempo).

Considere o seguinte esquema. O usuário insere suas credenciais para o aplicativo da memória no dispositivo. Infelizmente, você deve confiar que o dispositivo do usuário ainda não foi comprometido por um keylogger ou Trojan; o melhor que você pode fazer nesse sentido é implementar a segurança multifatorial, lembrando informações de identificação difíceis de falsificar sobre os dispositivos que o usuário usou (MAC / IP, IMEI, etc.) e fornecendo pelo menos um canal adicional por qual uma tentativa de login em um dispositivo desconhecido pode ser verificada.

As credenciais, uma vez inseridas, são ofuscadas pelo software cliente (usando um hash seguro) e as credenciais em texto sem formatação são descartadas; eles serviram ao seu propósito. As credenciais ofuscadas são enviadas através de um canal seguro para o servidor autenticado por certificado, que as processa novamente para produzir os dados usados ​​para verificar a validade do logon. Dessa forma, o cliente nunca sabe o que realmente é comparado ao valor do banco de dados, o servidor de aplicativos nunca conhece as credenciais em texto sem formatação por trás do que recebe para validação, o servidor de dados nunca sabe como os dados que armazena para validação são produzidos, e um homem o meio vê apenas palavras sem sentido, mesmo que o canal seguro esteja comprometido.

Uma vez verificado, o servidor transmite de volta um token pelo canal. O token é útil apenas dentro da sessão segura, é composto por ruído aleatório ou uma cópia criptografada (e, portanto, verificável) dos identificadores da sessão, e o aplicativo cliente deve enviar esse token no mesmo canal para o servidor como parte de qualquer solicitação fazer alguma coisa. O aplicativo cliente fará isso muitas vezes, porque não pode fazer nada que envolva dinheiro, dados confidenciais ou qualquer outra coisa que possa ser prejudicial por si só; em vez disso, ele deve solicitar ao servidor para executar esta tarefa. O aplicativo cliente nunca gravará nenhuma informação confidencial na memória persistente no próprio dispositivo, pelo menos não em texto sem formatação; o cliente pode solicitar ao servidor pelo canal seguro uma chave simétrica para criptografar quaisquer dados locais, dos quais o servidor se lembrará; em uma sessão posterior, o cliente pode solicitar ao servidor a mesma chave para descriptografar os dados para uso em memória volátil. Esses dados também não serão a única cópia; tudo o que o cliente armazena também deve ser transmitido de alguma forma para o servidor.

Obviamente, isso torna seu aplicativo fortemente dependente do acesso à Internet; o dispositivo cliente não pode executar nenhuma de suas funções básicas sem conexão e autenticação adequadas pelo servidor. Não é diferente do Facebook, na verdade.

Agora, o computador que o invasor deseja é o seu servidor, porque ele, e não o aplicativo / dispositivo do cliente, é algo que pode lhe render dinheiro ou causar dor a outras pessoas por sua diversão. Isso está ok; você ganha muito mais dinheiro gastando dinheiro e esforço para proteger o servidor do que tentando proteger todos os clientes. O servidor pode estar protegido por todos os tipos de firewalls e outros tipos de segurança eletrônica e, além disso, pode ser protegido fisicamente por proteção contra aço, concreto, acesso por cartão / PIN e vigilância por vídeo 24 horas. Seu invasor precisaria ser muito sofisticado para obter qualquer tipo de acesso diretamente ao servidor, e você (deveria) saberia imediatamente.

O melhor que um invasor pode fazer é roubar o telefone e as credenciais de um usuário e efetuar login no servidor com os direitos limitados do cliente. Caso isso aconteça, assim como a perda de um cartão de crédito, o usuário legítimo deve ser instruído a ligar para um número 800 (de preferência fácil de lembrar, e não no verso de um cartão que levaria na bolsa, na carteira ou na maleta que poderia ser roubados juntamente com o dispositivo móvel) de qualquer telefone que eles possam acessar que os conecte diretamente ao serviço ao cliente. Eles afirmam que o telefone foi roubado, fornecem algum identificador exclusivo básico e a conta está bloqueada, todas as transações que o invasor pode ter sido processado são revertidas e o invasor volta à estaca zero.


1
resposta perfeita !! Eu simplesmente amei o seu jeito de obter dados do servidor com algum token criptografado, acho que é quase impossível decodificar depois disso.
Dharam

Eu sei que isso é um pouco tarde, mas que tal acessar a parte acessando o servidor. Serviços como o Microsoft azure fornecem algo assim para acessar o servidor: MobileServiceClient mClient = new MobileServiceClient ("MobileServiceUrl", // Substitua pelo URL do site acima "AppKey", // substitua pela Chave do Aplicativo) e praticamente qualquer pessoa que tem acesso ao que pode acessar a sua edição final servidor que
edwinj

@edwinj - Não há problema na ciência da computação que não possa ser resolvido com outra camada de indireção. Seu snippet fornece a idéia básica para acessar um serviço de cliente móvel do Azure; Ele fornece um nível básico de segurança contra "drive-bys" da porta da frente da Microsoft. Por sua vez, você pode adicionar camadas adicionais, como exigir uma chave de sessão (basicamente qual é o token criptografado) em qualquer chamada de serviço e, para obter essa chave, elas devem ser autenticadas primeiro com uma combinação de conhecimento das credenciais e do esquema de criptografia.
Keiths

1
Uma das melhores respostas.
debo.stackoverflow

64

 1. Como posso evitar completamente a engenharia reversa de um APK Android? Isso é possível?

Isso não é possível

 2. Como posso proteger todos os recursos, ativos e código fonte do aplicativo para que os hackers não possam invadir o arquivo APK de nenhuma maneira?

Quando alguém altera uma extensão .apk para .zip, depois de descompactar, alguém pode obter facilmente todos os recursos (exceto Manifest.xml ), mas com APKtool é possível obter o conteúdo real do arquivo de manifesto. Novamente, um não.

 3. Existe uma maneira de tornar o hacking mais difícil ou até impossível? O que mais posso fazer para proteger o código fonte no meu arquivo APK?

Novamente, não, mas você pode impedir até algum nível, ou seja,

  • Baixe um recurso da Web e faça algum processo de criptografia
  • Use uma biblioteca nativa pré-compilada (C, C ++, JNI, NDK)
  • Sempre execute algum hash ( chaves MD5 / SHA ou qualquer outra lógica)

Mesmo com Smali, as pessoas podem brincar com o seu código. Em suma, não é POSSÍVEL.


7
@TrevorBoydSmith: A criptografia não ajuda muito quando o sistema operacional é de código aberto e pode ser rooteado. O sistema precisa de uma chave para descriptografar o APK e executar as coisas. E se o sistema tiver uma chave e eu tiver acesso irrestrito ao sistema, então eu sei onde encontrar a chave e posso encontrá-la. Ou seja, agora também tenho a chave .
cHao 13/12/12

4
@TrevorBoydSmith: É a parte "como fazer", que mata toda a idéia. Simplesmente não há como executar o código criptografado diretamente; em algum momento, o código descriptografado deve estar disponível. O que significa (1) deve haver uma chave (à qual eu, como root, provavelmente tenho acesso) e (2) posso até encontrar a cópia clara na RAM e não me preocupar com a criptografia.
cHao 14/12/12

3
@TrevorBoydSmith: O problema é que, neste caso, você simplesmente não pode aumentar o custo o suficiente para que não valha a pena. Não estamos falando de chaves de força bruta aqui; estamos falando de já tê- los - o sistema operacional precisa ter chaves e nós temos o sistema operacional. A única maneira de corrigir isso seria tornar o sistema operacional não rootável. Boa sorte com isso; até a Apple não consegue administrar. :)
Chao

3
@TrevorBoydSmith: Não acho que aumentar o custo em geral seja impossível. Penso (e digo), em particular , que sua sugestão é impossível - porque é . O MATLAB não é Android, e possui certas liberdades que o Android não possui. Em particular, tem ofuscação de lado; é muito mais difícil ocultar uma chave de criptografia. O Android não pode fazer isso. Qualquer pessoa que possua o código-fonte saberia onde as chaves estão ocultas e teria uma ferramenta para recuperá-las dentro de 10 minutos após o anúncio do recurso. Não é apenas possível fazer isso; é absolutamente trivial .
cHao

6
@ TrevevBoydSmith: Eu não insisti em nada disso. O que estou insistindo é que estática, mudando, movendo-se, etc. , não importa . Em um sistema operacional de código aberto, a criptografia sozinha não pode proteger o código de ninguém que possa fazer engenharia reversa. Como eu posso ler o código que faria a descriptografia, independentemente de como a chave é adquirida, usada e / ou armazenada, eu posso ver como você fez e replicá-la - ainda mais facilmente do que eu poderia reverter alguns segredos super secretos. código do aplicativo.
cHao 11/01

37

Não é possível evitar 100% de engenharia reversa do APK do Android, mas você pode usar estas maneiras para evitar a extração de mais dados, como código fonte, ativos do APK e recursos:

  1. Use o ProGuard para ofuscar o código do aplicativo

  2. Use NDK usando C e C ++ para colocar o núcleo do aplicativo e proteger parte do código nos .soarquivos

  3. Para proteger recursos, não inclua todos os recursos importantes na pasta de ativos com APK. Faça o download desses recursos no momento da inicialização do aplicativo.


7
O terceiro é realmente facilitar o trabalho dos atacantes. Cheirar a comunicação em rede é mais fácil do que a engenharia reversa.
obtida em 26/01/2015

Para resolver o problema de um terceiro, pode criptografar o conteúdo baixado e / ou usar uma conexão criptografada (por exemplo, SSL / TLS)
Stradivari

1
Criptografar a conexão protege contra pessoas que detectam ou modificam o tráfego. No caso em que o próprio usuário é malicioso (ou seja, ele tem seu apk e está tentando hackear), ele ainda obtém o conteúdo usando seu aplicativo, extraindo recursos como usuário root; mas sim, ajuda contra simples ataques de farejamento.
21716 Kevin Kevin

Somando a isso: 4) uso dexguard para maior ofuscação mas é pago 5) usar o arquivo OBB por ativos de download em vez de baixar aplicativo, ele vai ajudar a reduzir o tamanho do aplicativo aswell
Ashok Kumar

35

Os desenvolvedores podem seguir as etapas abaixo para impedir que um APK seja roubado de alguma forma,

  • a maneira mais básica é usar ferramentas como ProGuardofuscar seu código, mas até agora, tem sido bastante difícil impedir completamente alguém de descompilar um aplicativo.

  • Também ouvi falar de uma ferramenta HoseDex2Jar . Ele para Dex2Jarao inserir código inofensivo em um APK do Android que confunde, desativa Dex2Jare protege o código da descompilação. De alguma forma, poderia impedir que hackers decompilassem um APK em código java legível.

  • Use algum aplicativo do servidor para se comunicar com o aplicativo apenas quando necessário. Isso poderia ajudar a impedir os dados importantes.

De maneira alguma, você não pode proteger completamente seu código dos possíveis hackers. De alguma forma, você pode dificultar e é uma tarefa frustrante descompilar seu código. Uma das maneiras mais eficientes é escrever no código nativo (C / C ++) e armazená-lo como bibliotecas compiladas.


3
HoseDex2Jar é quase inútil. Apenas 'confunde' o dex2jar e pode ser facilmente bloqueado. smali / apktool, etc. funcionam bem com APKs 'hosed'.
Nikolay Elenkov

@NikolayElenkov Você sabe como o HoseDex2Jar funciona? O que eles usaram para evitar ou confundir o dex2jar. Porque não consigo carregar meu arquivo apk na Web para usar o HoseDex2Jar. Se eu puder fazer algo como HoseDex2Jar para confundir o dex2jar, será difícil hackear usando a ferramenta dex2jar.
sachin003

1
Talvez você tenha entendido errado o que quero dizer: o que o HoseDex2Jar faz é reembalar seu APK para que a popular ferramenta dex2jar não possa (fora da caixa) revertê-lo. No entanto, outras ferramentas podem, e é muito fácil derrotá-lo em geral. Não faz sentido usá-lo. Ninguém mencionou a coisa de Dexguard I (do autor do ProGuard; não é de graça), mas é um trabalho de olhar. Faz mais algumas coisas do que ofuscação "regular".
Nikolay Elenkov

C ++ nunca pode ser revertido? é difícil, mas possível. e existem ferramentas para ajudá-lo, como hex-rays.com/products/decompiler/index.shtml (sim, eles têm a versão ARM. não é assim tão fácil de obter).
precisa

sim, @VikartiAnatra: Eu também mencionou alguma forma, você poderia tornar difícil
Sahil Mahajan Mj

24

Aqui estão alguns métodos que você pode tentar:

  1. Use ofuscação e ferramentas como o ProGuard .
  2. Criptografar parte da fonte e dados.
  3. Use uma soma de verificação incorporada proprietária no aplicativo para detectar violações.
  4. Introduza o código para evitar o carregamento em um depurador, ou seja, permita que o aplicativo detecte o depurador e saia / mate o depurador.
  5. Separe a autenticação como um serviço online.
  6. Usar diversidade de aplicativos
  7. Use a técnica de impressão digital, por exemplo, assinaturas de hardware dos dispositivos de diferentes subsistemas antes de autenticar o dispositivo.

23

 1. Como posso evitar completamente a engenharia reversa de um APK Android? Isso é possível?

Impossível

 2. Como posso proteger todos os recursos, ativos e código fonte do aplicativo para que os hackers não possam invadir o arquivo APK de nenhuma maneira?

Impossível

 3. Existe uma maneira de tornar o hacking mais difícil ou até impossível? O que mais posso fazer para proteger o código fonte no meu arquivo APK?

Mais difícil - possível, mas na verdade será mais difícil principalmente para o usuário médio, que está apenas pesquisando nos guias de hackers. Se alguém realmente deseja invadir seu aplicativo, ele será invadido, mais cedo ou mais tarde.


22

 1. Como posso evitar completamente a engenharia reversa de um APK Android? Isso é possível?

Isso é impossível

 2. Como posso proteger todos os recursos, ativos e código fonte do aplicativo para que os hackers não possam invadir o arquivo APK de nenhuma maneira?

Os desenvolvedores podem tomar medidas como o uso de ferramentas como o ProGuard para ofuscar seu código, mas até agora, tem sido bastante difícil impedir completamente que alguém descompile um aplicativo.

É uma ferramenta realmente excelente e pode aumentar a dificuldade de 'reverter' o seu código enquanto reduz a área de cobertura do seu código.

Suporte integrado ao ProGuard: O ProGuard agora é fornecido com as ferramentas do SDK. Agora, os desenvolvedores podem ofuscar seu código como parte integrante de uma versão.

 3. Existe uma maneira de tornar o hacking mais difícil ou até impossível? O que mais posso fazer para proteger o código fonte no meu arquivo APK?

Enquanto pesquisava, vim a conhecer o HoseDex2Jar . Essa ferramenta protegerá seu código de descompilar, mas parece não ser possível proteger completamente seu código.

Alguns links úteis, você pode consultá-los.


21

A principal questão aqui é que os arquivos dex podem ser descompilados e a resposta é que eles podem ser "mais ou menos". Existem desmontadores como dedexer e smali .

O ProGuard, configurado corretamente, ofuscará seu código. O DexGuard, que é uma versão comercial estendida do ProGuard, pode ajudar um pouco mais. No entanto, seu código ainda pode ser convertido em smali e os desenvolvedores com experiência em engenharia reversa poderão descobrir o que você está fazendo com o smali.

Talvez escolha uma boa licença e imponha a lei da melhor maneira possível.


4
Como observação lateral (isenção de responsabilidade: IANAL) - a licença não protegerá o aplicativo em todas as jurisdições em todas as circunstâncias (por exemplo, em alguns países da Europa, é permitido desmontar para aumentar a compatibilidade).
Maciej Piechotka

12

Seu cliente deve contratar alguém que saiba o que está fazendo, que pode tomar as decisões corretas e orientá-lo.

Falar acima sobre você ter alguma capacidade de alterar o sistema de processamento de transações no back-end é um absurdo - você não deve ter permissão para fazer essas mudanças arquiteturais, por isso não espere poder fazê-lo.

Minha lógica sobre isso:

Como seu domínio é processamento de pagamentos, é seguro supor que o PCI DSS e / ou PA DSS (e possíveis leis estaduais / federais) serão importantes para os seus negócios - para estar em conformidade, você deve mostrar que está seguro. Para ficar inseguro, descubra (por meio de testes) que você não está seguro, conserte, teste novamente, etc. até que a segurança possa ser verificada em um nível adequado = maneira cara, lenta e de alto risco para o sucesso. Para fazer a coisa certa, pense com antecedência, comprometa talentos experientes no trabalho, desenvolva-os de maneira segura e teste, corrija (menos), etc. (menos) até que a segurança possa ser verificada em um nível adequado = barato, rápido, caminho de baixo risco para o sucesso.


8

Como alguém que trabalhou extensivamente em plataformas de pagamento, incluindo um aplicativo de pagamentos móveis (MyCheck), eu diria que você precisa delegar esse comportamento ao servidor, nenhum nome de usuário ou senha para o processador de pagamentos (qualquer que seja) deve ser armazenado ou codificado no aplicativo móvel, é a última coisa que você deseja, porque a fonte pode ser entendida mesmo quando você ofusca o código.

Além disso, você não deve armazenar cartões de crédito ou tokens de pagamento no aplicativo, tudo deve ser delegado novamente a um serviço que você criou, além de permitir mais tarde, ser compatível com PCI com mais facilidade e as empresas de cartão de crédito venceram. respire seu pescoço (como eles fizeram por nós).


7

As outras respostas votadas aqui estão corretas. Eu só quero fornecer outra opção.

Para determinadas funcionalidades que você considera importantes, você pode hospedar o controle WebView no seu aplicativo. A funcionalidade seria implementada no seu servidor web. Parece que está sendo executado no seu aplicativo.


@ Sarel Botha Sim, para telas IMP Eu já usei a visualização na web e sim, essa também é uma maneira de manter a segurança, estou aceitando sua resposta.
sachin003

7

Se queremos tornar a engenharia reversa (quase) impossível, podemos colocar o aplicativo em um chip altamente resistente a violações, que executa todas as coisas sensíveis internamente e se comunica com algum protocolo para possibilitar o controle da GUI no host. Até chips resistentes a violações não são 100% à prova de trincas; eles apenas definem a fasquia muito mais alta que os métodos de software. Obviamente, isso é inconveniente: o aplicativo requer um pouco de verruga USB que segura o chip para ser inserido no dispositivo.

A pergunta não revela a motivação de querer proteger esse aplicativo com tanta inveja.

Se o objetivo é melhorar a segurança do método de pagamento, ocultando quaisquer falhas de segurança que o aplicativo possa ter (conhecido ou não), é completamente errado. Os bits sensíveis à segurança devem, de fato, ser de código aberto, se isso for possível. Você deve facilitar o máximo possível para qualquer pesquisador de segurança que revise seu aplicativo encontrar esses bits e examinar sua operação e entrar em contato com você. Os aplicativos de pagamento não devem conter nenhum certificado incorporado. Ou seja, não deve haver nenhum aplicativo de servidor que confie em um dispositivo simplesmente porque ele possui um certificado fixo de fábrica. Uma transação de pagamento deve ser feita apenas com as credenciais do usuário, usando um protocolo de autenticação de ponta a ponta corretamente projetado, que impede a confiança no aplicativo, na plataforma ou na rede, etc.

Se o objetivo é impedir a clonagem, exceto o chip à prova de violações, não há nada que você possa fazer para proteger o programa de engenharia reversa e cópia, para que alguém incorpore um método de pagamento compatível em seu próprio aplicativo, fornecendo ascender a "clientes não autorizados". Existem maneiras de dificultar o desenvolvimento de clientes não autorizados. Uma seria criar somas de verificação baseadas em instantâneos do estado completo do programa: todas as variáveis ​​de estado, para tudo. GUI, lógica, qualquer que seja. Um programa clone não terá exatamente o mesmo estado interno. Certamente, é uma máquina de estado que possui transições de estado visíveis externamente semelhantes (como pode ser observado por entradas e saídas), mas dificilmente o mesmo estado interno. Um aplicativo de servidor pode interrogar o programa: qual é o seu estado detalhado? (ie me dê uma soma de verificação sobre todas as suas variáveis ​​de estado internas). Isso pode ser comparado com o código do cliente fictício que é executado no servidor em paralelo, passando pelas transições de estado genuínas. Um clone de terceiros precisará replicar todas as alterações de estado relevantes do programa genuíno para fornecer as respostas corretas, o que dificultará seu desenvolvimento.


7

Concordou com @Muhammad Saqib aqui: https://stackoverflow.com/a/46183706/2496464

E o @Mumair fornece boas etapas iniciais: https://stackoverflow.com/a/35411378/474330

É sempre seguro assumir que tudo o que você distribui para o dispositivo do usuário pertence ao usuário. Claro e simples. Você pode usar as mais recentes ferramentas e procedimentos para criptografar suas propriedades intelectuais, mas não há como impedir que uma determinada pessoa 'estude' seu sistema. E mesmo que a tecnologia atual possa dificultar o acesso indesejado, pode haver uma maneira fácil amanhã, ou mesmo na próxima hora!

Assim, aqui vem a equação:

When it comes to money, we always assume that client is untrusted.

Mesmo em uma economia tão simples quanto no jogo. (Especialmente em jogos! Existem mais usuários 'sofisticados' e brechas espalhadas em segundos!)

Como nos mantemos seguros?

A maioria, se não todos, de nossos principais sistemas de processamento (e banco de dados, é claro) localizados no lado do servidor. E entre o cliente e o servidor, estão as comunicações criptografadas, validações etc. Essa é a idéia do thin client.



4

APK esquema de assinatura v2 no Android N

A classe PackageManager agora suporta a verificação de aplicativos usando o esquema de assinatura APK v2. O esquema de assinatura do APK v2 é um esquema de assinatura de arquivo inteiro que melhora significativamente a velocidade de verificação e fortalece as garantias de integridade, detectando alterações não autorizadas nos arquivos APK.

Para manter a compatibilidade com versões anteriores, um APK deve ser assinado com o esquema de assinatura v1 (esquema de assinatura JAR) antes de ser assinado com o esquema de assinatura v2. Com o esquema de assinatura v2, a verificação falha se você assinar o APK com um certificado adicional após assinar com o esquema v2.

O suporte ao esquema de assinatura do APK v2 estará disponível posteriormente na N Developer Preview.

http://developer.android.com/preview/api-overview.html#apk_signature_v2


2
Apk assinatura v2 só impede recursos seja adulterado, mas não faz engenharia reversa mais difícil ...
Louis CAD

1
Além disso, você pode simplesmente remover a assinatura e assiná-la novamente. A assinatura v2 é apenas um bloco de dados no arquivo APK.
Robert

4

Não há como evitar completamente a engenharia reversa de um APK. Para proteger ativos, recursos de aplicativos, você pode usar criptografia.

  • A criptografia tornará mais difícil usá-lo sem descriptografar. Escolher um algoritmo de criptografia forte tornará o crack mais difícil.
  • Adicionando algum código de spoof à sua lógica principal para dificultar o crack.
  • Se você pode escrever sua lógica crítica em qualquer idioma nativo e isso certamente dificulta a descompilação.
  • Usando estruturas de segurança de terceiros como o Quixxi

3

Basicamente, não é possível. Isso nunca será possível. No entanto, há esperança. Você pode usar um ofuscador para fazer com que alguns ataques comuns sejam muito mais difíceis de realizar, incluindo coisas como:

  1. Renomeando métodos / classes (no descompilador você obtém tipos como a.a)
  2. Ofuscando o fluxo de controle (portanto, no descompilador, o código é muito difícil de ler)
  3. Criptografando strings e possivelmente recursos

Tenho certeza que existem outros, mas esses são os principais. Eu trabalho para uma empresa chamada PreEmptive Solutions em um ofuscador .NET . Eles também têm um ofuscador Java que funciona para Android e também um chamado DashO .

A ofuscação sempre tem um preço, no entanto. Notavelmente, o desempenho geralmente é pior e, normalmente, requer mais tempo em torno dos lançamentos. No entanto, se sua propriedade intelectual é extremamente importante para você, geralmente vale a pena.

Caso contrário, sua única opção é fazer com que seu aplicativo Android passe para um servidor que hospede toda a lógica real do seu aplicativo. Isso tem seu próprio compartilhamento de problemas, porque significa que os usuários devem estar conectados à Internet para usar seu aplicativo.

Além disso, não é apenas o Android que tem esse problema. É um problema em todas as lojas de aplicativos. É apenas uma questão de quão difícil é acessar o arquivo do pacote (por exemplo, não acredito que seja muito fácil para os iPhones, mas ainda é possível).


Infelizmente se alguém cortar o cliente (o aplicativo) que seria capaz de ver o formato de comunicação e criar seu próprio servidor :(
Jocky Doe

3

Não é possível evitar completamente o ER, mas, ao torná-los mais complexos internamente, você dificulta que os invasores vejam a operação clara do aplicativo, o que pode reduzir o número de vetores de ataque.

Se o aplicativo manipular dados altamente confidenciais, existem várias técnicas que podem aumentar a complexidade da engenharia reversa do seu código. Uma técnica é usar o C / C ++ para limitar a manipulação fácil do tempo de execução pelo invasor. Existem amplas bibliotecas C e C ++ muito maduras e fáceis de integrar com as ofertas JNI do Android. Um invasor deve primeiro contornar as restrições de depuração para atacar o aplicativo em um nível baixo. Isso adiciona mais complexidade a um ataque. Os aplicativos Android devem ter android: debuggable = ”false” definido no manifesto do aplicativo para impedir a manipulação fácil do tempo de execução por um invasor ou malware.

Verificação de rastreamento - Um aplicativo pode determinar se está sendo rastreado no momento por um depurador ou outra ferramenta de depuração. Se estiver sendo rastreado, o aplicativo poderá executar várias ações possíveis de resposta a ataques, como descartar chaves de criptografia para proteger dados do usuário, notificar um administrador do servidor ou outras respostas desse tipo na tentativa de se defender. Isso pode ser determinado verificando os sinalizadores de status do processo ou usando outras técnicas, como comparar o valor de retorno do ptrace attach, verificar o processo pai, depurar listas negras na lista de processos ou comparar os registros de data e hora em diferentes locais do programa.

Otimizações - Para ocultar cálculos matemáticos avançados e outros tipos de lógica complexa, a utilização de otimizações do compilador pode ajudar a ofuscar o código do objeto para que ele não possa ser facilmente desmontado por um invasor, dificultando a compreensão do código específico. No Android, isso pode ser alcançado com mais facilidade utilizando bibliotecas compiladas nativamente com o NDK. Além disso, o uso de um Ofuscador LLVM ou de qualquer SDK protetor fornecerá melhor ofuscação do código da máquina.

Remoção de binários - A remoção de binários nativos é uma maneira eficaz de aumentar a quantidade de tempo e o nível de habilidade exigidos de um invasor para visualizar a composição das funções de baixo nível do seu aplicativo. Ao remover um binário, a tabela de símbolos do binário é removida, para que um invasor não possa depurar ou fazer engenharia reversa de um aplicativo com facilidade.

E, finalmente, você deve estar ciente sobre ofuscação e ferramentas como o ProGuard.


3

Se seu aplicativo for sensível a isso, considere a parte do processamento de pagamentos no lado do servidor. Tente alterar seus algoritmos de processamento de pagamentos. Use o aplicativo Android apenas para coletar e exibir informações do usuário (ou seja, saldo da conta) e, em vez de processar pagamentos dentro dos códigos java, envie esta tarefa ao seu servidor usando um protocolo SSL seguro com parâmetros criptografados. Crie uma API totalmente criptografada e segura para se comunicar com seu servidor.

Obviamente, ele também pode ser invadido e não tem nada a ver com a proteção dos códigos-fonte, mas considere outra camada de segurança para tornar mais difícil para os hackers enganar seu aplicativo.


2

Os chips TPM (Trusted Platform Module) não devem gerenciar código protegido para você? Eles estão se tornando comuns em PCs (especialmente os da Apple) e podem já existir nos chips de smartphones atuais. Infelizmente, ainda não existe uma API do sistema operacional para utilizá-la. Esperemos que o Android adicione suporte para isso um dia. Essa também é a chave para limpar o DRM de conteúdo (no qual o Google está trabalhando para o WebM).


2

Nada é seguro quando você o coloca à mão dos usuários finais, mas algumas práticas comuns podem dificultar o roubo de dados por parte do invasor.

  • Coloque sua lógica principal (algoritmos) no lado do servidor.
  • Comunicar com servidor e cliente; verifique se a comunicação entre servidor e cliente está protegida por SSL ou HTTPS; ou use outras técnicas de algoritmos de geração de pares de chaves (ECC, RSA). Verifique se as informações confidenciais permanecem criptografadas de ponta a ponta.
  • Use sessões e expire após um intervalo de tempo específico.
  • Criptografar recursos e buscá-los no servidor sob demanda.
  • Ou você pode criar um aplicativo híbrido que acessa o sistema via webviewrecurso de proteção + código no servidor

Múltiplas abordagens; isso é óbvio que você precisa sacrificar desempenho e segurança


2

Eu posso ver essa boa resposta neste tópico. Além de você pode usar o facebook redexpara otimizar o código. Redex trabalha no .dexnível em que o proguard trabalha como .classnível.



1

Como posso proteger todos os recursos, ativos e código-fonte do aplicativo para que os hackers não possam invadir o arquivo APK de forma alguma?

Um arquivo APK é protegido pelo algoritmo SHA-1 . Você pode ver alguns arquivos na pasta META-INF do APK. Se você extrair qualquer arquivo APK e alterar qualquer conteúdo e compactá-lo novamente, e quando você executar esse novo arquivo APK em uma máquina Android, ele não funcionará, porque os hashes SHA-1 nunca serão correspondentes.


Isso é verdade; mas é trivial renunciar ao APK (com um certificado diferente) e tudo funcionará novamente. É possível verificar qual assinatura foi usada para assinar o APK no próprio aplicativo e gerar um erro se o certificado for alterado, mas é apenas um pouco menos trivial editar esse código fora do aplicativo.
David Dada

Isso pode impedir que o dispositivo Android execute o código modificado, mas você ainda pode extrair facilmente o código relevante e escrever um novo código em um PC que faça o que deseja.
Sarel Botha

1

Embora eu concorde que não há uma solução 100% que proteja seu código, a v3 do HoseDex2Jar agora está disponível se você quiser experimentá-lo.


1

Ferramenta: Usando Proguard em seu aplicativo, pode ser restrito a engenharia reversa de seu aplicativo


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.