Virtual Gibbs v5.05 - Tutorial

http://www.gibbsnc.com/ - Webpage (v4.29 / v5.04 / v5.05 / v5.11).

Traducción

Esta traducción está hecha, en forma de agradecimiento a los crackers ke han tenido la gentileza de escribir sus experiencias para iluminar el camino a gente ke como yo, estamos empezando en el universo del Cracking, una mención especial para los que se han tomado la molestia de contestar mis peticiones de ayuda en los foros de Visual Basic y crackin'. Espero esta traducción sea de su agrado, animo Crackers, Newbies, que necesitamos ser una generación nueva, que lleve al máximo este noble arte, saludos a todos, en especial a Karpoff, WKT, y a todos los ke han dejado huella. Atte. ^[G]oLe[E]^

Un poco de historia

La Razón por la cual escribí este tutorial, es porque siempre he hecho parches para Virtual Gibbs, desde la versión 4.23 mas o menos, y siempre he sido capaz de cambiar unos cuantos bytes y fácilmente crackear la protección dongle. Este era el caso hasta la versión 5.0, después de la cual, los desarrolladores comenzaron a usar sus dongles un poco mas funcionalmente controlables (específicamente las opciones de milling) con palabras recuperadas del dongle.

En la v5.04 encontré difícil de hacer los mencionados parches usando solamente intuición, creé un nuevo método para esto y aquí fue donde decidí tratar de emular el dongle, usando la rutina Centinela Principal (después de todo, he estado haciéndolo con HASP por 2 años o más). Virtual Gibbs usa una clase de SentinelPro, la especificación API que he visto que quedan bien con el código. Una marca de fabrica que he visto muchas veces en los Centinelas, es la verificación de un récord de paquetes que parecen comenzar siempre con "Br" (como sería vista en memoria).

Usualmente, esto nos provee de una conveniente búsqueda de palabras y Centinelas, ya que no poseemos un PE de encriptación real para ocultar este código (definitivamente es una función de librería). La mayoría de tiempo, lo he visto compilado con ESI, así, CMP WORD PTR [ESI], 7242 usualmente es bastante efectivo, pero en una PC rápida, '7242' es lo suficientemente limitado. De la guía del API Centinela, noté que el parásito SuperPro tiene reservadas 8 & 56 celdas con propositos generales, las primeras 8 (0-7) están reservadas (teniendo significados especiales) y no pueden ser reprogramadas.

Esto por supuesto, tiene sentido si has leído alguno de mis otros documentos acerca de centinelas, los cuales hacen énfasis en un 'PUSH 3F', por ejemplo, 63 (la última celda de la dongle) a un API Centinela del tipo sproRead(), cada celda es una PALABRA (WORD). mi idea principal por eso, fue hacer un bpx para este código "read Word" y chequear los registros y la pila para ver que registros pasaron en la función, por búsqueda simple en w32Dasm, encontramos 13 casos de "cmp eax, 7242" y 1 "mov word ptr [eax], 7242" lo cual, obviamente no es interesante (es mas parecido a algún tipo de inicialización de la estructura).

Algunos de estos chequeos '7242', probablemente son "inocentes", es decir, sin importancia, en la mayoría de Centinelas que he visto, usualmente han habido 13 casos del tipo '7242' compiladas muy juntas, sin embargo, es posible ajustarlas, usando una combinación de técnicas, buscando las funciones de llamada (CALLS), podemos chequear los parámetros que fueron empujados y aparearlos con la guía API, las llamadas inocentes a SproInitialize(), el cual debe ser realizado para no tomar parámetros y poder así poder ser descartados, también he encontrado que el bpx usual a las API de la dongle con sentido simple para los call, retornando AX=3, es otra buena técnica de localizar la llave de la función Centinela.

:006CAEA0 PUSH 00000175 <-- ID del Desarrollador.
:006CAEA0 PUSH 008948A0 <-- Empujar los paquetes Grabados.
:006CAEAA CALL 00787FD1 <-- Esto solo Puede ser sproFindFirstUnit().

Este primer descubrimiento (el cual encontré haciendo un bpio -h 378 rw y F12 funcionó) solo puede ser sproFindFirstUnit(), no puede ser ninguna otra de las funciones API documentadas, debido a los parámetros empujados, este código también puede decirnos que PUSH 008948A0 es realmente un PUSH paquetes_Grabados, el cual debe ser el caso para Cualquier llamada API. Refinemos la búsqueda y esos bpx.

