Вы находитесь на странице: 1из 7

Alvo: Advanced PDF Tools v2.0 Objetivo: Keygen (patch coisa de iniciante, e voc profissional, certo?) Ferramentas: OllyDBG.

G. Ol amiguinhos, muito tempo que no escrevo nada, e pensei, por que no um tutorial de keygen? Vejo que, a maioria dos crackers iniciantes, esto muito acostumados em pescar serial, fazer patchs, loaders de memria, e esquecem de perder um pouco de tempo analisando a rotina de registro e escrevendo o keygen. Mos a obra: Abra o programa no Olly e aperte F9. Vemos a tela de registro. Digite qualquer informao e clique em Register.

A seguinte tela aparece:

Agora volte ao Olly e coloque um breakpoint em DestroyWindow. (Voc sabe como fazer isso). Em seguida clique no OK da janela de erro.

Vemos o programa parado na API DestroyWindow. REMOVA o breakpoint. Ao observar a stack, podemos ver ele lendo o meu cdigo de registro. Acima do cdigo digitado RASTASDONTWORKFORCIA, temos: 0012F7AC \004D24CC $M. ; RETURN from Prjpdfinfo.00439F6C to Prjpdfinfo.004D24CC Logo, sabemos que existe uma CALL 00439F6C que aps terminar sua execuo retorna para o endereo 004D24CC. Clique nessa linha e tecle enter.

Observe, uma CALL 00439F6C e logo abaixo o endereo 004D24CC. ;) Muito bom jovem...

O cdigo mostra:

Uma Call em 004D24AE, um TEST AL, AL para verificar se o retorno da funo verdadeiro ou falso, e um JNE que salta para 004D24D1, onde podemos ver a API GetSystemDirectoryA, uma concatenao com \lbj.ini, logo, onde vai ser gravado nosso serial. Vamos analisar a call 00479FA8.

Em 479FD2 temos uma call seguido por um cmp eax, 10. Sem entrar na funo, sabemos que a funo: function length(s: string): integer; E o serial deve ter 0x10h (16 em decimal) caracteres. Em 479FDF vemos:

push eax mov ecx , 1 // qtde de caracteres a copiar mov edx, 2 // devo comear a cpia a partir de qual posio da string? mov eax, dword ptr ss:[ebp-4] // string a ser copiada. call 00404DCC Mais uma vez, sabemos (eu pelo menos sei) que essa funo a Copy do Delphi. function Copy( s : string; index, count : integer ) : String; Como no assembly os parmetros so passados em ordem inversa, sabemos que a funo se comportaria assim: copy(RASTASDONTWORKFORCIA, 2, 1) Copia COUNT caracteres da string S a partir da posio INDEX. Sabendo isso, colocamos um breakpoint em 479FF2, que onde vai manipular o segundo caractere que foi copiado do nosso serial. E rode com F9. No esquea de digitar um cdigo com 16 caracteres. Podemos ver o programa parado em:

EAX aponta para a letra A (para conferir, clique em EAX com o boto direito e v em Follow in Dump). Passe por cima dessa funo com F8 e veremos em que EAX ir se transformar. Erro!

Vamos substituir A por um nmero qualquer, por exemplo, 8. E clicar em Register.

O Olly volta para o breakpoint e passamos por cima da call com F8. Vemos o resultado de EAX = 8, logo sabemos que a funo StrToInt(s: String) : integer; Para ajudar a entender o cdigo no olly, voc pode definir labels nas calls assim: Clique em cima da call que voc o que ela faz, tecle enter, e no endereo que aparecer no Olly, voc pode clicar com o boto direito e ir em Add Label ou simplesmente apertar :. Fiz isso na funo Copy, StrToInt e Length. Veja como fica.

Muito mais legvel hein jovem! ;) Com isso, j podemos observar que, o programa pega os seguintes nmeros do serial: serial[2], serial[9], serial[0x0C]. 0x0Ch equivale a 12 em decimal. Mas claro que voc j sabe isso :) A primeira funo StrToInt move o resultado para em ESI
00479FF5 00479FFA E8 36F3F8FF 8BF0 CALL StrToInt(s: String) : Integer; MOV ESI,EAX

A segunda funo StrToInt move o nmero convertido para EDI.


0047A015 0047A01A E8 16F3F8FF 8BF8 CALL StrToInt(s: String) : Integer; MOV EDI,EAX

E a terceira funo StrToInt faz o seguinte:


0047A032 0047A035 0047A03A 0047A03C 0047A03E 8B45 F0 E8 F6F2F8FF 03FE 03C7 83F8 12 MOV EAX,DWORD PTR SS:[EBP-10] CALL StrToInt(s: String) : Integer; ADD EDI,ESI // Acrescenta o valor de ESI em EDI ADD EAX,EDI // Acrescenta o valor de EDI em EAX CMP EAX,12 // Compara EAX com 0x12h (18 em decimal)

Com isso, o programa pega esses 3 nmeros do nosso serial e faz a soma. O resultado deve ser igual a 18. Como ele usa 3 nmeros vou usar o 6 como exemplo, 6+6+6 = 18 ( eu sei isso tambm!)

Ao clicar em Register, temos:

Ns rigistamos o programa! :x Assim, um keygen em Delphi seria: (A funo est BEM idiota, mas por que tem gente que tem dificuldade de entender um algoritmo complexo.)
function keygen : String; const dicionario = '1234567890'; var i : byte; x, y, z : byte; begin Result := ''; // Inicializa a variavel de retorno Randomize; // Inicia a funcao random // de 1 ate 16, coloque um caractere aleatorio do // dicionario na string de retorno for I := 1 to 16 do Result := Result + dicionario[random(10) + 1]; repeat // Repita isso at que a soma dos numeros x := Random(10); // Escolhe um nmero qualquer y := Random(10); // Escolhe um nmero qualquer z := Random(10); // Escolhe um nmero qualquer until (x+y+z = 18); // ate que a soma de x+y+z = seja para para para 18 = X Y Z 18 menor que 10 menor que 10 menor que 10

Result[02] := IntToStr(x)[1]; // Coloca o numero x do serial na posicao 02 Result[09] := IntToStr(y)[1]; // Coloca o numero y do serial na posicao 09 Result[12] := IntToStr(z)[1]; // Coloca o numero z do serial na posicao 12 end; procedure TForm3.Button1Click(Sender: TObject); begin Edit1.Text := keygen; end;

Вам также может понравиться