012:software

Microhobby 12. Año II, del 22 al 28 de enero de 1985

Lorenzo Cebeira

Más de una vez he oído decir que los usuarios del Spectrum nos dividimos en dos categorías: los que pasan noches en blanco ideando nuevos trucos para proteger sus programas contra miradas indiscretas, y los que pierden el sueño intentando hacer saltar estas protecciones.

No estoy seguro de a qué categoría pertenecen los lectores de MICRO-HOBBY, sospecho que a las dos, pero no me cabe duda que una buena parte debe tener unas hermosas ojeras causadas por estas apasionantes actividades. Espero que este pequeño artículo les permita recuperar alguna de las horas de sueño perdidas.

Cuando hablamos de protección de programas podemos referirnos a dos cosas: la primera consiste en evitar que éstos se puedan duplicar. En este terreno los trucos son infinitos aunque, por desgracia para las casas de software, un buen par de magnetófonos bastan para desarticular el más protegido de los programas.

Siempre quedará el purista que considera que este método no tiene mérito, pero la verdad es que sigue siendo el más utilizado. La última astucia de los fabricantes consiste en entregar el programa con una lista de claves necesarias para su funcionamiento, la cual está impresa en colores de poco contraste para dificultar la fotocopia. Sin embargo poca gente se asusta a la hora de copiar a mano esta lista si el programa merece la pena. Hasta tal punto han llegado las cosas en este terreno, que comienza a extenderse la creencia de que un programa fácil de copiar no debe ser muy bueno… En mi opinión, estas técnicas de protección son algo inútil, no conozco ninguna que pueda resistirse a un usuario medianamente avanzado, y por lo demás, mientras no se prohiba la tenencia de dos magnetófonos, no va a haber quien pare el fenómeno de la piratería de programas.

En este estado de cosas más vale pasar al otro terreno de este campo de batalla: la protección de los programas destinada a evitar que puedan ser listados o modificados por el usuario.

En este género de protección tiene también un significado económico. En la mayor parte de los países, y el nuestro no es una excepción, la legislación sobre propiedad industrial e intelectual no protege, o protege muy mal, los derechos del autor de un algoritmo, de una idea para un videojuego, etc… Basta ver la cantidad de versiones que existen del famoso comecocos, para convencerse del perjuicio económico que supone esta falta de las legislaciones. Lógicamente, la reacción de los fabricantes consiste, una vez más, en acudir a los trucos de protección para evitar que otras personas puedan listar los programas y aprovecharse de las ideas y técnicas de los mismos. A diferencia de lo que ocurre en la protección contra copia, aquí sí es posible llegar a resultados bastante buenos, como vamos a ver a continuación. La otra cara de la moneda es que estas protecciones suponen, muy a menudo, un fastidio cuando nos interesa modificar un juego para aumentar, por ejemplo, el número de vidas, pasarlo a microdive, o para cualquier otro propósito legítimo. Es, pues, interesante conocer la panoplia de trucos más comunmente empleados.

El primero y más conocido es el clásico POKE 23659,0 que tiene por efecto bloquear nuestro ordenador si intentamos hacer un BREAK. La variable del sistema DF SZ cuya dirección es 23659 gestiona el número de líneas en la parte inferior de la pantalla. Si reducimos a cero este número, nuestro Spectrum no va a poder imprimir nada en esta zona de la pantalla y comoquiera que es precisamente aquí donde se van a imprimir los mensajes de error como el conocido «L BREAK into program» se producirá el clásico bloqueo que nos obligará a desenchufar nuestro ordenador o hacer uso del botón de reset en el caso de que lo hayamos instalado. El gran inconveniente de este truco es que no nos va a permitir utilizar la instrucción 1NPUT, por lo que si queremos introducir datos tendremos que hacerlo a través de la instrucción INKEY$.

Otra forma más elegante de obtener el mismo resultado es mediante POKE 23613,0 que provocará un reset si intentamos parar el programa con la ventaja de no inutiizar la parte baja de la pantalla. En esta dirección 23613, se encuentra la variable ERR SP que indica al Spectrum dónde tiene que saltar en el caso de error y para nuestro ordenador, el BREAK o cualquier interrupción del programa se trata como un error. Modificando la dirección de salto forzamos la ejecución de la rutina de inicialización produciéndose el borrado total de la memoria.

