TelePort Pro v1.29 KeyGenerator por Black Fenix

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.El programa te lo puedes bajar de http://www.tenmax.com

necesita.gif (15203 bytes)

marcador.gif (1024 bytes)SoftIce para windows
marcador.gif (1024 bytes) W32Dasm
marcador.gif (1024 bytes) Free Pascal Compiler, para hacer el Key Generator

Puedes conseguir estas "tools" en www.astalavsta.box.sk , el Free Pascal Compiler lo puedes bajar gratuitamente de http://tfdec1.fys.kuleuven.ac.be/~michael/fpc

comenza.gif (16493 bytes)

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

:004257058D4DF0lea ecx, dword ptr [ebp-10]
:00425708EB2Fjmp 00425739
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004256D7(C)
:0042570A8945F0mov dword ptr [ebp-10], eax
* Possible Reference to String Resource ID=07033: "We're sorry! The registration number you entered appears to"
:0042570D68791B0000push 00001B79
:004257128D4DF0lea ecx, dword ptr [ebp-10]
:00425715C745FC06000000mov [ebp-04], 00000006
:0042571CE8EAD50100call 00442D0B
:0042572153push ebx
:0042572253push ebx
:00425723FF75F0push [ebp-10]
:00425726C745FC07000000mov [ebp-04], 00000007
:0042572DE8EF3F0200call 00449721
:00425732834DFCFFor dword ptr [ebp-04], FFFFFFFF
:004257368D4DF0lea 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:

:004256C48D4DF0lea ecx, dword ptr [ebp-10]
:004256C7EB70jmp 00425739
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00425691(C)
:004256C957push edi // pasa como parametro la dirección del Nombre a registrar
:004256CAE809090000call 00425FD8 // Esta función cálcula el número de série válido y lo retorna en EAX
:004256CF85C0test 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
:004256D1A174B34700mov eax, dword ptr [0047B374]
:004256D659pop ecx
:004256D77531jne 0042570A // salta a mostrar el mensaje de error
:004256D98945F0mov dword ptr [ebp-10], eax
* Possible Reference to String Resource ID=07032: "You haven't entered a valid username. Your username must be"
:004256DC68781B0000push 00001B78
:004256E18D4DF0lea ecx, dword ptr [ebp-10]
:004256E4C745FC04000000mov [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).

:00425FD857push edi // guarda puntero al nombre
:00425FD98B7C2408mov edi, dword ptr [esp+08] // copia la dirección del nombre
:00425FDD85FFtest edi, edi // mira si es válida <> NULL
:00425FDF7409je 00425FEA // si es NULL no se puede calcular el número
:00425FE157push edi // guarda puntero a la cadena
:00425FE2E879560000call 0042B660 // esta función cálcula la longitud, resultado en en EAX
:00425FE759pop ecx
:00425FE8EB02jmp 00425FEC // salta para continuar con el cálculo del número
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00425FDF(C)
:00425FEA33C0xor 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)
:00425FEC83F805cmp eax, 00000005 // comprueba que la longitud del nombre sea > 5
:00425FEF7304jnb 00425FF5 // si no es inferior salta y continua con el cálculo
:00425FF133C0xor eax, eax // error, el numero es inferior a 5 caracteres
:00425FF35Fpop edi // restaura la pila
:00425FF4C3ret // y vuelve 
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00425FEF(C)
:00425FF553push ebx
:00425FF656push esi
:00425FF7BEA4E4FE5Dmov esi, 5DFEE4A4 // carga un valor constante en ESI
:00425FFC33DBxor ebx, ebx // pone EBX a 0 (prepara el contador)
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0042601E(U)
:00425FFE85FFtest edi, edi // vuelve a comprobar que la cadena no sea nula
:004260007409je 0042600B // si edi apunta a una cadena nula, no se puede calcular el número
:0042600257push edi // pasa puntero a la cadena
:00426003E858560000call 0042B660 // cálcula longitud , resultado en EAX
:0042600859pop ecx
:00426009EB02jmp 0042600D // continua con el cálculo
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00426000(C)
:0042600B33C0xor eax, eax // no se puede calcular el número EAX=0
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00426009(U)
:0042600D83C0FCadd eax, FFFFFFFC // suma FFFFFFFC a la longitud de la cadena (equivale a restarle 4)
:004260103BD8cmp ebx, eax // comprueba si el contador >= que EAX
:00426012730Cjnb 00426020 // si es inferior salta y fin del cálculo
:0042601433343Bxor esi, dword ptr [ebx+edi] // hace XOR de la constante con los 4 caracteres a los que apunta [EDI+EBX]
:00426017F6C340test bl, 40 // mira si el byte bajo del contador supera 64 caracteres (40h)
:0042601A7401je 0042601D // si es asi salta
:0042601C43inc ebx // incrementa contador de caracteres
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0042601A(C)
:0042601D43inc ebx // incrementa contador de caracteres
:0042601EEBDEjmp 00425FFE // salta para continuar con el cálculo
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00426012(C)
:004260208BC6mov eax, esi // copia el número calculado a eax
:004260225Epop esi // restaura la pila
:004260235Bpop ebx
:004260245Fpop edi
:00426025C3ret // 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.

keygen.gif (14559 bytes)

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.

You are inside Reversed Minds pages.

por Mr. Silver / WKT!.
La información aquí vertida es exclusivamente para uso educacional, no puedo hacerme responsable del uso que se haga de esta, por lo que atiendo a la honradez de cada uno :), recuerda que debes comprar el software que utilices :)