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

Programa Search and Replace v3.3 W95 / W98 / NT
Descripción Utilidad para buscar y reemplazar texto dentro de ficheros
Tipo Trial de 30 dias
Tipo de Tutorial [X]Original, []Adaptación, []Aplicación, []Traducción
Url http://www.funduc.com
Protección Nags Screens. Límite de funcionalidad a un cambio en 5 ficheros simultáneamente. Time Limit 30 Dias
Dificultad 1) Principiante, 2) Amateur, 3) Aficionado, 4) Profesional, 5) Especialista
Herramientas SoftIce v4.05, W32dasm v8.9, Regmon v4.25, Hex Workshop v3.1
Objetivo Eliminar todas las restricciones del Shareware.
Cracker Nowhere Man
Fecha 20 de agosto de 2000

INTRODUCCION
Literalmente traducido, Search and Replace significa buscar y remplazar; y seguramente pudiera ser la mejor descripción posible del programa.

Esta utilidad nos permite buscar cadenas de caracteres dentro de variados tipos de ficheros y sustituirlos de una sola vez por el nuevo texto que nosotros elijamos.

PROTECCIONES
Este programa se caracteriza por lo pesado que resulta en la versión de evaluación. Además de la consabida pantalla inicial de presentación:

cada vez que se realiza la operación de remplazado de texto nos aparece una ventana informándonos que en la versión de evaluación solo pueden realizarse cambios en 5 ficheros simultáneamente:

Una vez que se pulsa en "Si" se efectua el cambio. Y lo expreso en singular porque si se vuelve a intentar realizar otra sustitución el programa no nos deja, apareciendo la siguiente ventana:

No sé realmente a que se debe esta limitación; el tener que cerrar y volver a entrar en el programa para seguir evaluándolo no es la mejor manera de interesarse por él.

AL ATAQUE
La desprotección de este programa la voy a ir realizando por fases, que no van a seguir el orden de aparición en escena.

PERIODO DE EVALUACIÓN

Evitar que el programa caduque se puede conseguir al menos por dos procedimientos.

Primer método

Como casi siempre en estos casos lo primero que queremos encontrar son los avisos que los programas envían cuando no se dan las condiciones de evaluación. Adelentamos el reloj del sistema e inmediatamente después de la 'nag' inicial aparece el siguiente mensaje:

Lo siguiente es desensamblar el programa y buscar la cadena de caracteres de la ventana:

La línea 42D397 je 42D3C3 es un salto condicional justo antes de la presentación del mensaje. Anotamos el offset de esta instrucción, hacemos una copia del original y mediante un editor hexadecimal cambiamos el valor 74 por un 75. Guardamos, probamos y.... funciona nuevamente.

Ya se puede disfrutar de los días de evaluación que deeeemos.

Segundo método

Aunque realmente por el procedimiento anterior hayamos conseguido el objetivo, no debemos desechar la posibilidad de intentar cosas nuevas que en su día nos puedan resultar útiles.

El hecho de que una vez caducado el programa no deje volver a emplearlo aún retrasando la fecha, puede estar relacionado con la lectura o escritura de datos en el registro de Windows.

Empezamos buscando en el registro por si hay alguna clave que busque nuestro programa. Abrimos Regmon y filtramos las salidas de sr32.exe (en NT conviene emplear sr32*).

Observamos que una vez que sale la 'nag' inicial el programa arranca y obtiene una clave llamada 'Num Chars'situada en la rama "Current User":

Si antes de efectuar ningún adelanto al reloj del sistema copiamos el valor de 'Num Chars', podemos variarlo manualmente, o borrarlo, y luego restaurar también manualmente el valor.

Si hacemos esto veremos que el programa nos vuelve a mostrar la pantalla de final de evaluación. Por simple lógica este elemento de valor debe controlar la fecha codificada de instalación del programa. Si restauramos el valor que copiamos, el programa funciona normalmente.