Otra variante del mismo tema, más elegante todavía, es desactivar el BREAK recurriendo a la misma variable. En este caso, la instrucción a emplear es POKE 23613,82, con lo que en caso de BREAK forzamos un salto a la misma línea donde estaba ejecutándose el programa. El inconveniente de este truco es que no es permanente. Los bucles FOR-NEXT, los GOTO y los GOSUB-RETURN lo desactivan, por lo que es necesario repetir el POKE de marras, antes y después de cada instrucción de este tipo.

Todos estos trucos tienen, sin embargo, un grave problema. Basta con cargar el programa en memoria, pero evitando su autoejecución, para tener libre acceso al listado, que es lo que se trata de evitar. Hace ya mucho tiempo que se descubrió que basta con cargar un programa mediante la instrucción MERGE “” en vez de LOAD “”, para evitar que éste empieze a funcionar, por mucho que lo hayamos grabado con SAVE “ … ” LINE XXXXX. Pero como es lógico suponer, la alegría de los «piratas» duró poco tiempo. Rápidamente surgieron nuevas técnicas para evitar el MERGE. Las dos más conocidas consisten en grabar el programa como «Bytes» y provocar un bloqueo si se intenta utilizar el MERGE. Veámoslas con más detalle:

La primera de ellas requiere pararnos un poco a pensar en cómo funciona el intérprete BASIC de nuestro Spectrum. Cuando damos la orden de RUN el intérprete busca en las variables del sistema la dirección de comienzo del programa, toma nota del número de línea, la ejecuta y pasa a la siguiente. Cada vez que se termina de ejecutar una instrucción, las variables del sistema se actualizan para que en todo momento se sepa qué parte del programa está procesándose. Basándose en este principio, se pensó en grabar en el cassette el bloque de memoria que contiene no sólo el programa, sino también las variables del sistema, la zona de memoria donde se encuentran las direcciones de retorno para los GOSUB-RETURN y demás información necesaria para el intérprete basic. Si lanzamos la grabación durante la ejecución del programa y volvemos a cargarla a continuación, el intérprete continuará con la ejecución en la instrucción siguiente a la orden de SAVE. Veamos un ejemplo práctico con el siguiente programa:

9998 LET A = PEEK 23653 + 256 * PEEK 23654 : SAVE "programa" CODE 23552, A — 23500
9999 GO TO "principio del programa"

Si colocamos estas líneas al final de nuestro programa y hacemos GOTO 9998 grabaremos en el cassette un bloque de «bytes» con toda la información necesaria para que, una vez cargado, se ejecute automáticamente la línea 9999, que es la que lanzará nuestro programa. Y a ver quién es capaz de hacer un MERGE con un bloque de «bytes»!! Evidentemente es posible deshacer este truco, pero ya es harina de otro costal. Habría que cargar el bloque en la parte alta de memoria, protegido por RAMTOP, mediante un monitor de código máquina modificar «a mano» el listado del programa eliminando los trucos de protección que nos impidieran parar el programa así como las variables del sistema manipuladas, etc… En conjunto, un trabajo bastante pesado pero que, a veces, es necesario para pasar nuestros juegos favoritos al microdrive. Para los aficionados al código máquina, es más fácil copiar el bloque dé memoria tal cual en el microdrive y cargarlo en una dirección alta de memoria donde no interfiera con las variables del sistema y, posteriormente, emplear la instrucción de código máquina LDIR para restituir el bloque a su lugar original. Si nuestros lectores están interesados en el tema, les rogamos que nos lo hagan saber. Especialmente nos sería de gran utilidad saber cuántos disponen del microdrive para seguir profundizando en este terreno.

El segundo truco antiMERGE se basa en unos principios totalmente diferentes. Dado que esta instrucción está pensada originalmente para fusionar programas, es imprescindible que vaya tomando nota de los números de línea. El truco consiste en darle un número «imposible» con lo que la rutina se vuelve loca y se produce el consiguiente bloqueo. Naturalmente, hay que tener la precaución de restablecer las cosas a su estado normal antes de ejecutar el programa. Veamos un ejemplo:

1 POKE 23802, 0: POKE 23613, 0
2 GOTO 4
3 POKE 23801, 255: SAVE "programa" LINE 1: STOP
4 REM principio del programa

