Pirataria: Cracking de programas, como funciona?

Conceitos básicos

Assim que conheci os computadores fiquei impressionado com a pirataria de software. Como poderia um programa acabar de ser lançado e já possuir uma cópia pirata dele?

Tinha várias suposições para isso: alguma pessoa de dentro das empresas de software deixava vazar o projeto, quem sabe vendia no mercado negro ou ainda o cracker invadia a rede da empresa e furtava o projeto.

Depois conheci a engenharia reversa e vi que nada disso era necessário, era possível alterar o programa sem ter seu código-fonte.

Cracking e engenharia reversa de softwares são conceitos muito ligados, um quase chega a ser sinônimo do outro. Cracking consiste em atacar uma tecnologia de proteção de cópias para conseguir passar por ela.

Crackear programas comerciais é ilegal. Esse artigo não tem a intenção de incentivar o cracking, muito pelo contrário, a ideia é mostrar um pouco como funciona.

Caso você seja desenvolvedor de software ou trabalhe com segurança da informação é recomendável que você possua conhecimentos de cracking para proteger seus próprios sistemas. Tecnologias de proteção de cópias desenvolvidas por pessoas que nunca tentaram crackear um programa nunca serão efetivas.

Até na engenharia reversa de malwares o conhecimento sobre cracking é importante, as vezes é necessário “crackear” o malware para passar por uma criptografia, chamar alguma outra função, desviar o processamento, etc.

Esse artigo é recomendado para os iniciantes do tema. Focarei na técnica mais básica do cracking, que é a de inserir um “remendo” no código do programa para burlar ou passar pela proteção. Ela é conhecida como Patching.

Vamos ver agora na prática como isso funciona.

Ferramentas

Para realizar os procedimentos desse artigo são necessários esses três programas:

 
CrackMe é um tipo de programa feito especificamente para ser crackeado. Para treinarmos cracking não é preciso passar por cima de direitos autorais, existem inúmeros desses programas na Internet. Esse CrackMe foi eu mesmo que fiz, pode ser crackeado e pirateado a vontade. :)

Análise Inicial

O primeiro passo é fazer uma sondagem no programa para descobrir o maior número de informações possíveis. Antes de executar o programa vamos ver se o executável possui algum compactador. O Exeinfo PE é ótimo para fazer isso.


Nenhum compactador encontrado, “Not packed”, e ainda identificou o ambiente de programação utilizado, “Borland C++”.

Agora vamos executar o CrackMe.exe para ver como ele funciona.


Podemos ver dois campos, Nome e Serial, e um botão Registrar. Geralmente quando registramos um programa nos é fornecido um nome (nosso próprio nome, nome da empresa, nome fantasia, etc) e uma chave de números e/ou letras que é o chamado Serial Number.

Vamos inserir algumas informações aleatórias nos campos para testar o funcionamento.


Para todas as informações que inserimos nos campos Nome e Serial foi exibida a Mensagem: “Erro. Serial invalido, tente novamente!”.

Apesar de nosso CrackMe não fornecer muitas informações, ele já nos deu uma muito útil, a mensagem de erro. Ela deve estar próxima do trecho de validação do programa, isso nos dá uma pista de onde procurar no código.

Quando abrimos um arquivo binário em disassemblers são geradas milhares de linhas de código, analisar uma a uma seria inviável. Então agora que descobrimos a mensagem de erro podemos procurá-la diretamente no código para poupar tempo, localizando-a poderemos estar próximos do trecho de validação do registro do programa.

Geralmente as strings (frases) dentro de um programa mesmo após o disassembler mantém a estrutura original. Vamos tentar encontrar a frase da mensagem de erro para prosseguirmos com nosso intento.

Por dentro do código

Vamos abrir o OllyDbg e através da opções Files – Open abrir o CrackMe.exe.


Para buscarmos as strings, no quadrante superior esquerdo clique com o botão direito e em Search for – All referenced text strings.

Na janela que abriu já é possível ver a string que procuramos.


Junto dela existe uma outra string bastante sugestiva. Vamos clicar duas vezes em cima da string de Erro para sermos levados diretamente para o código onde ela é chamada.


Transcrevo abaixo parte do trecho encontrado próximo à mensagem de erro:

004019CF CALL CrackMe.@TForm1@compare

004019D5 TEST AL,AL
004019D7 JE SHORT CrackMe.004019EE

004019D9 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
004019DB PUSH CrackMe.0046320E ; |Title = "Sucesso"
004019E0 PUSH CrackMe.004631CC ; |Text = "Parabens! Programa registrado com suce...”
004019E7 CALL <JMP.&USER32.MessageBoxA>

004019EC JMP SHORT CrackMe.00401A01

