Sentinel LM
Sentinel LM
Sentinel LM
0/
CRACKSLATINOS.
Programa: Insight 3.5.1
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.
Veamos, dice algo del directorio, vamos a ver que hay ahí:
Vemos tres archivos creados `por Rainbow, entre ellos una dll.
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 ahora click sobre la dirección de retorno en la pila y con ENTER llegamos a esa dll:
Vemos los valores de retorno en los registros, en especial EAX que tiene cero.
Los programadores dejaron muchas referencias en el código, vemos directamente cual función
será llamada luego:
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:
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:
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.
Pues el programa se trago lo de la licencia y ahora busca las opciones o partes autorizadas, etc.
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.
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.
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.
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.
Volvamos a donde estábamos y pasemos por chico bueno para entrar a la función y ver
cuando decide:
Visto en el dump.
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:
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.
Joref Linaz
Enero 2008.