07. Armadilhas e alteração de código

Alguns aplicativos possuem certas proteções contra programas de debugging ( OllyDBG, SoftICE, WinDbg, etc. ), como é o caso do nosso alvo. A proteção que ele usa é bem simples, simplesmente gera uma exceção ( um desvio no código, que diversas vezes gera um erro no programa ) que exibe uma mensagem de texto avisando que estamos usando um debugger e encerra o programa após isso.

Nosso alvo:

Download: crackme2.zip
( créditos ao mucki )

Abra o alvo no Olly e aperte F9 para iniciar a execução. Logo de cara você nota que o programa não inicia e pausa em 401047. Repare no rodapé do Olly que apareceu algo assim:

Single step event at crackme2.00401047 - use Shift+F7/F8/F9 to pass exception to program

Isso indica que o programa encontrou uma "exception" e parou antes de ela ser executada. Se você apertar F9, ele vai continuar e vai exibir a MessageBox da imagem logo acima, e encerra o programa após isso. O Olly permite que você "pule" a exceção e continue rodando o programa normalmente, basta apertar Shift+F9. Agora você tem o programa funcionando corretamente.

Já passamos o sitema anti-debugging, vamos então prosseguir e alterar o nosso código. O que o aplicativo faz é pedir um nome e senha, comparar e verificar se as informações são coerentes. Se for, ele exibe uma mensagem dizendo que o código está correto. Caso não seja, ele indica que o serial não é válido.

Ao invés de setar um breakpoint na chamada da função MessageBox ( para nos levar ao local onde a key é checada ), vamos usar uma outra aproximação ( a da MsgBox é mais direta, mas vamos variar um pouco ). Vamos procurar por outras funções clássicas. Aperte CTRL+N para abrir a janela com os nomes das funções usadas. Analise a lista e repare na função "lstrcmp". O que ela faz é comparar 2 strings, se forem iguais, ela seta a "Zero Flag" para verdadeiro. Selecione a "lstrcmp" na lista e aperte ENTER. Uma nova janela apareceu com todas as ocorrências do uso dela no código. Como só tem 2 ocorrências, é só tentar em uma das duas para ver se fomos levados para o local correto. Selecione a primeira ocorrência e aperte ENTER novamente. Caímos aqui

Hum, parece que estamos no local certo. Repare nas funções "em volta" dela. Temos diversas funções típicas, como a formatação de um texto no formato de serial ( wsprintfA ), GetDlgItemTextA ( pega o nosso serial para comparar ), e as 2 MsgBox indicando se a serial é válida ou não.

Que tal alterar o código da MsgBox? Ao invés de ela exibir a mensagem de serial inválida, ela exibe o serial correto. Vamos fazer isso.

Repare na função "lstrcmpA" novamente, ela precisa de 2 argumentos ( as 2 strings ) para serem comparadas. Uma das strings obviamente é a serial que nós digitamos e a outra é a serial válida. Uma das strings está armazenada em 004060BA ( primeiro argumento puxado ) e a outra está em 004062B6 ( segundo argumento ). Em qual dos 2 argumentos está a serial correta? Ou você analisa o código da geração da key ( logo acima ) ou você vai por tentativa e erro ( testa com um endereço, e depois com o outro ). Eu já sei que a serial verdadeira está no endereço 4062B6 e a serial que nós digitamos está no 4060BA. Então o que nós precisamos fazer é alterar o texto da MsgBox: ao invés de aparecer "Wrong Serial - try again!", ele exibe o serial correto. Fazer isso é muto fácil, vá até o local onde ele puxa o texto "Wrong serial..." da msgbox ( 401274 ):

00401274 68 60604000 PUSH crackme2.00406060 ; ASCII "Wrong serial - try again!"

De um duplo clique sobre "PUSH crackme2.00406060" e altere para "PUSH 004062B6" :

00401274 68 60604000 PUSH crackme2.004062B6

O que nós fizemos foi: ao invés de chamar o endereço 406060 que contém "Wrong...", nós chamamos o endereço que contém a serial correta ( 4062B6 ). Para testar, basta salvar as modificações em um novo executável. Clique com o botão direito sobre a janela principal, vá em "Copy to Executable->All Modifications->Copy All". Na nova janela, clica novamente com o botão direito e escolha "Save File". Salve o novo arquivo, execute, digite um nome e um serial qualquer e veja a MessageBox que aparece:

Bingo! Ao invés de mensagem de serial incorreto, apareceu o serial verdadeiro. Anote e use-o!
Como tarefa, decifre o algoritmo do serial ( começa em 004011F6 ). Não é complicado, simplesmente realiza uma série de operações básicas com cada letra do nome digitado.

Antes de finalizar, só quero lembrar que nesse caso, o código poderia ser alterado sem sequer ter controlado a exceção, só quis explicar aquilo para que em outros casos você não desista somente porque o programa parou de funcionar no debugger ;D

F3rGO!