Curso de Desprotección de Programas – MSX – Capítulo 3

CURSO DE DESPROTECCIÓN DE PROGRAMAS

CAPITULO 3

1.INTRODUCCIÓN.

Una primera aclaración o consejo antes de empezar: dado el tiempo transcurrido desde que  leísteis este “culebrón galáctico”, no  estaría mal que lo releyeseis de  nuevo, sobre todo el primer capitulo de la saga y  también que repasaseis las malditas SOLUCIONES a los ejercicios del capitulo segundo.

Al plantearme la realización de la tercera entrega de este emocionante historia, una profunda duda atenazaba mi pluma… y no, ¡no!, no era la falta de tinta… La cuestión es si debía realizar un capitulo centrado en la teoría, como el segundo, o encaminado a la práctica, como en cierta forma el primero…???. Entendámonos, tenía claro la inclusión de bastantes ejemplos, imprescindibles para una buena comprensión de las ideas a ilustrar, pero no tenía tan claro el enfoque general que debía utilizar: ¿teórico con ejemplos, puramente práctico…, o alguna posición intermedia…?. Al final, se impuso el enfoque pragmático, es decir, el enseñar mediante la práctica, práctica y práctica directa, aunque introduciendo un poquito de teoría…

2.“PAPÁ” MICROSOFT, “MAMA” KONAMI… ¡y EL “TIO” GREMLIN….!.

Imagino la cara de mi amigo Antonio al leer esto y supongo que, una vez más, correrá a recordarme mi exagerada e injustificada – según él -, admiración por Gremlin Graphics. Tampoco escatimará esfuerzos en advertirme de lo exagerado que resulta ponerla junto a estos dos auténticos monstruos de la programación. En mi defensa diré que la graduación expuesta (Microsoft-Konami-Gremlin) responde a una exacta jerarquía en lo que a mis gustos se refiere, basada en el nivel de programación sobre el MSX que, a mi juicio, alcanzaron en su momento. Cierto, que otras empresas han superado con creces a Gremlin programando, pero  el hecho de que el primer videojuego que compré fuese suyo, ¡y fuese muy bueno! (fue el Avenger), es algo que impactó como una bala de Magnum 45 en mi mente infantil. Un recuerdo imborrable, ya lo creo…  Pero dejemos las bonitas palabras y empecemos de una maldita vez…

El presente capitulo estará dedicado a la DESPROTECCIÓN, entendido el término como lo definí en el capitulo segundo, de programas “TURBO” (programas que hacen rayitas multicolores en pantalla al cargar) como son los de GREMLIN, TOPO, y muchos otros…

2.1.TURBO GREMLIN 16 VÁLVULAS G.T.I.

Coge el LISTADO 1 de los que incluyo como ANEXO de este capitulo. Es el Analizador de Slots de Gremlin. Échale un breve pero intenso vistazo y haz con el lo siguiente:

  • Tecléalo en el GEN, el RSC II, asMSX ,…, ensámblalo y una vez sin errores grábalo para futuras utilizaciones.

(Si quieres ahorrarte este trabajo -¡gandul!’-, éxtraelo de algún programa original).

No es necesario saber como funciona, con tal de que funcione (enfoque pragmático, recuerda). De cualquier forma si te pica la curiosidad al respecto házmelo saber…

  • A continuación, coge el Loader “Estándar” de Gremlin, LISTADO 2. (Lo de estándar entrecomillado viene a cuento porque esta empresa, en sus primeros tiempos, no utilizaba este programa cargador en sus juegos.

Supongo que el listado ensamblador te sonará a chino, como mínimo… ¡No te preocupes, a mi me ocurre igual…!, y como lo mío no son los idiomas,  no voy a malgastar tu tiempo y el mío en intentar explicarte instrucción por instrucción el funcionamiento del programita.

Por  razones que no vienen a cuento, y que comprenderás en cuanto profundices en tu estudio del librito sobre el Z80 de Rodnay Zaks, los programas cargadores de “turbo” utilizan TODOS (los que conozco y he visto hasta hoy) la siguiente convención:

a) El registro IX se usa para cargar la dirección inicial de almacenamiento en memoria del bloque a cargar.

b) El registro DE contiene la longitud en bytes del bloque de datos a cargar.

c) El acumulador (A) suele cargarse con el valor 255 o cercano y la bandera de acarreo (C) suele ponerse a 1 antes de….

d) Llamar a la SUBRUTINA GENERAL DE CARGA, que existe SIEMPRE, y cuya misión será cargar los bloques desde el casete (en función de los datos contenidos en IX, DE, A y C).

Nota: El requisito c) no es tan genérico como los otros tres.

Como toda convención matemática, ésta puede parecer un tanto arbitraria. ¡Nada más falso!; he usado alegremente la palabra “convención”  para dar a entender un uso  continuado o generalizado, pero  en realidad no se trata de convención en sentido estricto (no es que los programadores se hayan reunido para decidir que siempre deba ser así, ¿está  claro?). Nada impide cargar  programas turbo de otra manera (piensa por ejemplo, en los que hacen rayitas de un mismo color al cargar, a los que no puede aplicarse esto)….

La primera diferencia que salta a la vista entre el método de cargar programas BASIC (Bload) y éste, es que no existe dirección inicial ni dirección de ejecución. Si lo piensas bien comprenderás que no son necesarias, pues con una dirección inicial y una longitud de bloque puede cargarse cualquier fichero secuencial desde cinta.

