Sei sulla pagina 1di 24

http://creativecommons.org/licenses/by/3.

0/

CRACKSLATINOS.
Programa: Insight 3.5.1

SentinelLM Version 7 y algo u 8, no se cual sera.

Dificultad: Intermedia o algo así.

Pues alguien me trajo este programa ya algo viejo, esta protección también es algo vieja.

Encontré algunos tutoriales de alrededor de 2001 de cyberheg, pero esa era otra versión. En
esa versión, bastaba con encontrar el DeveloperID y parchar con ello el keygen que venía en el
SDK de sentinelLM.

Para los que no lo saben, Sentinel es una línea de productos de Rainbow Technologies, la cual
es conocida por sus dongles, en especial los sppro y otras alimañas.

Pues SentinelLM es una dongle implementada en software, un archivo o keyfile que permite
amarrar una aplicación a una maquina especifica concediéndole opciones, tiempos de
ejecucion, licencias por red, etc etc etc tal como una dongle de hardware. Además pueden
usarse dongles físicas de ser necesario.

Este programa está protegido por una versión diferente, aquí no basta con el developerID
como veremos, pero no representa mayor dificultad.

Los keyfiles están encriptados o en texto puro con claves encriptadas para que el cliente sepa
que ha comprado.

En este caso, no hace falta un keyfile, las funciones no están ofuscadas ni nada por el estilo ni
hay antidebug, nada de nada, una malísima implementación.

Tools:

Olly.

API Documentation SentinelLM.


Empezamos, corremos la aplicación y vemos lo siguiente:

Pues aquí ya sabemos a quién nos enfrentamos.

Veamos, dice algo del directorio, vamos a ver que hay ahí:

