ESTUDIO COLECTIVO DE DESPROTECCIONES
Última Actualizacion: 25/10/2001

Programa TelePort Pro v1.29 W95 / W98 / NT
Descripción Programa para bajarse webs enteras o determinados tipos de archivo.
Tipo Trial
Tipo de Tutorial [X]Original, []Adaptación, []Aplicación, []Traducción
Url http://www.tenmax.com
Protección Time Limit
Dificultad 1) Principiante, 2) Amateur, 3) Aficionado, 4) Profesional, 5) Especialista
Herramientas SoftIce v4, W32dasm v8.9, UltraEdit, compilador de Pascal para l keygen
Objetivo Hacer un Keygenerator
Cracker Black Fenix
Grupo http://kickme.to/wkt
Fecha Junio del 2000

INTRODUCCION

De nuevo al ataque, en la décima entrega vamos a volver con los keygenerators, esta vez para un programa bastante útil, el TelePort Pro v1.29. Este programa es de gran utilidad para bajarse sitios web enteros y luego navegar off-line.

AL ATAQUE

Como siempre pondremos en marcha el SoftIce antes de ejecutar el programa luego ejecutamos el programa.Iremos al Menú/Help/Register, nos aparecerá un cuadro de diálogo donde se nos solicitan los siguientes datos: Nombre, Compañia y código de registro.

Introduciremos lo siguiente:

Your Name: Black Fenix
Company: reversed
Registration Code: 1234567

Seguidamente pulsaremos en OK, y como era de esperar nos aparecerá un mensaje de error informandonos que el código de registro no es válido. El mensaje dice lo siguiente:

teleportdlg.jpg

Salimos del programa y nos vamos al W32DAsm, desensamblamos el ejecutable (pro.exe) y hacemos click en el botón de referencias a cadenas. Buscaremos la cadena que aparece en el cuadro de mensaje "We're sorry! The ...." cuando la encontremos haremos doble click sobre esta. Veremos que el W32DAsm nos muestra el siguiente código:

:00425705 8D4DF0 lea ecx, dword ptr [ebp-10]
:00425708 EB2F jmp 00425739
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004256D7(C)
:0042570A 8945F0 mov dword ptr [ebp-10], eax
* Possible Reference to String Resource ID=07033: "We're sorry! The registration number you entered appears to"
:0042570D 68791B0000 push 00001B79
:00425712 8D4DF0 lea ecx, dword ptr [ebp-10]
:00425715 C745FC06000000 mov [ebp-04], 00000006
:0042571C E8EAD50100 call 00442D0B
:00425721 53 push ebx
:00425722 53 push ebx
:00425723 FF75F0 push [ebp-10]
:00425726 C745FC07000000 mov [ebp-04], 00000007
:0042572D E8EF3F0200 call 00449721
:00425732 834DFCFF or dword ptr [ebp-04], FFFFFFFF
:00425736 8D4DF0 lea ecx, dword ptr [ebp-10]

Como podemos comprobar si examinamos el código, en la línea 42570d se hace referencia a la cadena que estamos buscando, ahora, vamos a buscar el salto que nos envia a este lugar. Vemos que hay un salto en 4256d7 que hace referencia a la línea que hay por encima de 42570d, por lo que vamos a ver que es lo que hace que se nos envie aquí. nos desplazaremos por la ventana de código hasta llegar a la línea 4256d7 y veremos lo siguiente:

:004256C4 8D4DF0 lea ecx, dword ptr [ebp-10]
:004256C7 EB70 jmp 00425739
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00425691(C)
:004256C9 57 push edi // pasa como parametro la dirección del Nombre a registrar
:004256CA E809090000 call 00425FD8 // Esta función cálcula el número de série válido y lo retorna en EAX
:004256CF 85C0 test eax, eax // si EAX<>0 el número que hay en EAX es el número válido, si EAX=0 no se puede calcular un número para el nombre introducido
:004256D1 A174B34700 mov eax, dword ptr [0047B374]
:004256D6 59 pop ecx
:004256D7 7531 jne 0042570A // salta a mostrar el mensaje de error
:004256D9 8945F0 mov dword ptr [ebp-10], eax
* Possible Reference to String Resource ID=07032: "You haven't entered a valid username. Your username must be"
:004256DC 68781B0000 push 00001B78
:004256E1 8D4DF0 lea ecx, dword ptr [ebp-10]
:004256E4 C745FC04000000 mov [ebp-04], 00000004