Al cerrarlo, nuevamente accede al registro y escribe la misma clave codificada actualizada a la fecha del día.

Esto nos abre la posibilidad de entrar en el programa a través de las funciones de la API:

RegQueryValueExa: obtención de datos del registro.

GetSystemTime: obtención de la fecha del sistema.

Abrimos SoftIce con el "simbol loader" y colocamos las siguientes breakpoints:

Bpx GetSystemTime
Bpx RegQueryValueExa if *(esp->8)=='Num ' do "d *(esp+14)"

Ahora explicaré esta última línea.

La función RegQueryValue tiene la siguiente estructura:

RegQueryValueEx(
     HKEY hKey, // handle del elemento de valor que se busca
     LPTSTR lpValueName, // dirección del elemento de valor que se busca
     LPDWORD lpReserved, // reservada
     LPDWORD lpType, //dirección del buffer del elemento de valor buscado
     LPBYTE lpData, //dirección de retorno del elemento de valor buscado
     LPDWORD lpcbData //dirección del tamaño del buffer de datos

     );

Es decir, teniendo en cuenta que los parámetros se pasan a las funciones a través de la pila y en orden inverso:

En [ESP+00] estará la dirección de retorno
En [ESP+08] se pasará el nombre del elemento de valor a buscar, en nuestro caso 'Num '
En [ESP+14] se pasará la dirección de retorno en la que se colocará el valor buscado.

El hecho de colocar solo los cuatro primeros caracteres de 'Num Chars' se debe a que el comando de SoftIce *, nos devuelve valores del tipo DWORD o doble palabra (32 bits) que es equivalente a 4 octetos.

Un octeto se representa en Hexadecimal por ejemplo de la forma FF (la primera F es 15d o 1111b) por tanto FF sería en binario 1111 1111.

Los cuatro octetos de 'Num 'tendrán por tanto la forma:

4E 75 6D 20.

Hecho este inciso y con las breakpoints establecidas, pulsamos F5 aparecerá la 'nag' inicial. Aceptamos y nuevamente entramos en SICE. Si nos hemos fijado en el listado completo que nos proporcionó Regmon veremos que SR32.exe realiza varias solicitudes de datos al registro con el valor 'Num Chars', pero nosotros las saltaremos con F5 hasta que en nuestra ventana de datos aparezca el valor 'Num Chars' que ya conocemos.

En la línea 46EC5B almacena en ECX el elemento de valor de 'Num Chars'

Una vez que el programa lo recoge es claro que debe obtener la fecha de sistema, con lo que al siguiente F5 nos aparecerá la funcion GetSystemTime. Pulsamos F12 y volvemos al programa. Mediante F10 podemos trazar instrucciones y veremos como va colocando en los registros los valores de día, mes y año actuales (el resto no nos interesan). Como guía para los pocos iniciados 2000 en hexa es 7D0.

Cuando llegamos a la instrucción 4483A0 el programa ha guardado el día en EDX, el mes en EAX y el año en ECX-

A partir de aquí vienen una serie de instrucciones que codifican la fecha actual para pasarla a formato de 'Num Chars' y enseguida se llega a esta zona de código:

Si trabajamos con el programa original y no hemos sobrepasado el periodo de evaluación, veremos que los saltos en 42FCCB, 42FCE7 y 42FCEB (todos a la dirección 42FCF6) no se realizan, pero si realizamos lo mismo con la fecha excediendo los días de evaluación o modificando manualmente el valor de 'Num Chars' veremos que se realiza alguno de los saltos a 42FCF6 e inmediatamente nos aparece la ventana de fin de evaluación.

Una de las posibles maneras para siempre evitar que se produzca el salto es hacer un JMP a la siguiente instrucción. Como todos los saltos mencionados son cortos debemos emplear la expresión "corta" para JMP que es EB.

Nos quedarían 7C29, 7F0D y 7C09 como EB00

Y nuevamente queda desprotegido el programa del final de evaluación.

'NAG' RECORDATORIA DEL NÚMERO DE CAMBIOS POR SESIÓN

Cuando se inicia el programa y se seleccionan ficheros en los que realizar cambios, una vez efectuados dichos cambios aparece una ventana que nos recuerda las limitaciones de uso del programa:

Mediante Wdasm se busca la cadena de caracteres anterior apareciendo en:

Vemos que hay dos saltos condicionales por encima del mensaje. Comprobamos con SICE cual de los dos hay que invertir.

Nos fijamos en los contenidos de [EBP+08] y [EBP-64], en ambos casos es 1; y EBX es 0, ninguno de los dos saltos se producirá y siempre no aparecerá la 'nag'. Modificando cualquiera de ellos se evitará.

Cambiamos JZ 43C570 por JMP 43C570 (EB 26) y queda solucionado.

LIMITACIÓN DEL NÚMERO DE CAMBIOS POR SESIÓN

Como señalé al principio, una de las molestias de este programa es la imposibilidad de efectuar más de un cambio a más de cinco ficheros simultaneamente, por lo que hay que cerrar y abrir nuevamente el programa para conseguir poco a poco realizar las modificaciones (¡¡vaya sistema de evaluación!!).

Cuando se intenta realizar una modificación por segunda vez salta la siguiente ventana:

Mediante Wdasm buscamos la cadena de texto de arriba:

Vemos que a ella se puede acceder desde 5 saltos, si ponemos breakpoints con SoftIce veremos que el código llega desde 439DB6.

A primera vista parece el asunto de siempre, una inversión de los saltos y solucionado... pero no. Podemos hacer la prueba y siempre nos aparecerá la fastidiosa ventana.

No nos queda más remedio que emplear nuestro depurador SoftIce y pararnos en las cercanías del salto.

Bpx 439E36

Entramos en el programa utilizamos 7 u 8 ficheros de prueba y empezamos a realizar cambios, rápidamente aparece nuestro amigo SICE.

en 439E36 compara [EBP+08] con EBX. En EBP+8 siempre hay el valor 1 y en EBX siempre llegamos con el valor 0.

Luego el salto en 439E39 siempre se producirá.

En 439E3F compara el contenido de la variable global 4B357C con BX. En esta primera vez 4B357C contiene el valor 0.

Luego el salto en 439E46 se efectua esta vez ya que EBX es 0.

Pulsamos F5 y salimos nuevamente al programa, en la ventana confirmar remplazo. Si pulsamos en 'Replace this' vemos que SoftIce no salta y nos permite efectuar el segundo y sucesivos cambios, justo hasta que se ha realizado el quinto y nos aparece nuevamente la 'nag' recordatoria.

En este momento si volvemos a intentar efectuar alguna sustitución nuevamente entramos en el código de SoftIce. [EBP+08] sigue siendo 1 y EBX continua con el valor 0, pero la variable global 4B357C contiene ahora el valor 5, los cinco cambios como máximo permitidos, por lo que el salto en 439E46 no se efectuará y ahora directamente nos aparece la pesadita 'nag' sin haber realizado ni un solo cambio.

No quedaría más remedio que cerrar el programa y volverlo a abrir para poder seguir evaluándolo, de esta manera se inicializará la variable 4B357C a 0 y nos permitirá nuevamente un solo cambio en un máximo de 5 ficheros.

El camino a seguir parece claro, localizar el punto en el que se va incrementando la variable global y anularlo. Esto se puede conseguir en SICE mediante una interrrupción en la ejecución del programa en el momento en que éste acceda a la mencionada dirección de memoria para leerla o escribirla:

Bpm 4B357C RW

o también mediante Bpr 4B357C 4B357F

Cargamos nuevamente el programa en el "simbol loader" de Softice y establecemos una de las dos interrupciones de arriba.

