Shareware GPL, ¿legal 100% o violación de la licencia?

Hechos:

Hace un par de semanas me encontré con este caso, necesitaba un programa para convertir un archivo PDF a formato Word y me encontré con una herramienta de la empresa VeryPDF que cumplía perfectamente con mis espectativas (PDF2Word).

En la página web reza que la aplicación tiene licencia GPL y me extrañó encontrarme con la típica ventana Nag de los programas shareware que te invita a registrarte.

pdf2word1

pdf2word2

Análisis:

Tras usar la aplicación para la tarea en cuestión, me dio por investigar un poco más antes de desinstalarla.

Si vemos la página web de la empresa la aplicación se vende por 39,95 US$ la licencia individual, no hay problema, GPL no tiene porqué significar gratuito, pero la verdad me resultaba algo chocante que el método de cobro se haga directamente desde el programa teniendo que entregar el código fuente del mismo.

Notice: PDF2Word (PDF To Word) is licensed under the GNU General Public License (GPL). Portions of this software are copyright 1996-2006 Glyph & Cog, LLC. You may obtain the source code for PDF2Word at here.

Efectivamente, el código fuente de la aplicación está disponible aquí.

// Description : PDF2HTML/BMP software
// Author : verypdf.com Inc
// Version : Ver1.2
// Platform : Windows95/98/Me/NT/2000/XP

// Environment : Visual C++ 6.0
// Date : 2002/04/03
// This program is shareware; you can redistribute and/or
// modify it under the terms of the GNU General Public License.
// See the GNU General Public License for more details.

Entiendo la postura de la empresa, por un lado se intenta vender un producto para obtener unas ganancias, pero a la vez por moda y para tener de su parte a la comunidad quieren publicarlo bajo licencia GPL; de esta forma se puede jugar a doble baraja.

He visto esta maniobra en otras empresas, pero generalmente ofrecen una versión GPL totalmente libre y mantenida por la comunidad, y una versión corporativa que en muchas ocasiones no tiene la misma funcionalidad de la versión GPL, pero sí tiene soporte de la empresa.

Este caso algo especial porque el código publicado es antiguo (versión 1.4) mientras que la aplicación descargable va por la 3.0.

Usando google, me he encontrado con la página web gpl-violations.org donde tienen diversos FAQs sobre cómo se debe acatar la licencia GPL, y en uno de ellos específico sobre la publicación del código fuente, se indica que, por cada versión binaria publicada, se debe publicar el código fuente correspondiente y mantenerlo disponible durante al menos 3 años.

Conclusión:

Para que este software sea legal y no viole la GPL la empresa tendría que proporcionar el código fuente de cada versión publicada o bien tener dos versiones, la GPL y la corporativa.

Está claro que la empresa no está dispuesta a publicar el código fuente de la aplicación más reciente, de hecho ya en esta versión 1.4 que está publicada se notan ciertos recortes en el código. Revisando por curiosidad la ventana de registro (Código completo aquí: MyReg.cpp), me encontré con lo siguiente:

Si vemos la función IsCorrect:

Jamás va a devolver verdadero, por tanto falta todo el código fuente de la comprobación del número de serie. En el resto del fichero se puede ver que hay comprobaciones con el número de serie del disco duro, algunos ficheros en rutas escondidas, pero nada concluyente.

Ejerciendo nuestros derechos:

Puesto que la aplicación es GPL, vamos a ejercer nuestro derecho a modificar el programa para que no nos pida registrarnos, después de todo es GPL y no nos gusta que limiten el uso de la aplicación. Por un lado empezaremos por modificar el código fuente antiguo y después veremos cómo modificar el binario de la última versión.

Versión 1.4:

Revisando el código, en toda la aplicación se usa una variable global para indicar si estamos registrados:

En la creación de la ventana principal del programa encontramos el siguiente código:

Es la inicialización de esta variable, se llama a la función CheckSerialNo() para asegurarse de que todo es correcto:

Por tanto, si devuelve 0, estamos registrados, así que con dejar esta función como:

Compilamos y listo.

Versión 3.0:

Un buen paso es analizar el ejecutable usando una herramienta como podría ser el PEiD, que nos indica que el programa se encuentra empaquetado con UPX. Podríamos descomprimirlo utilizando esta misma herramienta, pero el propio UPX genera un mejor resultado, deja el ejecutable igual que el original.

Si intentamos descomprimirlo usando el parámetro –d nos muestra un error porque han modificado la cabecera PE del ejecutable para evitar esto. Os muestro en esta imagen el antes y el después de haber reconstruido dicha cabecera, sólo cambian los nombres de las secciones y la marca de versión que deja el compresor:

Cabecera PE

Una vez descomprimido, aun siendo distinta versión una cosa común en el software es que los programadores reutilizan código. Es probable que de la versión 1.4 a la 3.0 hayan cambiado totalmente el algoritmo para la generación del número de serie, pero seguramente el código para mostrar la ventana de registro y la función para verificar si estamos registrados sean las mismas; sabiendo esto, buscamos el mismo código que antes, empezando por buscar la cadena de texto “Thank you registered”, aterrizamos en el código que gestiona el bucle de mensajes y un poco más abajo vemos la llamada a la ventana de registro, que devuelve el estado de la variable global IsRegistered:

Constante Global IsRegistered

Como podeis ver, esa dirección estática es la variable global. Si buscamos las referencias a esa constante y vamos comparando con el código fuente que tenemos, en una de las referencias, más abajo se hace una llamada a EnableMenuItem, que coindice con el código de creación de la ventana principal del programa:

Inicialización de la constante

Y por fin llegamos a la función CheckSerialNo donde hicimos la anterior modificación, si cambiamos el código de la misma forma (pero en ensamblador) tal y como pongo de comentario:

Función CheckSerialNo()

Habremos conseguido la misma funcionalidad con la última versión del programa.

Y como colofón para los curiosos, aquí si que existe el código de la función IsCorrect, como el listado de código es algo largo no lo muestro aquí, puede encontrarse en la dirección 00405620. Lo que sí muestro es la lógica que sigue y una reconstrucción de la misma en C:

Un comentario

  1. Pingback: meneame.net

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *