Código automodificable en PHP

Recuerdo haber utilizado código automodificable (self modifying code) desde ensamblador, y en menor medica con C/C++.

En cambio jamás he visto utilizar esta técnica con lenguajes que no son nativos de la máquina.

El código automodificable, consiste en alterar directamente el programa que está en ejecución en ese momento, desde el propio programa. Así por ejemplo, podríamos encriptar y desencriptar el código completo en tiempo de ejecución, o hacer que una función que antes incrementaba un contador, ahora lo decremente.

En cualquier caso, la utilidad del código automodificable, ha sido puntual, quedando marginada a técnicas antidepuración, o a optimizaciones de tamaño.

Desde la versión 4 de PHP, el script ya no se ejecuta linea a linea, sino que se lee enteramente el archivo, se interpreta, y se ejecuta de golpe. Evidentemente esto incrementa el rendimiento sustancialmente, al igual que ocurrió con las páginas ASP bajo Internet Information Services 5.

El caso es que esta forma de ejecutar el programa, impide completamente modificar el código en ejecución, pues no tenemos acceso directo a la memoria del script.

Lo que si podemos hacer, es modificar el propio archivo del programa, de manera que las siguientes ejecuciones corran otro código, o partan de otros datos.

El sencillo ejemplo que he desarrollado, muestra el típico contador de visualizaciones de página, pero almacenando su estado, no ya en archivos, ni en base de datos, sino en el propio código del script. Por supuesto que nada impediría además de modificar el valor de una variable, como es el caso, alterar el código propiamente dicho.

<?php
error_reporting(0);

//Variable que modificaremos en tiempo de ejecución
$sHits='0000000';

//Leer código completo del script
$iFile=fopen($_SERVER['SCRIPT_FILENAME'], 'r');
$sContent=fread($iFile, 65536);
fclose($iFile);

//Buscar posición de la variable sHits
$iPos=strpos($sContent, '$sHits=\'');
if ($iPos!==false)
{
//Obtener valor de sHits e incrementarlo en 1
$iHits=((int) substr($sContent, $iPos+8, 7))+1;
echo '<h2>P&aacute;gina vista <b>' . $iHits .
'</b> veces.</h2>';

//Guardar código completo del script
$sContent=substr_replace($sContent, sprintf('%07d',
$iHits), $iPos+8, 7);
$iFile=fopen($_SERVER['SCRIPT_FILENAME'], 'w');
fwrite($iFile, $sContent);
fclose($iFile);
}
//Mostrar código
echo '---- <b>' . $_SERVER['PHP_SELF'] . '</b> ------<br>';
highlight_file($_SERVER['SCRIPT_FILENAME']);
?>

No se me ocurren demasiadas aplicaciones "del mundo real" que justificasen el uso de código automodificable dentro de aplicativos en PHP: Guardar valores de configuración, Control de integridad, ofuscación de código, … y poco más.

El algoritmo es válido incluso aunque se estén usando aceleradores PHP como Zend Optimizer, o Turck-MMCache, ya que al detectar el optimizador que la página ha sido modificada, la volvería a cargar, optimizar y cachear.

En cambio no es compatible con los encriptadores de código como PHP Coder o Zend Encoder, ya que el proceso de encriptación se realiza una sola vez, y no es reversible.

Ver código fuente y funcionamiento.

Código automodificable en PHP

8 comentarios en “Código automodificable en PHP”

  1. Los motores de plantillas como Smarty són ejemplo de esto. Crean scripts PHP a partir de unos datos en texto plano.

  2. Javier Gutiérrez Chamorro (Guti)

    No he utilizado Smarty, aunque si otros generadores de plantillas. Es cierto que generan archivos PHP dinámicamente, pero no se modifican ellos mismos, de ahí lo de automodificable.

  3. Eso es porque estas pensando en ficheros. Todos conocemos como los virus en ensamblador se modificaban en memoria (ya que datos y codigo en ensamblador se guardan igual) para encriptarse y luego escribirse en el nuevo fichero y asi ocultarse.

    Sin embargo parto de la base de que el código esté por ejemplo en un campo de una tabla de mysql, se recupere y se interprete con el eval. Asi se podría modificar el código antes, durante o de pués de su ejecución.

  4. Javier Gutiérrez Chamorro (Guti)

    Es cierto, no se me había ocurrido esto de almacenar el código PHP en una BD.

    Suena interesante. Gracias por el apunte.

Deja un comentario