Pero volvamos al programa cargador de Gremlin:

Se inicia en la dirección ram &HD800 (55.296) y acaba en &HD980 (55.680), aunque realmente acabe en &HD8F1 (55.537). Vamos a comentarlo paso a paso mientras sea necesario:

LD A, 2
CALL &H5F

Estas dos instrucciones activan el Screen 2, en este caso. Esto se consigue cargando en el acumulador el número de Screen deseado y llamando a la rutina BIOS situada en la dirección &H5F, que se encarga de activarlo.

DI

Desactiva las interrupciones del Lenguaje Máquina.

LD IX, &HD8ED                 IX= Direcc. Inicio Ram almacenamiento.
LD DE, &H4                         DE= Longitud bloque (bytes)
LD A, &HFE
SCF
CALL  &HD837

El registro IX se carga con la dirección RAM &HD8ED (dirección de inicio en memoria de la “minicabecera” Gremlin). En el registro DE se introduce el valor 4, que es el número de datos a cargar desde el casete (longitud de la “minicabecera”). En (A) se carga el valor 254 y el acarreo (C) se pone a uno con SCF. A continuación se realiza una llamada –CALL– a la SUBRUTINA GENERAL DE CARGA, que introducirá en memoria (a partir de &HD8ED) cuatro datos (DE) desde el  casete.

Hagamos un pequeño alto en el camino para explicar tres cosas de suma importancia:

  • Al ir a desproteger programas de este tipo por vuestra cuenta y estar desensamblando el programa cargador, deberéis buscar SIEMPRE una secuencia de instrucciones lo más parecida posible a la última comentada. Huelga decir que cuanto más similar sea la encontrada a ésta,  tanto más fácil será desproteger ese programa…. ¡y viceversa! (cuantas más instrucciones existan antes de la secuencia o intercaladas con ella más difícil será la desprotección).
  • También es evidente, pero no por ello dejaré de decirlo; cuantas menos instrucciones encontremos desde la dirección de ejecución del programa cargador (inicio REAL del mismo) hasta dar con la secuencia mencionada, tanto más fácil será, por lo  general, desproteger ese programa. Es obvio  si pensamos que las instrucciones precedentes pueden modificar el estado de los slots, la peligrosa pila, etc, con lo cual al retornar al Basic tras cargar un bloque de datos deberemos revertir a su estado original nuestro MSX (lo que requiere ampliossss  conocimientos por nuestra parte).

Como puedes observar en el listado ensamblador, los programas de Gremlin lo único que hacen antes de cargar un bloque de datos es activar el  Screen 2, cosa que a primera vista no parece muy grave, ¿verdad?.

  • La peculiaridad genial que distingue a Gremlin de las demás empresas que han usado el sistema “turbo” para cargar sus programas es, precisamente, la secuencia de instrucciones analizada y lo que ésta significa.  Así, mientras las demás empresas tenían que realizar un programa cargador para cada juego, pues  los contenidos de IX y DE variarán para cada bloque de datos, los chicos de Gremlin, más pillos y gandules que otros, se ahorraron este tedioso trabajo de tecleado mediante una sencilla pero genial variación…..¡INCLUYERON UNA MINICABECERA!, precediendo a cada bloque que contenía la dirección de inicio (IX) y la longitud (DE) del bloque tras ella. Son esos 4 bytes que veíamos al explicar las instrucciones.

Hicieron posible así un CARGADOR ESTÁNDAR PARA TODOS SUS PROGRAMAS, ya que las direcciones están grabadas en cinta y no  es preciso reescribir el programa cargador  para cada nuevo juego.

¡Pues vaya estupidez, pensarás…!. Pues vaya estupidez la de los demás, que NO lo hicieron; malgastando tiempo de programación, léase “dinero”, tontamente.

En honor a la verdad debo decir que Gremlin siguió,  consciente o inconscientemente, los pasos de “PAPA” MICROSOFT, el primero en hacerlo para MSX con sus Bload’s. Por algo está MICROSOFT la primera de mi lista….

Hecho este  pequeño paréntesis, continuemos:

JR NC, &HD805

Si el acarreo es uno (1) sigue buscando un bloque de datos en la cinta para cargarlo, porque no se ha cargado todavía nada. Si el acarreo (C) vale cero (0) continua.

LD IX, (&HD8ED)
LD DE, (&HD8EF)
LD A, &HFF
SCF
CALL &HD837
JR NC, &HD805

Si se ha cargado la cabecera, pues sino no se ejecutarán estas instrucciones, IX se carga con el valor contenido en la dirección de memoria &HD8ED (donde se guardan los dos primeros bytes de la minicabecera, o sea, la DIRECCIÓN DE INICIO del bloque de datos grabado a continuación en la cinta). El registro DE se carga con el valor contenido en &HD8EF, donde están almacenados los dos últimos bytes de la minicabecera, es decir, la LONGITUD  del bloque a cargar). Se actualizan el acumulador (A=255) y el flag de acarreo (C=1) para llamar a la SUBRUTINA GENERAL DE CARGA, que comienza en la dirección &HD837.

Si deseas saber como funciona en concreto dicha SubRutina no tienes más que preguntar. Como se  trata de un tema harto largo y complejo no voy a extenderme en su explicación, pero si te diré que esta SubRutina carga el bloque de datos desde el casete si previamente a llamarla con call se han inicializado los registros IX, DE, A y el flag C con los valores necesarios.

