Paint Shop Pro 5.01 Trial version removal by Black Fenix

Bienvenido a mi primer tutorial de cracking, en el cual vamos a eliminar el periodo de 30 dias de prueba que nos da la versión de evaluación del Paint Shop Pro 5.0.

Images/marcador.gif (1024 bytes)SoftIce para Windows
Images/marcador.gif (1024 bytes)W32Dasm
Images/marcador.gif (1024 bytes) Un editor hexadecimal (Ultraedit32 o HView)

Images/marcador.gif (1024 bytes)Vista Rápida de windows instalada (QuickView)

Nota: puedes encontrar estas tools en www.astalavista.box.sk

Abreviaturas usadas :SI -> SoftIce

Primero debemos tener claro que es lo que vamos a hacer, en este caso se trata de un control de tiempo en concreto de 30 dias por lo que necesitaremos saber las funciones de windows que se encargan de obtener la hora del sistema son:

GetSystemTime
GetLocalTime

que son las dos más utilizadas. Por otra parte necesitaremos saber que DLLs importa el ejecutable por lo que haremos click con el botón derecho del mouse sobre el ejecutable del programa y seleccionaremos vista rápida (en Inglés QuickView) esto nos dará la información que buscamos, apuntaremos los nombres de las DLL que usa el EXE y cargaremos los simbolos de estas en el SI (en la versión 4 del SI se pueden cargar dinámicamente sin tener que reiniciar el ordenador).

Para empezar modificaremos la fecha del sistemay la adelantaremos lo suficiente un par de meses estaría bien. Si ejecutamos el programa veremos que nos da un mensaje en el cual nos 'invita' a salir del programa ya que se ha terminado el periodo de evaluación. Salimos y entramos en el SI (Ctrl+D) , estableceremos breakpoints en estas dos funciones:

:bpx GetSystemtime
:bpx GetLocalTime

Nota: Hay que recordar que debemos tener cargados los simbolos que exporta la libreria KERNEL32.DLL ya que estas dos funciones estan en dicha DLL.

Ok, salimos del SI (Ctrl+D) y ejecutamos el Paint Shop Pro. Estamos de nuevo en el SI ya que un breakpoint a surtido efecto, en la parte superior izquierda del SI observamos que estamos dentro del modulo y función Kernel32!SetFileTime+0034 hmmmm. , parece que esto no tenga mucho que ver en un principio pero pulsamos F11 para retornar a la función que llamó a la del breakpoint y... Estamos en el móduloMSVCRT!Time parece ser que el programa no llama directamente a las funciones de tiempo sino que lo hace por medio de la libreria MSVCRT.DLL. Si pensamos un poco y sabemos que la libreria MSVCRT tiene varias funciones para la gestión del tiempo nos ahorraremos mucho trabajo ya que existe una función dentro de la DLL MSVCRT llamada difftime que devuelve la diferencia entre dos tiempos en segundos y es probable que el programa la use en algún punto para calcular los dias que quedan desde que se instaló el programa. La definición de este función en C sería:

double difftime( time_t timer1, time_t timer0 );

Nota:time_t es un longint.

Pues manos a la obra, borramos todos los breakpoints con BC * y salimos del SI (Ctrl+D). El programa nos mostrará el mensaje típico diciendo que el tiempo de evaluación a terminado como es lógico ya que hemos adelantado la fecha un par de meses. Salimos del programa ya que no nos deja continuar y activamos el SI (Ctrl+D), ponemos un breakpoint en la susodicha función:

:bpx difftime

y salimos del SI de nuevo con Ctrl+D.

Ejecutamos el programa y Boom!! aquí la tenemos. Podremos ver algo como esto en la ventana de código del SI:

 

PUSHEBP -> Guarda puntero de pila
MOVEBP,ESP-> Apunta EBP a los parametros pasados timer1 y timer0
MOVEAX,[ESP+08]-> Carga timer1 en EAX
SUBEAX,[ESP+0C]-> resta timer1-timer0
MOV[EBP+08],EAX ->guarda en timer1
FILDDWORD PTR [EBP+08] -> convierte el resultado en un double
POPEBP-> restaura pila
RET

Este es el código de la función difftime la cual hace el cálculo entre el tiempo actual y el de instalación. si trazamos paso a paso con F10 después del RET podremos ver lo siguiente:

 