004019EE PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
004019F0 PUSH CrackMe.00463238 ; |Title = "Erro"
004019F5 PUSH CrackMe.00463216 ; |Text = "Serial invalido, tente novamente!"
004019FC CALL <JMP.&USER32.MessageBoxA>

00401A01 POP ECX
00401A04 RETN

A primeira vista todos esses códigos podem assustar, mas se formos seguindo linha a linha as instruções poderemos entender a lógica por trás dele. Vou escrever abaixo o mesmo trecho explicando o que cada linha faz:

004019CF CALL CrackMe.@TForm1@compare
-Chama a função “compare” que está no formulário TForm1.

004019D5 TEST AL,AL
-Essa função é a mesma que “CMP AL,0”, o compilador escolhe utilizar o TEST porque ele ocupa menos bytes na memória. Seu significado é: compare o valor 0 (falso) com o valor que está no registrador AL (que é a resposta da função “compare”), ou seja quer saber se a função “compare” retornou falso.

004019D7 JE SHORT CrackMe.004019EE
-Jump if Equal, Pule para o endereço 004019EE se os dois valores da comparação anterior forem iguais (0,0), ou seja, se a função “compare” retornou falso.

004019D9 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
-Na linha anterior ele pula para um endereço a frente caso a comparação seja falsa, logo podemos concluir que se ele não pulou e chegou até essa linha quer dizer que não era falso, ou seja, verdadeiro. Essa linha escolhe o estilo da mensagem que será exibida.

004019DB PUSH CrackMe.0046320E ; |Title = "Sucesso"
- Escolhe o título da mensagem.

004019E0 PUSH CrackMe.004631CC ; |Text = "Parabens! Programa registrado com suce...”
- Escolhe o texto da mensagem.

004019E7 CALL <JMP.&USER32.MessageBoxA>
- Chama e exibe a mensagem padrão da API USER32 do Windows.

004019EC JMP SHORT CrackMe.00401A01
-Jump. Pula para o endereço 00401A01.

004019EE PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
-Se olharmos com atenção esse é o endereço para onde a função JE anteriormente pularia caso o retorno da função “compare” fosse falso. Essa linha escolhe o estilo da mensagem que será exibida.

004019F0 PUSH CrackMe.00463238 ; |Title = "Erro"
- Escolhe o título da mensagem.

004019F5 PUSH CrackMe.00463216 ; |Text = "Serial invalido, tente novamente!"
- Escolhe o texto da mensagem.

004019FC CALL <JMP.&USER32.MessageBoxA>
- Chama e exibe a mensagem padrão da API USER32 do Windows.

00401A01 POP ECX
- Esse é o endereço para onde a função JMP que estava no final do trecho da primeira mensagem (verdadeira) pularia.

00401A04 RETN
- Finaliza a validação e retorna os resultados.

Apesar de a princípio parecer um pouco complicado, esse é o trecho que o compilar gerou em Assembly da famosa instrução IF-ELSE codificada na linguagem C++.

Agora entendemos o que o código faz, simplificando é: chama a função “compare”, se ela retornar “falso” exibe mensagem de Erro, se retornar verdadeiro exibe mensagem de Sucesso.

Qual dessas linhas poderíamos alterar para o programa sempre exibir a mensagem de Sucesso independentemente do valor que inserirmos nos campos Nome e Serial?

Isso poderia ser feito de várias formas, vou apresentar duas soluções.

Como vimos, o trecho principal da validação é esse:

004019D5 TEST AL,AL
004019D7 JE SHORT CrackMe.004019EE

Uma solução seria substituir a instrução JE (Jump if Equal) por JNE (Jump if Not Equal). Inverteria o fluxo, sempre que inserirmos Nome e Serial inválidos o programa exibiria mensagem que o registro havia sido feito com Sucesso.

Outra solução, na minha opinião mais elegante :), seria substituir o JE pela instrução NOP (No Operation). Nesse caso o programa faria a comparação com o TEST mas na linha debaixo não faria nada e continuaria o fluxo normal nas linhas seguintes até chegar na mensagem de registro efetuado com sucesso.

Vamos ver como aplicar essa solução com NOP.

Aplicando o Patch

Com o CrackMe.exe aberto no OllyDbg, vamos clicar uma vez na linha que desejamos alterar para selecioná-la.

004019D7 JE SHORT CrackMe.004019EE

Agora clique duas vezes em cima da instrução JE SHORT. Será exibida a janela “Assemble at 004019D7”.


Nessa janela iremos inserir a instrução que desejamos para substituir a JE. Apague JE SHORT 004019EE e digite NOP. Deixe marcada a opção “Fill with NOP's”.


Um detalhe interessante sobre a opção “Fill with NOP's”. Ela irá adicionar NOP's se a nova instrução for menor que a antiga. Isso porque estamos lidando com código de máquina onde mover até mesmo 1 byte é uma tarefa complicada, muitas referências da linguagem Assembly são relativas, então mover um código poderia invalidar esses endereços relativos.