A la hora de proteger un programa contra MERGE incluiremos estas líneas al principio del mismo y lo grabaremos haciendo GOTO 3. El POKE de esta línea tiene por objeto transformar el número de la línea 2, cambiándolo a 65282, lo que para el Spectrum es imposible, y provocará el bloqueo si intentamos hacer MERGE. Por el contrario, si utilizamos el LOAD normal, la ejecución comenzará en la línea 1 donde el primer POKE devolverá a la línea 2 su número normal, y el segundo es uno de los de protección que ya hemos visto. Luego la ejecución se transferirá a la línea 4 donde comienza el resto del programa. Al utilizar esta rutinita hay que tener cuidado en no modificar la línea 1 ya que alteraríamos la dirección de la segunda línea con lo que el POKE debería de tener otra dirección. Por el contrario, si utilizamos microdrive hay que tener en cuenta que la zona de programa no empieza en el sitio habitual y habrá que modificar las direcciones en consecuencia. La misma advertencia es de tener en cuenta para los siguiente trucos.

Y siguiendo con nuestro panorama de trucos, vamos ahora con uno bastante inofensivo pero que siempre resulta divertido. El archifamoso de la línea 0. Muchos programadores que conocen este truco, lo emplean para crear una línea que no se puede editar y donde colocan su nombre para evitar que otra persona se apropie del programa. No nos parece mal, pero rogamos que no lo pongan en los programas que nos envían ya que luego llueven cartas de lectores justamente indignados quejándose de que no pueden introducir esta línea en su ordenador. Para ello, basta con introducir la línea con un número normal y, posteriormente, modificarlo cambiando los dos primeros bytes de la misma mediante POKEs. Toda la dificultad consiste en conocer la dirección donde tenemos que POKEAr, si se me permite el barbarismo. Supongamos, por ejemplo, que en la primera línea de nuestro programa hemos puesto nuestro nombre. Basta en este caso, con hacer POKE 23756,0 para transformarla en línea 0 que no se puede modificar mientras no hagamos otro POKE para deshacer el efecto. Si el número de esta línea fuese mayor que 255, entonces necesitamos añadir POKE 23755,0 ya que estos números se codifican en dos bytes. Este truco se suele emplear en combinación con los caracteres de control de color para dejar el fondo del mismo color que la tinta con lo que el listado se vuelve invisible hasta que no editemos la línea 0 y eliminemos los caracteres de control. Recordemos que en el número 2 de MICROHOBBY se explica cómo variar los colores de las líneas del programa.

Y vamos a terminar con un truco verdaderamente canallesco. Aquellos lectores que hayan tenido la paciencia de leer a fondo el manual del Spectrum (y hago aquí una pausa para afirmar que es uno de los mejores del mercado, otro día hablaremos de la traducción…) recordarán que los números se almacenan en memoria de dos formas. Primero viene la representación en ASCII del número, a continuación el código 14 que indica número y, por último, cinco bytes que lo representan en coma flotante. Lo interesante de este complicado asunto es que, para obtener el listado del programa, nuestro Spectrum emplea la representación el ASCII, mientras que para los cálculos emplea los cinco bytes mencionados. Esto significa que es posible cambiar los bytes que representan el número en ASCII dándoles unos valores irreales mientras que el programa va a seguir operando con los números reales, lo que nos permite confundir a todo aquel que intente reproducir nuestro programa. Y más interesante todavía, cuando editamos una línea «protegida» y la volvemos a introducir en memoria la representación en coma flotante cambia para ajustarse a la representación en ASCII lo que significa que el listado queda totalmente corrompido e inutilizable. Vamos con el ejemplo de turno:

Introduzcamos el siguiente y elemental programa:

1 PRINT 2 + 2

Y a continuación vamos a cambiar los números mediante POKE 23760,49 y POKE 23768,49. Si ahora hacemos LIST obtendremos el siguiente programa:

1 PRINT 1 + 1

ya que 49 es el código ASCII del número 1.

Pero si hacemos RUN observaremos con gran sorpresa que el resultado sigue siendo 4, y no 2 como sería de esperar. Y por último, editemos la línea mediante CAPS SHIFT y EDIT y sin modificarla volvamos a introducirla con ENTER. Si ahora pulsamos nuevamente RUN, veremos que el resultado es 2, lo que significa que ha perdido definitivamente la representación en coma flotante de los números originales al intentar editar la línea. Combinando este truco con el de los caracteres de control de color para volver invisible nuestro programa, habremos conseguido producir un buen dolor de cabeza a todo aquel que intente meterse dentro del mismo.

¡Qué ustedes se lo pasen bien!

  • 012/software.txt
  • Última modificación: d/m/Y H:i
  • por miguel