Ya no necesitas seguir comentando el programa cargador, puesto que una vez ejecutadas estas instrucciones tendremos cargado en memoria el bloque que empieza en la dirección de memoria contenida en &HD8ED y cuya longitud está contenida en &HD8EF. Ahora bien, ¿Cómo hacernos con el control del sistema y evitar que el programa  cargador siga ejecutándose (e.d., cargando bloques hasta el final, y haciendo luego funcionar el juego cargado)?. Pues, en el caso de Gremlin (no modifica slots, ni la pila ni nada) esto  es de lo más sencillo.

Cambiamos:

      LD HL, (&HD8ED)    (2A, ED, D8)  3 bytes

Por:

      RET    (C9)
      NOP    (0)       3 bytes
      NOP    (0)

Y una vez cargado el bloque, el propio programa cargador retornará al BASIC  devolviéndonos gentilmente el control del sistema.

Ahora es el momento de que cargues el LOADER de Gremlin con el MON (o RSC II) e introduzcas la mencionada variación.

La instrucción que queremos modificar —->LD HL, (&HD8ED) se encuentra en la Dirección de Memoria &HD825 y como hemos visto ocupa 3 bytes.

-Para modificar esos 3 bytes desde el RSC II tendremos que hacer lo siguiente:

PO &HD825, &HC9
PO &HD826, &H00
PO &HD827, &H00

-Si quieres hacer esa modificación desde el Basic se haría así:

POKE &HD825, &HC9
POKE &HD826, &H00
POKE &HD827, &H00

Nota: como puedes ver &HC9 es la instrucción RET y que &H00 es la instrucción NOP.

-Para grabar el Programa modificado desde el RSC II tendrás que hacer lo siguiente:

GB”NOMBRE”, &HD800, &HD980, &HD800

-Para grabar el Programa modificado desde el BASIC tendrías que hacerlo así:

BSAVE”NOMBRE”, &HD800, &HD980, &HD800

Pues con ese Programa que acabamos de grabar ya casi tienes un copión estándar para Gremlin. Te falta tan sólo un pequeño módulo base en BASIC que controle la E/S desde el teclado y  cargue el “TURBO” para grabar BASIC. Ese programilla (Listado 3) lo único que hace es cargar el programa cargador modificado – valga la rebuganancia- y ejecutarlo, con BLOAD”CAS:”, R primero y DEFUSR=&HD800: A=USR(0) después. Este programa nos carga los bloques “turbo” desde la cinta (ejecutando el programa cargador) y nos devuelve el control al módulo base en BASIC. Entonces nosotros calculamos la Dir. Final del Bloque (DF = Dir contenida en &HD8ED + Dato contenido en &HD8EF) y lo grabamos en Basic con:

BSAVE”nombre”, (&HD8ED), Dir. Final, (&HD8ED)

Los paréntesis significan “contenido  de la dirección de memoria X”. ¡Por cierto!, si quieres leer ese contenido directamente puedes hacer:

?PEEK (&HD8ED)+256*PEEK (&HD8EE) lo que te dará la dir. Inicial del bloque.

?PEEK (&HD8EF)+256*PEEK (&HD8F0) lo que te dará la long. del bloque a cargar.

Te habrás dado  cuenta de que los bloques de datos de Gremlin están ESTRUCTURADOS, e.d., su dirección de ejecución y su dirección de inicio SIEMPRE COINCIDEN. Esto no tiene porque ocurrir, y de hecho no ocurre con otras marcas.

Si repites la operación de carga/grabación con todos los bloques del programa, ya “casi” lo tendrás desprotegido El problema consiste ahora en ingeniárselas para cargarlo desprotegido  (¡y funcionando a ser posible!). Esta cuestión será una autentica comedura de coco con otros programas, pero no con los de Gremlin. Además de estar ESTRUCTURADOS, éstos también se AUTOEJECUTAN (los bloques), e.d.; se transfieren automáticamente a las direcciones de memoria definitivas en las que residirán los datos cargados. Por todo ello, para cargar un juego desprotegido de esta empresa, el único cargador que precisas es el siguiente:

10 Rem LOADER GREMLIN
20 COLOR 15, 1, 1: SCREEN 2
30 BLOAD”CAS:”, R: GOTO 30

Teclea el anterior, y complejo, programa y  grábalo en cinta. Tras él, graba el Analizador de Slots de Gremlin, seguido de los bloques del programa desprotegidos (y en el mismo orden del original)….¡et voila!. Todo listo para la carga. 😉

Desconozco si con unidad de discos los juegos de Gremlin plantean problemas específicos  de carga, pero lo que es  con el casete, ¡la cosa va como la seda!. Ahora bien, si grabas el programa desprotegido en disco no podrás percibir un pequeño-GRAN detalle: el programita desprotegido tarda ¡MUCHO MÁS! en cargar que el original (o “turbo”). Evitar el pirateo, ja, ja, ja…. y agilizar la carga, fueron las dos poderosas razones  por las que los programadores idearon este sistema especial de grabar/cargar datos en/con el casete.

3.NIVEL 2: “LEARNING TO FLY”.

Puede decirse que hasta el momento no hemos progresado gran cosa. ¡Cierto!, hemos desprotegido programas de Gremlin, pero esto, gracias a la propia Gremlin, ha resultado tan fácil que incluso nos ha dejado con mal sabor de boca. Va siendo hora de atreverse con algo bastante más difícil; p.ej. el juego BLACK BEARD, de Topo Soft.