Parece que la llamada en 4256CA, condiciona bastante el salto que nos envia al mensaje de error, por lo que vamos a comprobar que es lo que se le pasa a esta función poniendole un BPX en el Soft-Ice. Ejecutamos el programa, vamos a Menu/Help/Register, rellenamos los datos igual que antes y antes de pulsar Enter activamos el Soft-Ice y ponemos un BPX MessageBoxA, salimos del Soft-Ice (Ctrl+D) y pulsamos OK, el BPX habrá surtido efecto y estaremos de nuevo en el Soft-Ice. Pulsamos F12 para ir al código que llamó al cuadro de mensaje, y ahora ya podremos poner un BPX en 4256CA. Salimos del Soft-Ice y volvemos a pulsar el botón OK. Ahora se activará el Soft-Ice antes de que aparezca el cuadro de diálogo y estaremos en la línea 4256CA, vamos a ver a que apunta EDI con:

>d edi

En la ventana de datos veremos que aparece nuestro nombre (Black Fenix para el ejemplo), ya sabemos que ha esta función se le pasa la dirección de nuestro nombre, por lo que es posible que esta sea nuestra función.Pulsaremos F10 para que se ejecute la llamada. Hechando un vistazo a los registros que se han modificado, veremos que EAX contiene el siguiente valor: 51FAE285, vamos a ver el valor decimal de este número con:

> ? eax

Veremos que EAX tiene el valor decimal 1375396485 mmm..., parece un número válido. Probemosló. Salimos del Soft-Ice (Ctrl+D) y cambiamos el número 1234567 por 1375396485, pulsamos OK y sorpresa, el programa se ha registrado. Bueno ya sabemos que función se encarga de realizar el cálculo del número y ademas sabemos que lo devuelve en EAX, si examinamos el código anterior veremos que lo que se comprueba, es que ese número no sea 0. Volveremos a desensamblar el EXE y iremos a la posición de código 4256CA, luego iremos a la llamada que se hace en esta línea (call 00425fd8) con Goto/Code Location (introduce 425fd8 y pulsa OK). Allí veremos el siguiente código,(recuerda que EDI apuntaba al nombre antes de entrar a la función).

:00425FD8 57 push edi // guarda puntero al nombre
:00425FD9 8B7C2408 mov edi, dword ptr [esp+08] // copia la dirección del nombre
:00425FDD 85FF test edi, edi // mira si es válida <> NULL
:00425FDF 7409 je 00425FEA // si es NULL no se puede calcular el número
:00425FE1 57 push edi // guarda puntero a la cadena
:00425FE2 E879560000 call 0042B660 // esta función cálcula la longitud, resultado en en EAX
:00425FE7 59 pop ecx
:00425FE8 EB02 jmp 00425FEC // salta para continuar con el cálculo del número
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00425FDF(C)
:00425FEA 33C0 xor eax, eax // devuelve 0, ya que el nombre introducido es una cadena nula
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00425FE8(U)
:00425FEC 83F805 cmp eax, 00000005 // comprueba que la longitud del nombre sea > 5
:00425FEF 7304 jnb 00425FF5 // si no es inferior salta y continua con el cálculo
:00425FF1 33C0 xor eax, eax // error, el numero es inferior a 5 caracteres
:00425FF3 5F pop edi // restaura la pila
:00425FF4 C3 ret // y vuelve  
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00425FEF(C)
:00425FF5 53 push ebx
:00425FF6 56 push esi
:00425FF7 BEA4E4FE5D mov esi, 5DFEE4A4 // carga un valor constante en ESI
:00425FFC 33DB xor ebx, ebx // pone EBX a 0 (prepara el contador)
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0042601E(U)
:00425FFE 85FF test edi, edi // vuelve a comprobar que la cadena no sea nula
:00426000 7409 je 0042600B // si edi apunta a una cadena nula, no se puede calcular el número
:00426002 57 push edi // pasa puntero a la cadena
:00426003 E858560000 call 0042B660 // cálcula longitud , resultado en EAX
:00426008 59 pop ecx
:00426009 EB02 jmp 0042600D // continua con el cálculo
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00426000(C)
:0042600B 33C0 xor eax, eax // no se puede calcular el número EAX=0
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00426009(U)
:0042600D 83C0FC add eax, FFFFFFFC // suma FFFFFFFC a la longitud de la cadena (equivale a restarle 4)
:00426010 3BD8 cmp ebx, eax // comprueba si el contador >= que EAX
:00426012 730C jnb 00426020 // si es inferior salta y fin del cálculo
:00426014 33343B xor esi, dword ptr [ebx+edi] // hace XOR de la constante con los 4 caracteres a los que apunta [EDI+EBX]
:00426017 F6C340 test bl, 40 // mira si el byte bajo del contador supera 64 caracteres (40h)
:0042601A 7401 je 0042601D // si es asi salta
:0042601C 43 inc ebx // incrementa contador de caracteres
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0042601A(C)
:0042601D 43 inc ebx // incrementa contador de caracteres
:0042601E EBDE jmp 00425FFE // salta para continuar con el cálculo
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00426012(C)
:00426020 8BC6 mov eax, esi // copia el número calculado a eax
:00426022 5E pop esi // restaura la pila
:00426023 5B pop ebx
:00426024 5F pop edi
:00426025 C3 ret // retorna de la función con el número válido en EAX  