Agora clique no botão Assemble e no X para fechar a janela.

Pronto, o código já está alterado com nosso Patch mas ainda não foi salvo diretamente no EXE, por enquanto a alteração está válida somente dentro do OllyDbg.

Para torná-la permanente clica com o botão direito em cima da área de código e selecione “Copy to executable – All modifications”. Na janela que abrir escolha “Copy all”. Uma nova janela irá se abrir com o novo executável já com as modificações. Em cima dessa janela clique com o botão direito e escolha “Save file”.

Escolha o nome que desejar e clique em salvar.

Feito! Agora feche o OllyDbg e execute o CrackMe que você salvou. Inseria qualquer informação nos campos Nome e Serial e veja o resultado.


O programa está crackeado! Mesmo sem termos um Nome e Serial válido ele foi registrado. Por mais simples que seja esse tipo de validação, acredite, existem muitos programas que ainda utilizam essa técnica, muitos desses sharewares que baixamos na Internet são similares.

Desafio

Caso tenha chegado até aqui imagino que realmente se interessou pelo assunto. Agora eu proponho um desafio para treinar as habilidades de cracking e engenharia reversa.

A técnica que utilizamos foi a de Patching, que é a mais simples, apenas desviamos da validação. Uma outra técnica bastante conhecida é a de KeyGen (Key Generator). É um programinha que os crackers fazem para gerar serial válido para qualquer nome que for digitado.

Você conseguiria gerar um KeyGen para esse CrackMe? Ou mais simples, você conseguiria me informar um Nome e Serial válido, que não seja necessário alterar o código do CrackMe para exibir a mensagem de Sucesso?

Qualquer dúvida sobre algum trecho que não tenha ficado claro no artigo estou à disposição para esclarecer, fique a vontade para deixar comentários.

Leia a continuação:

Ronaldo Lima
crimesciberneticos.com | twitter.com/crimescibernet