Para empezar, hazte con una copia protegida del mismo y procede como sigue:

  1. Carga la presentación (el nombrecito saltarín) estando muy atento para hacer CTRL+STOP nada más ejecutar ésta.
  1. Teclea LOAD”CAS:” Una vez hayas cargado el pequeño programita Basic, examínalo. Verás que a continuación hay grabados dos bloques, llamados TEST y LOAD. El primero es el analizador de Slots de Topo, el segundo es el Loader o programa cargador (os envío su listado aparte para que lo veáis). Extraed los dos programas en una cinta aparte.

Lo primero que debes hacer para desproteger un programa es desensamblar (usando MON o RSC II) su programa cargador y sacarlo por impresora si puedes. En todo caso puedes copiarlo en papel, a mano, o a máquina…

A continuación averigua CUÁNTAS cargas, léase bloques, tiene ese programa. Para hacerlo debes localizar la “secuencia” antes mencionada partiendo, en tu búsqueda, desde la dirección de ejecución del programa  cargador (no  desde la inicial, ¡¡mucho ojo!!). Puede serte útil cargar el programa normalmente antes de empezar a desproteger, contando con los deditos los bloques que tiene…..

En el caso concreto del BLACK BEARD hallarás estas “secuencias” de instrucciones:

LD IX, &H9C40       Primer bloque.
LD DE, &H1BBA      Screen

……..

LD IX, &H2328        Segundo bloque
LD DE, &H32C8

……..

LD IX, &H55F0       Tercer bloque
LD DE, &H2A00

……..

LD IX, &H8400        Cuarto bloque
LD DE, &H4FFF

Visto esto, no es necesario ser Einstein ni tener el C.I. de Goethe para  darse cuenta de que el juego tiene cuatro bloques protegidos. En este momento conviene hacer una pausa y recapacitar, ordenando de paso la información que conocemos. Yo lo solía hacer así: (es muy útil, casi vital)

BLACK BEARD:  Loader —>  D6D8D81CD6D8

1er.   Bloque —> Ini = &H9C40        Longitud = &H1BBA (Screen)

2do.  Bloque —> Ini = &H2328         Longitud = &H32C8

3er.   Bloque —> Ini = &H55F0        Longitud = &H2A00

4to.   Bloque —> Ini = &H8400         Longitud = &H4FFF

(&HD6E6) –-> Dir. INICIO.

(&HD6E9) –-> LONGITUD bloque.

>&HD71F –-> SUBRUTINA GENERAL DE CARGA.

Modifiquemos ahora el programa cargador, con el objeto de que cargue un bloque “turbo”  y nos devuelva el control al Basic. Coloquemos un RET y dos NOP tras la primera llamada a la Subrutina General de Carga, es decir, en &HD6F1.

Fíjate en el principio del programa cargador. Verás que, antes de cargar nada, se hacen una serie de llamadas a subrutinas; subrutinas de las que no conocemos los efectos. Luego, en principio, es peligroso ejecutarlas (en este caso estas rutinas tienen por objeto analizar los slots y subslots y conectar la configuración de memoria TODO RAM). No debemos ejecutarlas pues de hacerlo nuestro MSX se quedaría colgado al intentar retornar a un  Basic desconectado. Para saltarnos estas llamadas deberemos POKEAR las direcciones de memoria justamente anteriores a LD IX, &H9C40, e.d., desde &HD6E1 hasta &HD6E3. Introduciremos los valores 0, 0 y F3 (o  sea, NOP, NOP y DI). En realidad basta con pokear una dirección antes de la citada instrucción, pero yo prefiero ser un poco más cautelososo.

  • Estamos en condiciones de cargar el primer bloque del programa; cosa que haremos con DEFUSR=&HD6E1:A=USR(0). ¡Por cierto!, no estaría de más que antes grabases el programa cargador modificado  en una cinta aparte  por si se te quedase bloqueado el ordenador. Así te ahorrarías tener que repetir todo el proceso (¡créeme, sería muy raro que no se te colgase a menudo!).

Carga el primer bloque, la pantalla de presentación, y grábalo con BSAVE”nombre”, &H9C40, &H9C40+&H1BBA (&HB7FA). Puedes ejecutar la portada para verla si lo deseas, con:

10 SCREEN 2: DEFUSR=&H9C40:A=USR(0)

  • Vamos a por el siguiente bloque (segundo bloque). Pero ¡OJO!, antes de cargarlo hay que actualizar la dirección de inicio y la longitud, haciendo:

POKE &HD6E6, &H28   La dirección se debe pokear al revés
POKE &HD6E7, &H23    por eso conviene trabajar en hexadecimal.

&H2328 es la dir. de inicio REAL del segundo bloque.

POKE &HD6E9, &HC8    LB –> Byte bajo en dir. ram menor
POKE &HD6EA, &H32    HB–> Byte alto en dir. ram mayor.

                                                           Tiene su lógica, ¿no?

Y &H32C8 es la longitud del mismo.

Ahora podríamos cargar el segundo bloque con DEFUSR=&HD6E1:A=USR(0) pero….¡¡¡ALTO!!!, ¡¡ESPERA!!, ¡NO lo hagas todavía!.

