| 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: 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