PUSH EAX-> empuja el primer tiempo
PUSH ECX-> empuja el segundo tiempo
CALL [MSVCRT!.difftime] -> esta es la función de donde hemos venido (cálcula la diferencia en segundos)
ADDESP,08->ESTAMOS AQUI!! en esta linea, ajusta la pila en 8 (tamaño de los (argumentos timer1 y timer0)
CALL[MSVCRT!f_tol]-> convierte el resultado (es un double) a un long
MOVECX,EAX-> pasa la diferencia en segundos a ECX pej= 4589077 seg. En hexadecimal 460615 seg
MOVEAX,C22E4507-> EAX= 3257812231
IMULECX -> multiplica los segundos * 3275812231 resultado en EDX:EAX Ej: EDX= FFEF172E, EAX = E353D393
ADD EDX,ECX-> suma a EDX la diferencia anteriorEDX= FFEF172E + 460615 = 351D43
SAREDX,10-> desplaza con signo a la derecha 10 posiciones EDX= 35h - > 53 -> equivale a dividir entre 1024 
MOVEAX,EDX-> EAX=35h -> 53
SHREAX,1F -> y divide entre 2147483648, EAX=0 En EAX y EDI se hayan los dias totales , ahora se suman en EDI
LEAEDI,[EAX+EDX+01]-> (se suma 01 dia para que no sean 0 dias ) -> EDI = 54 dias
CMPEDI,01-> Ha pasado + de un día ?
JGE00589DAE-> Salta si afirrmativo

Que te parece?, Basicamente esta rutina pasa los segundos que retorna la función difftime a dias y es precisamente esto es lo que nos está jodiendo, para comprobarlo puedes ver que pasa despues del salto JGE, trazando paso a paso te daras cuenta que hay más instrucciones de comparación para EDI (dias), lo más inteligente aquí sería modificar esta rutina para que el dia siempre fuera 1 (EDI=1) antes de saltar, por lo que habrá pensar como. Necesitamos saber cuantos bytes ocupan las instrucctiones aquí codificadas asi quelo mejos será desensamblar el EXE con el W32Dasm e ir a la dirección de código donde se hace la llamada a difftime (esto lo podemos ver en el SI al lado de la instrucción call) en nuestro caso es la xxxx:589D7F.

Mientras el EXE se desensambla podemos hacer una copia del ejecutable por si las moscas ya que ahora vamos a modificar su código jejejejee :). Una vez desensamblado vamos al Menu Goto/Code Location e introducimos el valor 589D7F click en Ok y apareceremos al ladito de la llamada a difftime.

Bajamos hasta el LEA EDI,[EAX+EDX+01] y vemos que este instrucción ocupa 4 bytes si nuestra intención es hacer que el programa crea que siempre es el primer día, no bastará con un XOR EDI,EDI (2 bytes) y un par de NOPs (2 más) ya que será el día 0 y nuestra intención es que sea el dia 1.
Como lo haremos? Facil, sabemos que un MOV EDI,1 son 5 bytes (codificado BF01000000) y el LEA son 4 por lo que nos hará falta 1 byte más, de donde lo sacamos? pues facil tambien, de la instrucción previa al LEA el SHR EAX,1F. Mirando el código vemos que ocupa 3 bytes, pues bien los 2 primeros bytes los rellenaremos con un NOP cada uno y el tercer byte será el que nos falta. Por lo tanto si tenemos que modificar el EXE nos colocaremos sobre la linea del SHR EAX,1F asegurandonos que la linea de posición azul está justo encima de esta, miraremos abajo en la barra de estado del W32Dasm y veremos que donde pone @Offset vemos el valor 0018919Dh. Este valor es la posición del primer byte de la instrucción dentro del archivo por lo que lo apuntaremos en un papel para luego. Ahora sabemos que hay que sustituir a partir de esta posición 7 bytes de código (2 NOP + el MOV EDI,0) la codificación de estas instrucciones sería: 90 90 BF 01 00 00 00. Ok, nos vamos al editor hexadecimal abrimos el ejecutable, buscamos el offset18919D con las ordenes del editor si este las tiene o a mano si no las tiene (vaya editor más cutre) una vez allí reemplazamos los bytes por 9090BF01000000y ya podemos ejecutar el programa.Ahora ya no pasaran los dias para nuestra versión "especial".

Si nos molesta la pantalla que sale al principio podemos eliminarla pero el trabajo sucio ya está hecho por lo que lo dejo a vuestro cargo.

Una pista:

DialogBoxParamIndirect
DialogBoxParamA


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