33 comentários:

  1. Muito bom o artigo. Tá show o blog. Continue assim.

    ResponderExcluir
  2. já pensou em escrever um livro? abração

    ResponderExcluir
  3. Daria para pescar o serial neste programa?

    ResponderExcluir
  4. Amigo, por favor desenvolva video aulas referente este assunto que é muito interessante.

    ResponderExcluir
  5. Gostei, segui o tutorial a risca, e foi...crackeado como disse...
    Mas, agora que sei como fazer isso, como treinar para apefeisoar meus programas, "predendo fazr um jogo RPG" Single Player mesmo, apenas atualzação seria na net...
    tem como usar esse metoro para evitar crackeamento? Acredito que sim, como diz ai em cima...Mas como eu posso treinar de varios modos diferente...PQ ainda assembly é RUSSO pra minha pessoa...Abraços a todos. e obg pelo Tutorial.

    ResponderExcluir
  6. Agradeço todos comentários e sugestões.

    Guilherme,
    Livro? Quem sabe um dia. :) Tenho que estudar muito ainda.

    SampaBR,
    Vou pensar nas vídeo aulas para posts futuros. Pescar serial, humm... vc tentou? É um bom caminho para conseguir um serial. :)

    Allan,
    Legal que conseguiu realizar o tutorial. Nesse método você viu que se vc fizer no seu jogo uma validação de serial usando apenas IF-ELSE seu programa estaria muito vulnerável para cracking.
    Pesquise também sobre o método "pescar serial", que é através do debug do programa vc descobrir o serial válido.
    Quando você conhecer vários métodos de cracking pode então criar no seu jogo alternativas onde esse métodos não surtam efeito.

    Uma coisa eu digo, todos os programas são passíveis de cracking, vide as empresas multinacionais que têm seus programas crackeados em pouquíssimo tempo. A diferença é que uns são mais simples de crackear e outros complexos.

    Abraços a todos!
    Continuem participando do Blog.

    ResponderExcluir
  7. Aqui está Ronaldo o keygen em python:
    http://pastebin.com/fWQTwRaA

    É uma rotina do tipo acumulativa, somente acumula e soma as letras do nome e depois temos uma multiplicação simples.

    De qualquer modo, foi um bom texto, espero ver mais por aqui.

    ResponderExcluir
  8. Gu,

    Muito bom, parabens!!
    Ficou show seu script!
    Depois vou fazer um post novo com sua solucao e uma outra que vou mostrar fazendo Ripping do Assembly.

    Grande abraco!

    ResponderExcluir
  9. Estou aguardando amigo, abraço !

    ResponderExcluir
  10. olá ronaldo gostei muito desse toturial aqui postado muito a frente gostaria de falar contigo dá para me adicionares no msn ? sergio-rocha@hotmail.com
    abraço

    ResponderExcluir
  11. Olá Sérgio, agradeço os comentários. Não costumo usar msn mas se quiser podemos conversar por e-mail mesmo: crimesciberneticos@ymail.com. Abraço.

    ResponderExcluir
  12. Ótima dica. Imagino a paciencia ao explicar o que cada linha em assembly faz! Gostei muito, Obrigado!

    ResponderExcluir
  13. Este comentário foi removido por um administrador do blog.

    ResponderExcluir
  14. O comentário anterior foi muito engraçado mas tive que excluir porque tinha muito palavrão.

    ResponderExcluir
  15. Fala Ronaldo aqui está minha solução para o Crack-me abraços
    também tenho um blog se quiser fazer uma visita ou alguma paceria estamos ai!

    http://youtu.be/ZEMccJZREk4

    ResponderExcluir
  16. Ronaldo, tenho que elogia-lo pelo excelente tutorial, sou iniciante na área de TI, mas compreendi perfeitamente toda a explicação algo que geralmente cansa a algumas pessoas é diferencial neste tutorial, meus parabéns continue este ótimo trabalho que forma intelectuais.

    Diêgo Rafa.

    ResponderExcluir
  17. boa noite , sera que alguem me poderia ajudar a perceber este programa, ja tentei tirar uma key e ele nao me da , nao sei se estarei a fazer alguma coisa mal, ou para o que eu quero nao da ...
    tem por ai alguem que perceba ?
    obrigada

    ResponderExcluir
    Respostas
    1. tô percebendo que vc anda fumando muita maconha, ou utilizando-se de muito de alucinógenos

      Excluir
  18. muuuito bom o blog estou tentando aprender tudo . parabens!

    ResponderExcluir
  19. E o seguinte, o que fazer com programas que verifica o serial correto pela internet?
    tipo o SPY VIEW PRO. ja tentei de tudo mais nao consigo registra-lo, a unica coisa que consegui foi para o tempo que ele expirarar.

    ResponderExcluir
  20. cara estou con dificuldade em um programa vc mode me ajudar?

    ResponderExcluir
  21. Boa tarde,

    Sou novo nessa área, mas o programa que estou testando pelo Exeinfo PE não aparece a mensagem: “Not packed”
    Então, nesse caso, qual seria o procedimento?

    Obrigado desde já!

    ResponderExcluir
    Respostas
    1. Dei uma olhada com calma e o instalador com serial foi comprimido no Microsoft Visual C++ 6.0 [Overlay]. Como não consegui o serial para instalar, tentei extrair o conteúdo do arquivo .exe (instalador) mas não foi possível por esse motivo.

      Excluir
  22. eu mudei apos o test mandar direto para o endereço de mensagem de ok:
    JMP SHORT 004019D9
    mandando direto para a mensagem de parabéns , dando certo

    ResponderExcluir
  23. Olá Ricardo, admiro muito seu trabalho e ensinos na área de Engenharia Reversa.. sou leigo no assunto, mas sua explicação foi nota 10.. até consegui resolver o desafio de descobrir um nome e serial válido para o programa CrackMe.
    No teste usei meu nome para gerar um serial válido...

    Nome: savio
    Serial: 7862400

    Me interessei muito pelo assunto, gostaria de conhecer mais sobre E.R...
    Tem algum livro que eu possa encontrar para download relacionado a este tema? Até mais

    ResponderExcluir
  24. Por favor, alguem poderia me dar a certeza se empresas podem utilizar programas daqueles que sao gratuitos mas precisem de serial e que na forma mais exata nao sao pagos??? isso é considerado crime? meu e-mail é jleozim@gmail.com

    ResponderExcluir
  25. Por favor, alguem poderia me dar a certeza se empresas podem utilizar programas daqueles que sao gratuitos mas precisem de serial e que na forma mais exata nao sao pagos??? isso é considerado crime? meu e-mail é jleozim@gmail.com

    ResponderExcluir
  26. Amigo por fvr faz um vídeo demonstrativo e manda o link aq pra nós
    pq um vídeo a pessoa saka melhor.

    Faz um tuto ensinado como quebrar a proteção d um programa q não aparece a msg d erro(aquela caixinha d diálogo)

    ResponderExcluir
  27. o problema é que isso é de 2010.parei no processo do disassembler pq ta meio conpicado e sem as imagens entao...agradeceria qualquer ajuda.

    ResponderExcluir
  28. ESSE ASSUNTO E DE 2010 MAIS AINDA ASSIM É MUITO BOM.

    VALEW RICARDO PELO POST.

    SERIA BOM SE VC POSTASSE OUTRO...

    AI GALERA TE UM SITE SHOW DE (ER)

    http://fergonez.net/tutoriais/fergo/reveng

    ResponderExcluir

Related Posts Plugin for WordPress, Blogger...