Aunque “podamos” cargarlo (que NO podemos  por estar las paginas 0 y 1 conectadas en ROM), ¿no te parece que cargarlo en su dirección de inicio REAL (&H2328 es Ram oculta al  basic) no nos sería muy útil?, porque a ver, una vez cargado ¿cómo puñetas íbamos a grabarlo con BSAVE?. Tanto BLOAD como BSAVE operan con la RAM comprendida entre &H8000  y &HFFFF porque, como es lógico, para que funcionen estas instrucciones han de estar conectados el BIOS y el BASIC (Rom). Por eso, si grabas con una dirección inferior a &H8000, estarás grabando la Rom. Y si estás pensando en cargar algo en Rom…¡pégate un capón de mi parte!.

Sabemos que no podemos cargar nada por debajo de &H8000 (32.768) en Basic; de hecho, ni siquiera podemos empezar a cargar por esa dirección puesto que precisamente en &H8000 comienzan a almacenarse los programas Basic (y no nos olvidemos del pequeño  cargador  Basic que deberemos hacer para cargar el Black Beard desprotegido). No recomiendo cargar nada por debajo de &H8200, reservando esos 512 bytes  para el cargadorcito basic.

La táctica a emplear es clara: cambiar la dirección de inicio REAL del bloque  por una dirección TEMPORAL (o ficticia) que se encuentre en Ram Basic (desde &H8200 hasta &HEF00). Por encima de &HEF00 es peligroso cargar datos porque podrían colisionar con la PILA BASIC.

Para encontrar esa dirección TEMPORAL hay que tener presente la longitud de los bloques a cargar. Si la dirección  escogida es muy elevada, p.ej. &HD000, los datos cargados colisionarían con el programa cargador y ¡ahora sin duda!, se nos bloquearía el ordenador.  O sea, que en realidad puedes cargar los bloques del Black Beard entre las direcciones &H8200 y &HD6D7. En total son 21.719 bytes libres, un buffer de carga/grabación de un tamaño  más que suficiente si consideramos que el bloque más largo del Black Beard mide &H4FFF (20.479 bytes).

Vamos a asignarle al segundo bloque una nueva dirección de inicio (temporal) como p. ej. &H8400:

    POKE &HD6E6, &H00
    POKE &HD6E7, &H84

Ahora SI estamos en condiciones de cargar este bloque; cosa que haremos de inmediato como ya sabemos (DEFUSR=……). Una vez cargado lo grabaremos,  tras el primero con BSAVE”nombre”, &H8400, &H8400+&H32C8  (&HB6C8).

  • Vamos a por el tercer bloque, que al igual que el anterior tiene su inicio real en Ram oculta. Habrá que cargarlo en Ram Basic (y, ¿por qué no a partir de &H8400 otra vez?). ¡Hagámoslo!:

      POKE &HD6E9, &H00
      POKE &HD6EA, &H2A

No hace falta alterar la dirección de inicio, &H8400. Tranquilo si esto te suscita alguna duda –muy lógica. Más adelante volveremos sobre este tema. De momento, graba este tercer bloque con BSAVE “nombre”, &H8400, &H8400+&H2A00 (&HAE00).

  • El último bloque (bloque cuarto) también se cargará  a partir de &H8400 (que es “casualmente” su dirección de inicio real). Tendremos que modificar la longitud en el programa cargador, como sabemos hacer….¡venga!, ¿a qué estás esperando para hacerlo?:

      POKE &HD6E9, &HFF
      POKE &HD6EA, &H4F

Cárgalo como siempre y grábalo tras los otros bloques. La desprotección, propiamente dicha ha terminado. Hemos desmontado el PUZZLE, …. ahora debemos montarlo y encajarlo para que todo funcione de nuevo.

Por si no tienes claro lo que hemos hecho hasta ahora, aquí te lo resalto de un modo más gráfico. Esta es la situación presente:

NUESTRA GRABACIÓN EL ORIGINAL
1er bloque: Una pantalla de carga que  no se ejecuta.

 &H9C40&HB7FA&H9C40

Una pantalla de carga que se ejecuta, en:

 &H9C40&HB7FA&H9C40

2do. Bloque:Un bloque de datos descolocado en :

        &H8400&HB6C8

Un bloque de datos perfectamente colocado en Ram oculta:

          &H2328&H55F0

3er. Bloque: Un bloque de datos alucinado en:

        &H8400&HAE00

Otro bloque que  por “suerte” está en su sitio en:

          &H55F0 &H7FF0

4to. Bloque: El último mohicano.

        &H8400&HD3FF

La oveja negra de la familia:

          &H8400&HD3FF

Eso sin hablar  del Analizador de Slots y del Loader basic que nos faltan. ¡Vale!, los resultados no son muy brillantes, lo reconozco. ¿Qué esperabas de un “Hacker” de cuarta regional como yo? (¡Ah!, los tiempos del abuelo JACK. ¡Aquellos si eran años!).

«El viejo vaquero limpió con dignidad la pernera de su gastado pantalón. Agachó la espalda, estirando su  brazo hasta coger su pisoteado sombrero. Se lo puso y, levantando la vista al cielo, sintió el reseco aliento del desierto en su garganta.» 

«”Perro” Clyde arrastraba su malherido brazo en un desesperado intento de alcanzar su revolver. El viejo vaquero bajó la cabeza. Su rostro, antaño sonrosado, su ingenio, siempre vivaz, se habían esfumado. Su semblante era la viva imagen de la muerte.»

«Avanzando unos pasos hacia Clyde se detuvo a su lado. Al agacharse junto a él, en cuclillas, el “perro” sintió como sus ladridos se le ahogaban en la garganta. La palidez del viejo le hizo comprender, como ninguna palabra podría haber hecho, que había llegado su hora, su minuto y su segundo.»