Pulsamos F5, obtenemos la 'nag' inicial y nos disponemos a efectuar cambios en los ficheros de prueba, en cuanto aceptemos realizar el primer cambio saltará SICE en 439E46, esto ya lo habíamos visto, es la primera comparación de la variable global inicializada a 0. Pulsamos F5 otra vez y aparecemos en:

Comparación de nuestra variable con 6. Seguimos, F5 y:

Aquí hay algo interesante, se mueve el contenido de la variable global a la parte inferior del registro EAX, se incrementa, se comprueba el nuevo valor con otra variable global 491E18, cuyo valor es 5, y finalmente coloca el valor incrementado de nuevo en 4B357C.

No hay que ser un genio para deducir que aquí es donde se "cocina" el número máximo de ficheros en los que se puede realizar cambios y por añadidura el límite de una única sustitución.

Si anulamos con NOP's la instrucción 43BFC0 inc EAX, cuando el programa alcance la instrucción 439E46

el salto siempre se realizará ya que la variable global siempre estará a 0. Habremos eliminado las limitaciones de funcionalidad y la molesta 'nag'.

'NAG' INICIAL

He dejado para el final lo que en realidad aparece al principio, debe ser por que fué lo que más me costó, o donde menos espabilado estuve, que todo es posible.

Como casi siempre que aparece una 'nag' de este tipo solemos pensar en la función del API DialogParamA y poner, mediante SoftIce, una interrupción en ella. Eso mismo hice yo sin lograr nada.

Probé también la función ShowWindow y mediante ella si que lograba la "aparición" de SoftIce, pero comprobando con Wdasm desde dónde se llamaba aprecié, con horror, que esta función se invocaba desde 15 puntos. Intentar seguir este camino es imposible, entre otras cosas porque la función ShowWindow se emplea también para mostrar la pantalla principal del programa.

Desesperanzado abandoné y decidir utilizar el programa quitanag que, por otra parte, realizaba su trabajo con total diligencia.

Pero no sé qué tiene esto que como lo pruebes te engancha. Una buena actitud en estos casos es descansar y dedicarse a otra cosa. Así se fijan ideas y se suele acometer con mayor prestancia el trabajo.

Cuando uno se cree meter en un callejón sin salida merece la pena pararse a pensar, solo a pensar. Tanto ir y venir por el código del programa solo nos hace ver números y de vez en cuando conviene recapacitar:

Cuando adelantábamos el reloj del sistema, al principio de todo, antes de aparecer la ventana que nos indicaba el final del periodo de evaluación se dejaba ver la 'nag' inicial. Volvamos pues al código del final de evaluación:

¿Podrá ser que alguna de las 2 Call por encima del mensaje genere la 'nag' inicial?

Probemos con SoftIce

Bpx 42D37F y a continuación r eip=42D384 para saltarnos esa Call, pulsamos F5 y ¿¡Bingo!? LA 'NAG' NO APARECE, todo listo.

Muchas veces un programa se deja de examinar cuando uno cree haber conseguido algo, lo he visto en varios tutoriales.

La paciencia es una buena virtud. Probemos a seguir con el programa, intentemos realizar cambios. No funciona correctamente... aparecen unos mensajes de error entre los tamaños del fichero a remplazar.

¿Estamos donde estábamos?, no, algo hemos conseguido y algo sabemos con rotundidad: NO HEMOS TERMINADO.

Habrá que examinar la Call 45E448.

Esta rutina discurre entre las instrucciones 45E448 y 45E55C, habrá que estar al tanto y probar con F4 donde estamos.

Voy trazando con F10 y antes de cada Call compruebo los argumentos que se envían a ella por si pudiera obtener una pista.

En la línea

45E4FE PUSH DWORD PTR [EBP-14] se envía una dirección a la pila y muy cerquita se ve el texto del encabezado de la 'nag' "About Search...."

Seguimos con F10 y en 45E529 Call 45DBB7 aparece la 'nag'. Si "nopeamos" esta Call el programa produce un error. Ahora podemos o bien entrar dentro de esta Call o bien evitar llegar a ella.

