Ofuscación de código

  Uno de los aspectos más valorados en el código fuente de un proyecto software es su facilidad de comprensión. Si es factible entender cómo funciona el código, entonces es más sencillo corregir errores y añadir nuevas funcionalidades. Además, es más fácil que otras personas más allá del autor puedan participar y contribuir al proyecto. Todos estos son  aspectos clave en el desarrollo de proyectos de código abierto.  

  ¿Qué pasa si no queremos que se sepa cómo funciona un programa? Si el lenguaje de programación es compilado, aquí ya hay una primera barrera: el binario no es tan sencillo de entender como el código fuente, aunque no es una barrera insalvable.  Pero si es un lenguaje interpretado, el código fuente está a nuestra disposición. Entonces, ¿cómo lo hacemos para ocultar el comportamiento de nuestro código? Aquí es donde entran en acción las herramientas de ofuscación de código.

  Hay ocasiones en las que nos puede interesar ofuscar el código. Por ejemplo, cuando el código vaya a ser visible por el cliente, como suele ocurrir en lenguajes como JavaScript, y no deseas que nadie pueda desentrañar su funcionamiento o modificarlo, ya sea para conseguir seguridad por oscuridad o para evitar ser plagiado por competidores.

  La ofuscación se refiere a encubrir el significado de una comunicación haciéndola más confusa y complicada de interpretar. Precisamente, la ofuscación de código es el proceso que intenta modificar un programa para hacer más compleja su comprensión. Realizar una ofuscación perfecta es imposible, porque tarde o temprano hay que decirle al ordenador lo que tiene que hacer, pero pueden darse suficientes rodeos para confundir a quién esté analizando nuestro programa (ya sea un humano o una herramienta automática). Las técnicas que pueden usarse para ofuscar un programa son muy variadas:

  • Eliminar comentarios, espacios en blanco y saltos de línea (o a la inversa, introducirlos aleatoriamente para dificultar la lectura).
  • Modificar los nombres de variables y funciones para que no proporcionen información sobre su objetivo.
  • Complicar artificialmente el control de flujo del programa.
  • Alterar la distribución del código dentro del proyecto (partir funciones, trasladar código de un fichero a otro, copiarlo, etc.).
  • Utilizar macros para que el precompilador deba expandir parte del código del programa.
  • Convertir determinadas constantes del código en valores que deben calcularse durante la ejecución (p.ej. convertir un 5 en un bucle que suma 1 cinco veces).
  • Añadir código innecesario (p.ej. un condicional que sabemos que siempre evaluará a cierto, un parámetro de la función que sólo se usa en instrucciones innecesarias).
  • Hacer que parte de los datos del programa o el código fuente estén cifrados y deban descifrarse durante la ejecución.
  • Hacer que el código del programa se modifique a sí mismo antes de ejecutarse.

Motivos para usar ofuscación:

  • El primer motivo para usar ofuscación de código es motivos de seguridad: no queremos que un atacante comprenda el funcionamiento del código para que no lo altere con malos propósitos. Por ejemplo, si un programa contiene un control de licencias, nos puede interesar que nadie lo modifique para saltarse dicho control. O bien nos puede interesar que un cliente no envíe peticiones malintencionadas al servidor. Hay que tener en cuenta que esto sólo consigue seguridad por oscuridad: el sistema es seguro simplemente porque nadie sabe cómo funciona. Pero si alguien consigue entender su funcionamiento mediante el análisis, toda la seguridad se va al traste. Por tanto, usar ofuscación con este propósito sólo tiene sentido como medida adicional para poner las cosas más difíciles a un atacante, porque no es infalible en absoluto.
  • Un segundo motivo para usar ofuscación está muy relacionado con el primero (pero al revés): ocultar código malicioso (un virus, un troyano, un rootkit, una bomba lógica, una puerta trasera, …). Obviamente, los autores de este tipo de malware están interesados en impedir su detección y pueden usar estas técnicas para dificultar la tarea de antivirus o revisores humanos.
  • Otra razón para usar ofuscación es la protección de la propiedad intelectual. Quizás no quieres que tu competencia no sepa qué método usas para resolver tan rápido un cierto problema o que nadie copie una animación que has programado (o que si la usa, al menos no sea sencillo quitarle tu nombre y la licencia que le hayas asignado).
  • Existen determinados procesos que producen ofuscación como efecto colateral. Un ejemplo es la minificación: la transformación del código fuente de un programa con el propósito de reducir el número de bytes que ocupa. En lenguajes interpretados como JavaScript esto reduce el espacio de almacenamiento y el tiempo necesario para descargar un script por Internet. También hay quien dice que la optimización de código de un compilador consigue, en cierto modo, un cierto nivel de ofuscación al modificar el programa para mejorar su rendimiento.
  • Un último motivo para utilizar la ofuscación de código es, simplemente, pura diversión. Entender cómo funciona un programa ofuscado es como un rompecabezas, y un programa difícil de entender puede llegar a ser un gran desafío.

Como acabamos de ver, mediante la ofuscación protegemos la utilidad del código pero, comúnmente, aplicarlo va contra las buenas prácticas de la programación. De todas formas, aunque ya esté compilado, este sigue estando descubierto ante miradas externas ya que existen herramientas de descompilación del código y otras técnicas para conseguir un código que acabe haciendo lo mismo. Igualmente, esta técnica es una forma de proteger un código al menos de programadores más inexpertos.

Nos alegra que te hayas sumado a esta lectura. Te invitamos a compartir este material en las redes y dejarnos tus comentarios ¡para que podamos seguir creando más contenido para vos!