Vemos tres archivos creados `por Rainbow, entre ellos una dll.

Cargamos el ejecutable main.exe en olly y veamos si hay llamadas a esta dll:


Ahí en la ventana de memoria aparece cargada, pero no hay referencias directas a las
funciones.

Damos click y mandamos la seccion .text a dissasembler con ENTER, luego damos CTRL+N para
ver los nombres de las funciones, damos click a types para ordenarlas de acuerdo a import o
export, nos interesan las exports:

Son muchas, necesitamos saber que hace cada una, por ello es necesario contar con la API de
SentinelLM, buscando en la web encontré el SDK completo de varias versiones, así que
leyendo la documentación encontré un manual conteniendo muchas de estas funciones.

Veamos la introducción:
Pues ya sabemos cuáles funciones deben llamarse primero, así que podremos bp a todas las
mencionadas en ese párrafo, eso nos deberá llevar directo a la zona caliente:

Damos run y aterrizamos aquí:

Y en la pila, la dirección de retorno:


Vemos lo que ya esperábamos encontrar, las funciones son llamadas desde otra dll llamada
Options.

Damos ahora click sobre la dirección de retorno en la pila y con ENTER llegamos a esa dll:

Ponemos bp y ejecutamos hasta llegar ahí:

Vemos los valores de retorno en los registros, en especial EAX que tiene cero.

Veamos la info de la función:

Los status codes son dados en una tabla del apéndice:


El valor cero representa lo que queremos: Buen Chico.

En esta función se está inicializando la comunicación con el servicio SentinelLM, y el servicio ha


dicho que si, por lo que devolvió cero.

Los programadores dejaron muchas referencias en el código, vemos directamente cual función
será llamada luego:

Pues busca el servidor de licencias, al llegar a la llamada vemos la pila:

Esta reservando 50h bytes a partir de 12fc14, ejecutamos y en eax:


Veamos que significa:

Mmm, esto es raro.

Debió devolver cero y el nombre de un host.

Como no sabemos cómo manejara este valor, veamos las intermodular calls de esta dll y
pondremos bp a todas las Apis de lswin32.dll, damos run y caemos aquí:

VLSsetcontactserver:

Y si vemos el parámetro serverName en la pila:


Es el nombre de la maquina local que estoy usando, al salir de la función vemos eax:

Pues ahora nuestra maquina es el servidor de licencias, como tenemos aun los bp puestos,
demos run de nuevo:

Allí se detuvo, hay tres llamadas a funciones mediante su ordinal, para saber sus nombres, lo
mejor es ir a buscarlas a los intermodulars calls:

Y la ultima:

Y de la referencia:
Pues la primera establece que la maquina local manejara todas las peticiones de licencias,
mientras que la segunda deshabilita un temporizador que al parecer controla el chequeo
periódico de las licencias, esto es bueno. En este caso vemos que envía argumentos de ceros,
por lo que deshabilita todos los autotimers.

L a tercera es solo una consulta para ver si se realizaron los comandos anteriores:

Al revisar EAX vemos que devuelve 1:


Pues es de esperar, ya que aun no hemos solicitado licencias, solo nos hemos conectados.

Ejecutamos ahora con F9 y llegamos aquí:

Llamando a LSRequest:
LSRequest( )
Requests an authorization license code from the license server.
Syntax LS_STATUS_CODE LSRequest (
unsigned char *licenseSystem,
unsigned char *publisherName,
unsigned char *featureName,
unsigned char *versión,
unsigned long *unitsReqd,
unsigned char *logComment,
LS_CHALLENGE *challenge,
LS_HANDLE *lshandle;
LS_NORESOURCES An error occurred in attempting to allocate
memory needed by function.
LS_NONETWORK Failed to initialize Winsock wrapper. (Only
applicable if using network-only library.)

Argument Description
licenseSystem Unused. Use LS_ANY as the value of this variable.
LS_ANY is specified to indicate a match against installed
license systems.
publisherName A string giving the publisher of the product. Limited to 32
characters and cannot be NULL. Company name and
trademark may be used.
featureName Name of the feature for which the licensing code is
requested. May consist of any printable characters and
cannot be NULL. Limited to 24 characters.
versión Version of the feature for which the licensing code is
requested. May consist of any printable characters. Limited
to 11 characters.
unitsReqd The number of licenses required. The license server
verifies that the requested number of units exist and may
reserve those units, but no units are actually consumed at
this time. The number of units available is returned.
If the number of licenses available with the license server
is less than the requested number, the number of available
licenses will be returned using unitsReqd. If unitsReqd is
NULL, a value of 1 unit is assumed.
logComment A string to be written by the license server to the comment
field of the usage log file. Pass a NULL value for this
argument if no log comment is desired.
challenge The challenge structure. If the challenge-response
mechanism is not being used, this pointer must be NULL.
The space for this structure must be allocated by the
calling function. The response to the challenge is provided
in the same structure, provided a license was issued, i.e.,
provided the function
LSRequest( ) returned
LS_SUCCESS. For details of the challenge-response
mechanism and how to use it effectively, see page 44.
lshandle The handle for this request is returned in lshandle. This
handle must be used to later update and release this
license code. A client can have more than one handle
active at a time. Space for lshandle must be allocated by
the caller.
.
Returns The status code LS_SUCCESS is returned if successful.

Pues esta verificando que tengamos una licencia válida, esta api determina si al menos una
licencia se encuentra disponible para el programa, si existe la licencia, devolverá cero, veamos
la pila:
El name de la licencia es INNCRS, al ejecutar, nos devolverá un error:

Aquí lo que necesitamos es que eax valga cero, por lo que modificamos el código así:

Antes:

Después:
Con esto tendrá para seguir.

Damos a F9 sin olvidar poner eax a cero y caemos aquí:

Ordinal 25, veamos que es:

Pues el programa se trago lo de la licencia y ahora busca las opciones o partes autorizadas, etc.

Aquí es donde se pone interesante:


Veamos la pila para ver los argumentos:

La opción es INAuDi y la función retorna una estructura de datos que inicia en 12FA04h:

Vacía, y al ejecutarse:
Pues continuara vacía, no hay licencia, por lo tanto no hay opciones, y en eax:

Error 12, debió ser cero, y no nos dio la versión de la opción como indica la referencia al buscar
la opción por nombre.

Aquí no basta con poner en cero eax, veamos el código 12:

Sin la estructura estamos arruinados, nos tocara simular que la estructura si fue devuelta con
eax cero y vigilar los accesos a esta área de memoria.

Veamos el código que sigue:


Está evaluando los códigos de error, si eax es cero, el salto en F3ADD8 se efectuara, esto al
salir de la call en F3ADD3, luego revisara los códigos de error.

Aquí es difícil sin una licencia válida, hay mucho que tracear, pero es importante no perder la
calma y pensar, asi que ejecutare de nuevo con F9 y veremos que pasa:

Vuelve a llamar la misma función evaluando otra opción, esto indica que esta ciclando en esta
subrutina, por lo que deben estarla llamando desde fuera, no puede quedarse aquí para
siempre, asi que veamos el call stack:
Gracias por la ayuda, más claro no puede ser, la dll tiene los nombres muy claros, esta es la
subrutina o función FindLicenses de options.dll.

Ejecutamos hasta el retn 2 veces y salimos de la subrutina:

Aterrizamos en otro retn luego de la llamada a FindLicenses:

Ejecutamos de nuevo con F7:

Seguimos saliendo de subrutinas, seguimos hasta el siguiente retn:

Y al salir:
Bueno, no podemos pedir más ayuda, esa función SetLicenseValue es más que explicativa.

Vean eso , se evalúa eax, si es chico malo hay un push 0, si es chico bueno , pues un push 1.

Además se empuja ecx, con esto solo bastara siempre mandar un 1 a la función, por lo que no
necesitaremos que SentinelLM nos diga pobres.

Veamos si hay mas llamadas a esta función:

Hay muchas, pero lo que vemos es que al volver de FindLicenses:

Veamos otras llamadas a esa función:


Y asi y asi y asi, no hay similitud, asi que habrá que modificar la mismísima función, ese 1 debe
evaluarse y tiene que haber un salto mágico dentro que valide la licencia.

Volvamos a donde estábamos y pasemos por chico bueno para entrar a la función y ver
cuando decide:

Ahí el uno en la pila.

Visto en el dump.

Ponemos bp on Access y damos run:


Ahí está, modificamos la función para que siempre mueva 1, después de verificar apostaremos
a que siempre eax esta en cero al llegar aquí, asi que solo sumaremos 1 a eax:

Y damos run para ver si no vuelve a verificar el 1:


Pues ya lo está sobrescribiendo, así que ha funcionado, quitamos el bp y continuamos:

De nuevo, seguirá buscando opciones hasta terminar, modificamos para que eax valga cero de
nuevo así que es hora de quitar este bp y dejarlo engañarse solo:

En la barra de tareas el programa corre, es un servicio y ya no hay rotulo de licencia, y en el


task manager:
Vemos el proceso corriendo sin problemas.

Activaremos una opción de GUI que requiere licencia en el archivo .ini, con esto sabremos si
todas las opciones están activas:
Activamos las aplicaciones de la parte baja derecha que también requieren licencia y veamos
que pasa:
Pues sí, ha muerto.

Espero haya sido de su agrado, bastante largo pero ha valido la pena.

Los agradecimientos de siempre, a toda la lista de Crackslatinos.

Joref Linaz

Enero 2008.

Potrebbero piacerti anche