:006CAE5E PUSH 00001004 <-- Empujar Packet_Len.
:006CAE63 PUSH 008948A0 <-- Empujar los Paquetes Grabados.
:006CAE68 CALL 00787D6E <-- Inicializa los valores default del sproFormatPacket() .
:006CAE81 PUSH 008948A0 <-- Empuja los Datos Grabados
:006CAE86 CALL 00787DBA <-- chequea el Centinela sproFindNextUnit()
:006CAEF9 PUSH EAX <-- Puntero a donde la palabra será retornada 8.
:006CAEFE ADD ECX, 10
:006CAF01 PUSH ECX <-- Dirección a ser leída.
:006CAF02 PUSH 008948A0 <-- Empujar los paquetes grabados.
:006CAF07 CALL 007882BE <-- sproRead().

Bien, viendo esto, notamos que todo está acá, ahora solo necesitamos un bpx para 6CAE5E y verlo desdoblado frente a nuestros ojos, nuestro primer parche será sproFindFirstUnit(), yo cambie el MOV AX, 2 por MOV AX, 0 y redireccioné el JZ a este nuevo código (un cambio de 2 Bytes) :-

:00787FEF CMP EAX, 7242 <-- Es el paquete grabado valido
:00787FF4 JZ 00787FFA <-- por supuesto, es este.
:00787FFA MOV AX, 0 <-- ahora es valido.

Este cambio, resulta en un "La llave de Hardware no funciona ("Hardware key does not match flavor"), probablemente te has figurado que sproRead() debe ser el culpable, veamos esto, ahora mira a lo que está en la pila:-

A0 48 89 00   11 00 00 00   04 FD 3D 01
^^^^^^^^^^^   ^^^^^^^^^^^   ^^^^^^^^^^^
  Paquete      Dirección     Dirección
  Grabado        a leer     a Almacenar

Puedes ver, presionando F5 varias veces que la dirección a leer cambia cada vez, las palabras 11-17 incluso, son verificadas, así que reescribirémos este código para simular la presencia de nuestra dongle.

Simulando la dongle.....

:007882E1 JZ 007882E7 (0F 84 00 00 00 00) <-- Paquete de Datos Validados.
:007882E7 PUSH EBP (55)
:007882E7 MOV EAX, [ESP+20] (8B 44 24 20) <-- Obtiene la dirección a leer.
:007882EB SHL EAX, 1 (D1 E0) <-- Como estamos emulando una WORD.
:007882ED CALL $+5 (E8 00 00 00 00)
:007882F3 POP EBP (5D) <-- Establecemos el Delta.
:007882F4 LEA EDI, [EBP+1C] (8D 7D 1C) <-- Donde comenzara la memoria simulada.
:007882F7 MOVZX EAX, WORD PTR [EAX+EDI] (0F B7 04 38) <-- Recuperando el WORD.
:007882FB MOV EDI, [ESP+24] (8B 7C 24 24) <-- Obtiene la dirección para colocar la dongle WORD.
:007882FF MOV [EDI],AX (66 89 07) <-- Colocándola.
:00788302 XOR EAX, EAX (33 C0) <-- Exito.
:00788304 POP EBP (5D)
:00788305 POP EDI (5F)
:00788306 POP ESI (5E)
:00788307 POP EBX (5B) <-- POP registrado de la pila, como es requerido.
:00788308 LEAVE (C9)
:00788309 RET 0C (C2 0C 00) <-- Fin.

Ahora todo lo que necesitamos haces, es un bpx para nuestra rutina de simulación, y seguir cada WORD como es chequeada. para habilitar todas las opciones, el siguiente valor podría ser usado.

Word	Valor
----	-----
11	0400
12	0001
13	00EF
14	0000
15	0002
16	9FF0
17	0000

Nota irónicamente que nuestra memoria simulada esta usando el espacio previamente ocupado por la Protección Centinela. También te gustaría leer algunos feedbacks que recibí del autor de esta protección.

greenball.gif (835 bytes) Dongles greenball.gif (835 bytes) Return to Main Index


© 1999 CrackZ. Revised 26th September 1999.
www.000webhost.com