«Con un rápido gesto el viejo vaquero puso su pistola en la frente de Clyde. Su mano temblaba ligeramente, pero en el tono de su voz no se percibía ninguna duda.

-“Dame una buena razón por la que debas vivir”– dijo.

Y aquel disparo resonó, llevado por el eco de la justicia, en los corazones de los habitantes de Denton City.» (1)

Forastero, ¿has rezado ya tus oraciones?. Más te vale haberlo hecho, porque ahora llega….

OTRO POQUITO DE CÓDIGO MÁQUINA:

Nos volvemos a detener a medio camino (esto se va pareciendo al Talgo Almeria-Madrid) para hacer un par de precisiones:

  • Si te pareció complejo, confuso o complicado lo visto hasta el momento….¡más te vale dejarlo! (y ponerte a empollar el “pequeño manual” de Rodnay Zaks y los dos capitulitos anteriores). De ahora en adelante las cosas van a complicarse cada vez más. Esto irá “in crescendo”….
  • Si te has ido enterando de todo hasta el momento, quizás, solo quizás, hayas sido lo bastante perspicaz como para deducir un axioma de la programación en C/M:

“UN PROGRAMA (C/M) SOLO SE EJECUTARÁ CORRECTAMENTE SI ES CARGADO EN SUS DIRECCIONES DE MEMORIA ORIGINALES (DONDE FUE ENSAMBLADO)”.

Como casí todas las máximas, ésta es una perogrullada y, ¡para colmo!, tiene sus excepciones (el GEN-MON p. e.). Si bien es cierto existen programas que pueden cargarse –y ejecutarse- en direcciones de memoria variables, siendo conocidos por ello como “reubicables”, no es este el caso de los juegos. Por tanto deberemos, de alguna manera, devolver los bloques desplazados a sus direcciones originales (el segundo y el tercero en este caso).

Desgraciadamente solo podemos hacer tal cosa, por tratarse de desplazamientos a la Ram oculta, trabajando en C/M (comprenderéis ahora el porqué de los capítulos anteriores de este impresentable cursillo). Necesitamos de un programita en ensamblador que realice esas transferencias de datos. ¡Ánimo hombre!. NO es tan  difícil como parece….

Este es el programa TRANSFER para el BLACK BEARD:

10   ORG &HE000
15  ;TRANSFER BYTES

20 BK2:         DI
30              LD A, (&HE292)
40              OUT (&HA8), A
50              LD HL, &H8400
60              LD DE, &H2328
70              LD BC, &H32C8
80              LDIR
90              LD A, (&HE290)
100             OUT (&HA8), A
110             RET

120 BK3:        DI
130             LD A, (&HE292)
140             OUT (&HA8), A
150             LD HL, &H8400
160             LD DE, &H55F0
170             LD BC, &H2A00
180             LDIR
190             LD A, (&HE290)
200             OUT (&HA8), A
210             RET

220 BK4:        DI
230             LD A, (&HE292)
240             OUT (&HA8), A
250             JP &H92AC

Nota: Si quisieras teclear este Programa usando el Ensamblador “GEN” tendrías que cambiar “&H” por “#” (Este Listado que he puesto está hecho para el Ensamblador “RSC II”)

La dirección de inicio del TRANSFER (&HE000) no debe colisionar con las direcciones ocupadas por el juego (&H2328 – &HD3FF). El listado anterior debe ensamblarse con el RSC / RSC II. Una vez ensamblado sin errores, hay que grabarlo en cinta. No debe ser ejecutado porque este programa SÓLO FUNCIONARÁ SI PREVIAMENTE HAS CARGADO Y EJECUTADO EL ANALIZADOR DE SLOTS DE TOPO (¿Te acuerdas del “TEST” del principio?) puesto que utiliza los datos calculados por aquel:

  • &HE292 TODO RAM.
  • &HE290 ROM / RAM.

Venga, vamos a cargar de una vez el “Black Beard” desprotegido. Lo primero es teclear y grabar el programita cargador en  Basic:

10 REM Loader “BLACK BEARD” DESPROTEGIDO.
20 COLOR 15, 1, 1: SCREEN 2
30 BLOAD”CAS:TEST”,R:BLOAD”CAS:TRANSFER”
40 BLOAD”CAS:SCREEN”,R
50 BLOAD”CAS:BLOCK2”:DEFUSR=&HE000:A=USR(0)
60 BLOAD”CAS:BLOCK3”:DEFUSR=&HE(BK3):A=USR(0)
70 BLOAD”CAS:BLOCK4”:DEFUSR=&HE(BK4):A=USR(0)

Nota: BK3 y BK4 son las direcciones de inicio de dichas rutinillas.

Tras esto graba el Analizador de Slots de Topo (“TEST”) y el TRANSFER. Después graba los bloques desprotegidos en orden. El programa ha sido desprotegido por completo y debería cargar perfectamente tanto en cinta como en disco. Ahora bien; ¿qué hace el TRANSFER?, ¿Cómo lo hace?, ¿Y cuándo debe hacerlo?.

El TRANSFER son, en realidad, tres subrutinillas independientes en C/M (BK2, BK3 y BK4 son sus dir. de inicio y ejecución). Cada rutina debe ser ejecutada tras cargar el bloque que deba transferir (colocar en su lugar). Olvídate de momento de la subrutina BK4, muy diferente, y centrémonos en BK2 y BK3. Ambas hacen lo mismo, de igual forma, aunque en diferentes momentos y con distintos bloques de datos. Las comento.