Encima de nuestra Call hay 3 saltos: en 45E50C, 45E512 y 45E521, los dos primeros evitan la Call, el tercero no, luego en principio este lo desechamos.

Si seguimos el salto hasta 45E530 llegamos a una instrucción 45E546 JMP 45E565 (fuera de la imagen); el mismo destino que el salto en 45E50C.

Obligamos por tanto el salto en 45E512, saltamos a 45E530, pulsamos F5 y FUNCIONA.

Como la variación la hicimos con el SoftIce debemos fijarla con el editor hexadecimal, anotamos el offset, invertimos el salto y nuevo ERROR. AAAAAAARRRRGGGGGGG!!!!!.

Si ponemos un breakpoint en 45E512 vemos que antes de salir la 'nag' el programa pasa dos veces por aquí, la primera vez debe saltar para no presentar la 'nag' pero la segunda vez no debe saltarse para presentar la pantalla principal del programa.

Si intentamos invertir en 45E50C el problema es el mismo, la primera vez debe saltar pero la segunda vez no.

Se pueden comprobar los registros en la primera y segunda pasada y se ven que difieren, pero no he sido capaz de conseguir que se igualen en ambas.

Solo me quedaba la posibilidad de modificar el código. Esto me costó. Primero tenía que buscar allí mismo el sitio en el que eliminar instrucciones e introducir en ese mismo espacio el nuevo código, sin pasarme un byte.

Desde la instrucción 45E50A a la 45E512, ambas inclusives, solo hay comparaciones y saltos, sería un buen lugar y dispongo de espacio para 10 bytes.

El sistema será:

1º elegir una variable que se encuentre a 0
2º saltar la primera vez
3º incrementar esta variable de manera que no se salten las sucesivas.

Pongo una interrupción en SoftIce en 45E50A y miro el valor de los registros en las dos pasadas, todos varían a excepción de EDX.

Realizo d EDX y miro a ver si en sus alrededores hay un espacio de 4 bytes que estén a 00 00 00 00 para utilizarlo de variable a incrementar.

Parece que hay varios lugares y elijo EDX+10 ya que la trascripción a código máquina ocupa menos bytes que por ejemplo EDX+90; y aquí andamos justos de espacio.

Salgo de SoftIce y vuelvo a entrar con la misma interrupción. Antes de la primera pasada EDX+10 esta a cero y antes de la segunda ¡también! ¡¡QUE SUERTE!!

El código que introduzco es el siguiente:

 

45E508 33DB XOR EBX,EBX   45E508 33DB XOR EBX,EBX
45E50A 3BC3 CMP EAX,EBX   45E50A 3B5A10 CMP EBX,[EDX+10]
45E50C 7457 JZ 45E565   45E50D FE4210 INC BYTE PTR[EDX+10]
45E50E F6462410 TEST BYTE PTR[ESI+24],10   45E510 7353 JAE 45E565
45E512 741C JZ 45E530   45E512 90 NOP
45E514 6A04 PUSH 04   45E513 90 NOP
        45E514 6A04 PUSH 04

He resaltado en azul la parte que modifico, a la izquierda el código del programa y a la derecha la modificación introducida.

De lo que se trata fundamentalmente es de ocupar el mismo "espacio" empleando la instrucción NOP las veces que resulte necesario.

En la instrucción nueva 45E50A efectuamos la comparación de EBX con [EDX+10] como ambos son cero el salto en 45E510 se producirá, antes habremos incrementado el valor contenido en [EDX+10] a 1 por lo que en la siguiente pasada EBX no será mayor o igual que [EDX+10] y el salto no se producirá; habiendo logrado saltar en la primera pasada y no en las sucesivas.

Probamos y ahora si F U N C I O N A.

Todas las protecciones y limitaciones del programa se han superado.... con paciencia.

Ahora, como no somos unos mangutas, borramos nuestro fichero modificado y si nos interesa el programa lo compramos.

[ 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