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

KeygenMe #1 (I-2)

Dom

27

Ago

2006


17:46

(16 votos, média 4.81 de 5) 


Correndo o código com o OllyDbg

Rode o OllyDbg e carregue o keygenme1.exe. Procure pelo endereço 00401323, que deve mostrar as mensagens já citadas. Observe que o OllyDbg assinala com um traço vertical colocado logo à direita dos endereços de memória uma subrotina que termina em 0040136D (RET) e que começa em 00401208. É bem aí que vamos colocar um breakpoint com F2. Depois disso, rode o executável com F9. Coloque qualquer coisa como nome (eu usei "teste"), um serial qualquer (eu usei "aaaaa") e clique em [check]. A execução pára exatamente no breakpoint que colocamos.

Execute algumas linhas com F7 (sugiro que use F8 quando chegar numa instrução call):

00401208  /$ 68 F8DC4000    PUSH keygenme.0040DCF8                   ; /String = "teste"
0040120D  |. E8 80010000    CALL <JMP.&kernel32.lstrlenA>            ; \lstrlenA
00401212  |. A3 86DC4000    MOV DWORD PTR DS:[40DC86],EAX
00401217  |. 833D 86DC4000 >CMP DWORD PTR DS:[40DC86],4
0040121E  |. 0F8C 29010000  JL keygenme.0040134D
00401224  |. 833D 86DC4000 >CMP DWORD PTR DS:[40DC86],32
0040122B  |. 0F8F 1C010000  JG keygenme.0040134D

Em 00401208 podemos ver a string com o nome "teste". Logo em seguida, é chamada a rotina para devolver o comprimento da string (lstrlenA) no registrador EAX (como "teste" tem 5 caracteres, EAX = 5). A seguir, este comprimento é comparado com 4 - se for menor, faremos um salto para a mensagem de Name must be 4 - 50.... A seguir, o comprimento é comparado com 32 (em hexadecimal, ou seja, 50 no sistema decimal). Se for maior, recebemos a mesma mensagem de erro, se não, a execução continua.

Seguindo as instruções com F7 (e F8) podemos observar que alguns cálculos são efetuados e seus resultados são combinados numa string. Pulando todos os cálculos, aqui estão as operações efetuadas:

...
004012B3  |. 68 FCDB4000    PUSH keygenme.0040DBFC    ; /Format = "Bon-"
004012B8  |. 68 F8DD4000    PUSH keygenme.0040DDF8    ; |s = keygenme.0040DDF8
004012BD  |. E8 D6000000    CALL <JMP.&user32.wsprintfA> ; \wsprintfA
004012C2  |. 83C4 08        ADD ESP,8
004012C5  |. 68 F8E04000    PUSH keygenme.0040E0F8    ; /StringToAdd = "FFFFFE58"
004012CA  |. 68 F8DD4000    PUSH keygenme.0040DDF8    ; |ConcatString = "Bon-FFFFFE58-FB74E600-41720F48"
004012CF  |. E8 B2000000    CALL <JMP.&kernel32.lstrcatA> ; \lstrcatA
004012D4  |. 68 01DC4000    PUSH keygenme.0040DC01    ; /StringToAdd = "-"
004012D9  |. 68 F8DD4000    PUSH keygenme.0040DDF8    ; |ConcatString = "Bon-FFFFFE58-FB74E600-41720F48"
004012DE  |. E8 A3000000    CALL <JMP.&kernel32.lstrcatA> ; \lstrcatA
004012E3  |. 68 F8E14000    PUSH keygenme.0040E1F8    ; /StringToAdd = "FB74E600"
004012E8  |. 68 F8DD4000    PUSH keygenme.0040DDF8    ; |ConcatString = "Bon-FFFFFE58-FB74E600-41720F48"
004012ED  |. E8 94000000    CALL <JMP.&kernel32.lstrcatA> ; \lstrcatA
004012F2  |. 68 01DC4000    PUSH keygenme.0040DC01    ; /StringToAdd = "-"
004012F7  |. 68 F8DD4000    PUSH keygenme.0040DDF8    ; |ConcatString = "Bon-FFFFFE58-FB74E600-41720F48"
004012FC  |. E8 85000000    CALL <JMP.&kernel32.lstrcatA> ; \lstrcatA
00401301  |. 68 F8E24000    PUSH keygenme.0040E2F8    ; /StringToAdd = "41720F48"
00401306  |. 68 F8DD4000    PUSH keygenme.0040DDF8    ; |ConcatString = "Bon-FFFFFE58-FB74E600-41720F48"
0040130B  |. E8 76000000    CALL <JMP.&kernel32.lstrcatA> ; \lstrcatA
00401310  |. B8 F8DD4000    MOV EAX,keygenme.0040DDF8 ;  ASCII "Bon-FFFFFE58-FB74E600-41720F48"
00401315  |. BB F8DE4000    MOV EBX,keygenme.0040DEF8 ;  ASCII "aaaaa"
0040131A  |. 53             PUSH EBX                  ; /String2 => "aaaaa"
0040131B  |. 50             PUSH EAX                  ; |String1 => "Bon-FFFFFE58-FB74E600-41720F48"
0040131C  |. E8 6B000000    CALL <JMP.&kernel32.lstrcmpA> ; \lstrcmpA
00401321  |. 74 15          JE SHORT keygenme.00401338

Hehehe :cool: No endereço 00401310 está o serial para o nome teste: Bon-FFFFFE58-FB74E600-41720F48. Não dá para resistir à tentação. Que tal transformar o keygenme1.exe no seu próprio key generator?

A instrução que nos mostra o serial diz para transferir para EAX a string que está no endereço de memória 0040DDF8. Marque este endereço pois vamos usá-lo logo mais. Além disso, após comparar o serial calculado com o fornecido, há uma salto condicional para 00401338 se os dois coincidirem. Se transformarmos este salto condicional em salto obrigatório, trocando JE por JMP, seremos levados diretamente para a mensagem Hello, Mr. Goodboy! onde faremos uma segunda alteração. Por enquanto, faça o seguinte:

  1. Selecione a linha 00401321 e aperte a tecla de espaço.
  2. Na janela de edição, troque JE (jump equal = salte se igual) por JMP (jump = salte).
  3. Clique no botão [Assemble] e feche a janela.
00401321  |. 74 15          JE SHORT keygenme.00401338

será transformado em

00401321  |. EB 15          JMP SHORT keygenme.00401338

Agora vamos até o endereço 00401338 e, usando o mesmo método descrito acima, troque o endereço 0040DC03 pelo endereço do serial

00401338: 68 03DC4000               PUSH 0040DC03 -> Hello, Mr. Goodboy!

será transformado em

00401338: 68 DDF84000               PUSH 0040DDF8 -> Bon-FFFFFE58-FB74E600-41720F48

Rode o executável novamente usando Ctrl+F2, digite o nome que quiser, um serial qualquer, clique no botão [check] e o serial bichado será substituído pelo correto :cool:

Informações adicionais