-Lo primero que hacen es desconectar las INTERRUPCIONES con:

            DI

-Es algo que debe hacerse SIEMPRE (¡qué pesaico soy!) antes de conectar o desconectar páginas de memoria (que es lo  siguiente que hacen):

            LD A, (&HE292)
            OUT (&HA8), A

-Conecta la configuración de memoria TODO RAM (sólo si se ejecuta antes el “TEST”. ¡Pero que pesaico soy!). A continuación viene lo interesante:

LD HL, &H8400
LD DE, &H2328 ó &H55F0
LD BC, &H32C8 ó &H2A00
LDIR
 

–>en el registro HL se carga la dirección de inicio TEMPORAL.
–>en el registro DE se carga la dirección de inicio REAL de los datos en Ram.
–>en el registro BC se carga la longitud del bloque de datos a transferir.

LDIR es una instrucción de transferencia automática que hace, ella sólita, todo lo que sigue:

  • “Carga de bloque con incremento repetida”.
  • “El contenido de la posición de memoria HL se carga en la posición DE. A continuación se incrementan HL y DE y se decrementa BC. Si BC es distinto de cero el contador del programa se  decrementa en 2, y la instrucción vuelve a ejecutarse.”

O sea,

INI:     (DE) <– (HL)
             DE = DE + 1
             HL = HL + 1
            BC = BC – 1
            SI BC <> 0 GOTO INI 

Nota: Podría considerarse no obstante la posibilidad de realizar transferencias a Ram oculta desde el BASIC, lo que os evitaría el tener que programar en C/M el BK2 y BK3. Estas transferencias se harían usando un comando ampliado en BASIC, p.ej.:

    CMDLDIR (Dir Fuente, Dir Destino, Bytes Longitud).

Recuerda que soñar sigue siendo gratis (razón de peso para hacerlo….). Pero hasta que los sueños se conviertan en realidades palpables, seguid usando el Ensamblador tal y como os lo he explicado…..

 O sea “again”, que el bloque de datos que se inicia en HL y mide de longitud BC es transferido dato a dato a la dirección contenida en DE. SE dice que LDIR es una instrucción muy potente porque hace sólita un güebo de cosas.

Las siguientes instrucciones son necesarias para restituir la configuración ROM/RAM y retornar al BASIC:

LD A, (&HE290)
OUT (&HA8), A
RET
 

Comprenderás, si entiendes como funcionan las subrutinillas Transfer, que no tenía importancia el grabar y cargar los bloques “turbo” (todos) a partir de &H8400, porque al cargarlos desprotegidos el programa Transfer se ocupará al instante de posicionarlos en sus direcciones reales de memoria.

He dejado a propósito  la explicación del complejo BK4 para el final. A estas alturas, deberías tener claro que el bloque cuarto del programa no necesita transferirse a ninguna parte. Se encuentra en su posición Ram definitiva. Entonces, ¿qué sentido tiene el bloque BK4?.

  • Antes de activar el juego “BLACK BEARD” es necesario activar la configuración TODO RAM. Para eso sirve la rutina BK4….
  • …. pero además, será necesario saltar a la dirección de ejecución del programa (JP es más o menos como GOTO). Con este salto, salto absoluto a la fuerza, perderemos definitivamente el control del sistema y este pasará al programa, como debe ser.

Se te planteará la duda; ¿cómo saber cual es la dirección de ejecución del juego?….¡oye!, ¿tú has mirado el programa cargador del “Black Beard”?. Lo digo porque, sabiendo leerlo y  con un pelín de astucia se comprende que tras cargar el ÚLTIMO bloque de datos lo lógico y lo “normal” es que el programa se ejecute (como en este caso hace, con JP &H92AC).

Hemos acabado con el NIVEL 2 (¡aleluya!). Toma buena nota, sobre todo de las subrutinas Transfer y, en general, de todo el proceso. En el futuro TÚ deberás hacerlo todo solito, incluidas las rutinillas Transfer en C/M….

COMENTARIOS varios:

–  Para que después de cargar un Bloque de Disco la Disquetera se apague debéis incluir este código en vuestros Programas:

            Defusr=&HFD9F:FOR I = 0 to 255: A=USR(0):NEXT

– Si queréis ejecutar el último BLOAD cargado, podéis usar este código:
            DEFUSR=PEEK(&HFCBF)+256*PEEK(&HFCC0):A=USR(0)

  • Incluiré en un Capítulo 4 o Capítulo ANEXO los Listados de todos los Programas aquí mencionados.

TO BE CONTINUED…


4.EJERCICIOS DELCAPITULO 3 (I): 

-Consigue todos los juegos de Gremlin que puedas, en versión protegida, y lánzate a su desprotección. TODOS, ABSOLUTAMENTE TODOS, se desprotegen de la forma explicada, aún cuando no posean el Loader Standard (como p. ej. el Valkyr).

Es evidente que NO DEBES usar el copión  de Gremlin. NO se trata de que nos lo den todo hecho y nos conviertan en semivegetales estúpidamente fascinados ante la pantalla, en seres no-pensantes (para eso, para comodidad, ….¡CÓMPRATE UN PC!). Se  trata de aprender a pensar y a realizar las cosas por uno mismo. Este es el camino más duro, el más difícil; pero también es el más gratificante.

