A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Oficina

kiTo KGNmeAGAiN (C-1)

Seg

28

Ago

2006


10:20

(7 votos, média 5.00 de 5) 


O serial

Só falta mais um tiquinho e chegaremos lá. Já temos uma string que cheira a serial, mas precisamos encontrar a rotina que compara o serial calculado com o fornecido. Veja a continuação do código e observe que a linha 4011C0 já mostra String1 = "6D68-9C2":

...
004011A7  |. 6A 32          PUSH 32                        ; /Count = 32 (50.)
004011A9  |. 68 6A334000    PUSH kiToKGNm.0040336A         ; |Buffer = kiToKGNm.0040336A
004011AE  |. 68 EA030000    PUSH 3EA                       ; |ControlID = 3EA (1002.)
004011B3  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]      ; |hWnd
004011B6  |. E8 51080000    CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
004011BB  |. 68 6A334000    PUSH kiToKGNm.0040336A         ; /String2 = ""
004011C0  |. 68 38334000    PUSH kiToKGNm.00403338         ; |String1 = "6D68-9C2"
004011C5  |. E8 24080000    CALL <JMP.&kernel32.lstrcmpA> ; \lstrcmpA
004011CA  |. C9             LEAVE
004011CB  \. C2 0400        RETN 4
  1. F7 - Põe 32h na pilha.
  2. F7 - Põe um endereço para um buffer na pilha.
  3. F7 - Põe o manipulador da janela na pilha.
  4. F8 - Chama a função GetDlgItemTextA para pegar o texto da segunda caixa de texto (onde colocamos o serial bichado "aaaaa"). Assim que retornamos desta função, a linha com String2 = "" é transformada em String2 = "aaaaa".
  5. F7 - Põe "aaaaa" na pilha.
  6. F7 - Põe "6D68-9C2" na pilha.
  7. F8 - Com as duas strings como parâmetros, fazemos a chamada para a função que compara strings do kernel32.

Sabe o que acontece? O óbvio: as strings não são idênticas e já sabemos que, se o serial fornecido não estiver correto, o programa simplesmente não reage. Para provar definitivamente que o serial calculado é o certo, faça o executável rodar novamente com F9, troque o serial "aaaaa" pelo que acabamos de descobrir e clique no botão [Check]. A execução deve parar no breakpoint (ou breakpoints, se você colocou mais alguns). Use F9 para fazer o programa deslanchar e, tá em casa. Recebemos uma mensagem de... sei lá o que... escrita em sueco!

O keygen

Podemos usar o próprio programa como keygen, mesmo sem entender muito bem como o serial foi calculado. Eu sei que é covardia, mas nada impede de fazermos duas pequenas alterações no executável original para transformá-lo numa ferramenta geradora de seriais dele mesmo. Veja como é fácil:

  • Em primeiro lugar, temos uma rotina que cria uma caixa de mensagem quando o serial fornecido for o certo - nada impede que a usemos para informar o serial calculado.
  • Já descobrimos o endereço onde o serial calculado é armazenado na memória (403338).

Pois bem, reinicie o programa com Ctrl+F2 e a execução vai parar novamente na rotina de cálculo do serial. Role o código um pouco para cima e ponha um breakpoint na última linha desta rotina, ou seja, em

...
004011C5  |. E8 24080000    CALL <JMP.&kernel32.lstrcmpA> ; \lstrcmpA
004011CA  |. C9             LEAVE
004011CB  \. C2 0400        RETN 4

Digite F9 e depois F7 para voltar para o ponto de chamada. Você deve encontrar o seguinte:

...
0040106C  |. 0BC0           OR EAX,EAX
0040106E  |. 75 16          JNZ SHORT kiToKGNm.00401086
00401070  |. 6A 40          PUSH 40                        ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401072  |. 68 4B304000    PUSH kiToKGNm.0040304B         ; |Title = "kiTo - KgnMe AGAiN!"
00401077  |. 68 03304000    PUSH kiToKGNm.00403003         ; |Text = "Bra, om du inte har gjort en keygen
                                                              än, så är det den ända lösningen ;)"
0040107C  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]      ; |hOwner
0040107F  |. E8 8E090000    CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA

Agora é partir para o abraço. Não queremos que o salto em 0040106E seja feito para que a caixa de mensagem seja apresentada. Podemos fazer duas coisas: transformar JNZ em JE ou simplesmente trocar os dois opcodes (75 16) por NOP. Se você optar pela primeira solução, selecione a linha do salto, aperte a tecla de espaço para obter o editor, troque JNZ por JE e clique no botão [Assemble]; se optar pela segunda, selecione a linha do salto, clique com o botão direito do mouse sobre ela e escolha Binary e Fill with NOPs. Pronto, o salto não será mais realizado. Agora vamos à caixa de mensagem.

O código logo a seguir coloca os parâmetros da função MessageBoxA na pilha para depois chamá-la. Agora é só selecionar a linha com a mensagem de texto em sueco, apertar a tecla de espaço para abrir a janela de edição, trocar o endereço 00403003 pelo endereço do serial calculado (00403338), clicar no btão [Assemble] e fechar a caixa de edição. Imediatamente o serial aparece.

...
0040106C  |. 0BC0           OR EAX,EAX
0040106E     74 16          JE SHORT kiToKGNm.00401086
00401070  |. 6A 40          PUSH 40                        ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401072  |. 68 4B304000    PUSH kiToKGNm.0040304B         ; |Title = "kiTo - KgnMe AGAiN!"
00401077     68 38334000    PUSH kiToKGNm.00403338         ;  ASCII "9A3F-71A"
0040107C  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]      ; |hOwner
0040107F  |. E8 8E090000    CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
...

Tecle F9 e divirta-se com o resultado smile

Informações adicionais