Bueno, examinando el código, ya podemos asegurar que aquí se calcula el número válido, si analizamos el algoritmo de cálculo veremos que es bastante sencillo. Primero se comprueba que el nombre apunte a una cadena válida, luego que tenga una longitud => que 5 caracteres, luego se carga un valor constante en ESI (5DFEE4A4), se inicializa un contador a 0 (EBX), se vuelve a calcular la longitud del nombre (cosa innecesaria) y se va haciendo un XOR con los cuatro carácteres del nombre que son apuntados por EDI+EBX sobre ESI dentro de un bucle que se procesa longitud(nombre)-4 veces. Tambien se comprueba que el contador de carácteres EBX no sea superior que 64, en caso de que esto sea así se incrementa el contador doblemente. Una vez computado el número, se copia a EAX y se retorna de la función.

Bueno es hora de implementar un algoritmo en Pascal que realize este cálculo, esta vez he usado el compilador gratuito Free Pascal de 32 bits en su versión windows.

Program TelePort_Pro_v1_29_KeyGen;

Uses Crt;

Const Seed=$5DFEE4A4;

Var Name:string[80];
    Nlength,contador:integer;
    regnum:dword;
    dptr:^dword;    
    

Begin
	textcolor(10);
	Writeln('Teleport Pro v1.29. Key Generator By Black Fenix 15/01/2000');
	textcolor(15);
	Writeln('-----------------------------------------------------------');
	textcolor(7);
	Writeln;
	Write('Enter your name (min 5 characters):');
	readln(Name);	
	Nlength:=length(Name);
	
	if (Nlength<5) then
	Begin
		Writeln('Sorry, the length of the name must be greater than 5 characters.');
		Halt(0);
	End;
	
	// copia puntero al primer caracter 
	
	regnum:=seed;
	Nlength:=Nlength+$fffffc; { es lo mismo que restarle 4, pero así lo hacemos igual que el original :-) }
	contador:=1;
	
	while (contador<=Nlength) do
	Begin
		dptr:=@Name[contador];
		regnum:=regnum xor dptr^;
		if (contador=$40) then 
		Begin
			writeln('hola');
			inc(contador);
		End;
		inc(contador);	
	End;
	writeln;		
	Write('Your registration number is:');
	textcolor(15);
	write(regnum);
	textcolor(7);
	writeln;
End.
[ Entrada | Documentos Genéricos | WkT! Web Site ]
[ Todo el ECD | x Tipo de Protección | x Fecha de Publicación | x Orden Alfabético ]
(c) Whiskey Kon Tekila [WkT!] - The Original Spanish Reversers.
Si necesitas contactar con
nosotros , lee esto antes e infórmate de cómo puedes ayudarnos