Pergunta

Minha pergunta é bastante direta:Você é um arquivo executável que gera "Acesso concedido" ou "Acesso negado" e pessoas mal-intencionadas tentam entender seu algoritmo ou consertar suas entranhas para fazer você dizer "Acesso concedido" o tempo todo.

Após esta introdução, você deve estar se perguntando o que estou fazendo.Ele vai quebrar o Diablo3 quando for lançado?Posso apaziguar suas preocupações, não sou um desses malucos.Meu objetivo são crackmes.

Crackmes podem ser encontrados - por exemplo - www.crackmes.de.Um Crackme é um pequeno executável que (na maioria das vezes) contém um pequeno algoritmo para verificar uma serial e gerar "Acesso concedido" ou "Acesso negado" dependendo da serial.O objetivo é fazer com que essa saída executável tenha "Acesso concedido" o tempo todo.Os métodos que você pode usar podem ser restritos pelo autor - sem correção, sem desmontagem - ou envolver qualquer coisa que você possa fazer com um editor binário, objdump e hexadecimal.Quebrar crackmes é definitivamente uma parte da diversão, no entanto, como programador, estou me perguntando como você pode criar crackmes que são difíceis.

Basicamente, acho que o crackme consiste em duas partes principais:uma certa verificação serial e o código circundante.

Tornar a verificação serial difícil de rastrear apenas usando assembly é muito possível, por exemplo, tenho a ideia de tomar a serial como entrada para um microprocessador simulado que deve terminar em um determinado estado para que a serial seja aceita.Por outro lado, pode-se baratear e aprender mais sobre formas criptograficamente fortes de proteger esta parte.Assim, tornar isso difícil o suficiente para fazer o atacante tentar corrigir o executável não deve ser difícil.

No entanto, a parte mais difícil é proteger o binário.Vamos supor uma verificação serial perfeitamente segura que não pode ser revertida de alguma forma (é claro que sei que pode ser revertida, na dúvida, você arranca partes do binário que tenta quebrar e joga séries aleatórias nele até que ele aceite).Como podemos evitar que um invasor simplesmente substitua os saltos no binário para fazer com que nosso binário aceite qualquer coisa?

Tenho pesquisado um pouco sobre esse assunto, mas a maioria dos resultados sobre segurança binária, binários autoverificáveis ​​e coisas assim terminam em artigos que tentam impedir ataques a um sistema operacional usando binários comprometidos.assinando certos binários e validando essas assinaturas com o kernel.

Meus pensamentos atualmente consistem em:

  • verificando locais explícitos no binário como saltos.
  • verificar partes do binário e comparar as somas de verificação calculadas em tempo de execução com elas.
  • tenha verificações de tempo de execução positivas e negativas para suas funções no código.Com efeitos colaterais na verificação serial.:)

Você consegue pensar em mais maneiras de incomodar um possível invasor por mais tempo?(claro, você não pode mantê-lo afastado para sempre, em algum momento, todas as verificações serão quebradas, a menos que você consiga quebrar um gerador de checksum ao ser capaz de incorporar a soma de verificação correta para um programa no próprio programa, hehe)

Foi útil?

Solução

Você está entrando em "técnicas anti-reversor". E é uma arte basicamente. Pior é que, mesmo que você pique os novatos, existem "plugins de reversão anti-anti-anti" para Olly e Ida Pro, eles podem baixar e ignorar grande parte de suas contramedidas.

As medidas de contador incluem detecção de depurador por APIs de depurador de armadilhas ou detecção de 'passo único'. Você pode inserir o código que, depois de detectar um quebra de depurador, continua a funcionar, mas começa a agir em momentos aleatórios muito mais tarde no programa. É realmente um jogo de gato e mouse e os biscoitos têm uma vantagem significativa.

Verificação de saída...http://www.openrce.org/reference_library/anti_reversing - Parte do que está lá fora.

http://www.amazon.com/reversing-secrets-engineering-eldad-eilam/dp/0764574817/ - Este livro tem uma informação anti-reversor muito boa e passa pelas técnicas. Ótimo lugar para começar se você estiver sendo revertido em geral.

Outras dicas

Eu acredito que essas coisas geralmente são mais problemáticas do que valem a pena.

Você gasta muito esforço escrevendo código para proteger seu binário. Os bandidos gastam menos esforço quebrando -o (geralmente são mais experientes do que você) e depois liberam o crack para que todos possam ignorar sua proteção. As únicas pessoas que você irritará são aquelas honestas que são incomodadas por sua proteção.