Desproteger los programas “a mano” es una labor pesada, repetitiva, ingrata….¡bien lo sé, por propia experiencia!… pero también sé que no existe alegría comparable a la que siente un programador aficionado cuando, ante una rutina o programa (por simple que sea), tiene la satisfacción de decir: “LO HE HECHO YO”. Estas cuatro palabras abren las puertas del paraíso al autentico amante de la Informática (¿Es orgullo o simple vanidad lo que encierran estas palabras?. Algo de ambos hay, no voy a negarlo, pero en mi caso prefiero creer que encierran autoestima, autoafirmación, simple satisfacción por lo  conseguido). Para mi la Programación es, sobre todo, un desafío que YO resumo en la frase: “¿QUÉ SERÉ CAPAZ DE HACER MAÑANA?”. Sólo aprendiendo, practicando, pensando, HOY podré recoger el guante y afrontar el mañana, y….

….¡DEMONIOS! ¿Os habéis dado cuenta de cómo me enrollo y enrollo, y me largo en un plis-plas por los cerros de Úbeda?. ¡Cosssaaa Mala…..!).

Paco Persiana.

La autoestima es la madre de la vanidad y la satisfacción la madre del orgullo. Como decía ARISTOTELES, «En el centro está la virtud». NO creo que casi NADA tomado en su justa medida sea negativo….

P.D. En  primer lugar, quiero realizar una aclaración de suma importancia… Este curso fue creado originalmente por FRANCISCO FUENTES LORENZO. El formato original del mismo son fotocopias escritas a máquina, y que yo JOSÉ MANUEL SOTO, he intentado pasar a pdf  para luego aplicarle soft de OCR, pero viendo los desastrosos resultados he optado por teclearlo todo letrita a letrita en formato WORD, respetando fielmente el original….

Para cualquier aclaración, comentario, sugerencia, etc, etc… no dudéis en escribirme. Me  gustaría que todo aquel que tenga conocimientos sobre el tema, y pueda contribuir a mejorar este curso, ampliarlo, corregirlo, etc, que se anime y me escriba. También me gustaría me escribierais para darme vuestra opinión sobre el mismo, si lo habéis leído, y tenéis intención de seguirlo, etc, etc, etc… Y aprovecho, aún a riesgo de ser pesado que por favor, todos los que tengaís material MSX por ahí que sea interesante para el resto (Libros, Revistas, Documentación Técnica, etc, etc, …) o  si sabeis de alquien que lo tenga, que lo escaneéis y lo paséis a pdf para compartirlo con el resto  y que todo ese valioso material no desaparezca con el paso del tiempo!!!).

Gracias al Paco y al Robsy por animarme a llevar a cabo esta iniciativa y a Karloch por darle difusión. Y gracias, mil veces gracias al Paco que casualidades de la vida nos hemos vuelto a “encontrar” después de mucho tiempo, mucho, mucho tiempo… Gracias y mil veces gracias Paco por tus cartas, los juegos que gracias a ti conseguí, las dudas que me resolviste, tu infinita paciencia y por haber escrito este curso en su día”exclusivamente para mi”… (ja, ja, ja… quien te iba a decir esto por  aquel entonces, ¿eh?).

¡¡¡Va por ti, MAESTRO…!!!

Antes de despedirme “definitivamente” quiero aclarar que la realización de este tercer y último capitulo ha sido muy, muy dura debido a que he tenido que conseguir los listados (que incluiré en un Cuarto y último Capítulo como ANEXO) y revisarlos y “formatearlos”…. El LOADER ESTANDAR DE GREMLIN lo he conseguido gracias a Javi (alias Nazgul en Hispamsx) 😉

Como veis, esto ha llegado a su “fin”… Como consejo práctico os diré  que os imprimais todo este curso, incluido su siguiente y último Capítulo-ANEXO con los listados y que lo releáis una y otra vez si es necesario… haciendo las anotaciones pertinentes y subrayando todo lo que creáis necesario… Cuando os sintáis con el valor y las fuerzas suficientes ya sabéis lo que os queda: afrontar vosotros solos el reto de lanzaros a desproteger por vuestra cuenta y riesgo…

Me gustaria que todos aquellos que os lanceis a la aventura de la desprotección y consigais desproteger algún juego lo compartais conmigo y ¡¡¡con los demás!!!. Estaría bien que redactarais un “mini tutorial” explicando las peculiaridades del juego, como lo habéis abordado, etc,  etc, etc… De esta forma todos podremos aprender y establecer diferentes técnicas a la hora de abordar diferentes juegos y  diferentes compañías. Quizás cada compañía (Dinamic, Topo, Opera, etc, etc, etc, etc…) hayan seguido de una forma consciente o inconsciente los mismos esquemas a la hora de “proteger” sus juegos, así que os reto y os invito a que lo comprobeís, a que investigueis, a que pongaís en práctica todo esto,y a que lo COMPARTAIS….

(Si, lo sé…, sé que soy un pesado…. pero si yo no hubiera compartido todo esto con vosotros ahora sabriáis un “poquito menos”, y si el resto de los usuarios no hubiera hecho lo mismo imaginad lo que hubiera pasado….). Así que os animo a que compartais todos vuestros conocimientos, juegos, programas, documentación técnica, revistas, libros, etc, etc, etc con el resto de los usuarios, a que los escaneéis y los paséis a pdf para que puedan llegar al maximo de gente posible y  todo este valioso material e información no se pierda con el paso del tiempo.

josemanuel74@gmail.com

Anuncios
Esta entrada fue publicada en Sin categoría. Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s