Basta ver a pirataria como um custo de negócios - o custo incremental do software pirateado é zero se você garantir que todo o suporte seja feito apenas para pagar clientes.

Há tecnologia TPM: TPM na Wikipedia

Ele permite armazenar as somas de verificação criptográfica de um binário em chip especial, que pode atuar como verificação unidirecional.

Observação: O TPM tem uma espécie de rap ruim porque pode ser usado para o DRM. Mas para especialistas no campo, isso é meio injusto, e há até um T-TPM aberto Grupo que permite que os usuários do Linux controlem exatamente como o chip TPM é usado.

Uma das soluções mais fortes para esse problema é Computação confiável. Basicamente, você criptografaria a aplicação e transmitiria a chave de descriptografia para um chip especial (o Módulo de plataforma confiável), O chip apenas descriptografaria o aplicativo depois de verificar se o computador está em um estado "confiável": sem espectadores/editores de memória, sem depuradores etc. Basicamente, você precisaria de hardware especial para poder apenas ver o programa descriptografado código.

Então, você deseja escrever um programa que aceite uma chave no início e o armazena na memória, recuperando -o do disco. Se for a chave correta, o software funciona. Se for a chave errada, o software trava. O objetivo é que é difícil para os piratas gerar uma chave de funcionamento e é difícil corrigir o programa trabalhar com uma chave não licenciada.

Isso pode realmente ser alcançado sem hardware especial. Considere nosso código genético. Funciona com base na física deste universo. Tentamos invadi-lo, criar drogas, etc., e falhamos miseravelmente, geralmente criando toneladas de efeitos colaterais indesejáveis, porque ainda não nos engenhamos totalmente revertidos no complexo "mundo" em que o "código" genético evoluiu para operar . Basicamente, se você está executando tudo em um processador comum (um "mundo" comum), ao qual todos têm acesso, é praticamente impossível escrever um código tão seguro, como demonstrado pelo software atual sendo tão facilmente rachado.

Para alcançar a segurança no software, você essencialmente teria que escrever sua própria plataforma suficientemente complexa, que outros teriam que reverter completamente e completamente o engenheiro para modificar o comportamento do seu código sem efeitos colaterais imprevisíveis. Depois que sua plataforma for projetada reversa, no entanto, você estaria de volta à estaca zero.

A captura é que sua plataforma provavelmente será executada em hardware comum, o que facilita a sua plataforma, o que, por sua vez, facilita o seu código um pouco mais fácil de reverter o engenheiro. Obviamente, isso pode significar que a barra é aumentada um pouco para que o nível de complexidade exigido da sua plataforma seja suficientemente difícil de reverter o engenheiro.

Como seria uma plataforma de software suficientemente complexa? Por exemplo, talvez após cada 6 operações de adição, a 7ª adição retorna o resultado multiplicado pelo PI dividido pela raiz quadrada do log do módulo 5 da diferença do número total de subtrair e multiplicar operações realizadas desde a inicialização do sistema. A plataforma teria que acompanhar esses números de forma independente, assim como o código em si, para decodificar os resultados corretos. Portanto, seu código seria escrito com base no conhecimento do complexo comportamento subjacente de uma plataforma que você projetou. Sim, ele comia ciclos de processador, mas alguém teria que reverter o engenheiro aquele comportamento surpresa e reengine-o em qualquer novo código para que ele se comportasse corretamente. Além disso, seu próprio código seria difícil de mudar uma vez escrito, porque entraria em colapso na complexidade irredutível, com cada linha, dependendo de tudo o que aconteceu antes. Obviamente, haveria muito mais complexidade em uma plataforma suficientemente segura, mas o ponto é que alguém teria engenharia reversa sua plataforma antes que pudesse reverter o engenheiro e modificar seu código, sem efeitos colaterais debilitantes.

Ótimo artigo sobre proteção contra cópia e proteção da proteção Mantendo os piratas afastados:Implementando proteção contra crack para Spyro:Ano do dragao

A idéia mais interessante mencionada lá e que ainda não foi mencionada são as falhas em cascata - você tem somas de verificação que modificam um único byte que causa falha em outra soma de verificação.Eventualmente, uma das somas de verificação faz com que o sistema trave ou faça algo estranho.Isso faz com que as tentativas de piratear seu programa pareçam instáveis ​​e faz com que a causa ocorra muito longe da falha.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top