Noticias Weblogs Foros Wiki Código
Sponsors:

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

PlanetaCódigo en inglés

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin

El arte de programar

Ejecutar una variable

Julio 28th, 2005 - [Enlace local]

Tal como se lee puede parecer algo un tanto extraño. Todo el mundo que programa usa las variables para leer o introducir datos en ellas (aunque a veces lo que se esta haciendo por debajo es realmente llamar a una función). El caso es que el C, y por extensión el C++ (ignoro si el C# tiene esta caracteristica) puede crear punteros a funciones. Estos punteros, como el resto, son una variable que contiene una dirección de memoria; sin embargo, su uso normal es asignarle el nombre de una función en vez de una variable, tal que así:

typedef unsigned int (*funcion)(const char *);
funcion pepe;
pepe=strlen;
printf("Longitud de hola:%d\n",pepe("hola"));


Pero que pasaría si en vez de asignarle una función le asignamos una variable? Pues
que el contenido de esa variable lo ejecutaría. Por supuesto, la variable no puede tener cualquier contenido; los bytes que contendría deberían ser codigo maquina. Por ejemplo el siguiente código en ensamblador:

MOV EAX,9
RET


traducido a codigo máquina del intel x86 sería:

B8 09 00 00 00
C3


Por lo que si ejecutamos las siguientes lineas:

typedef unsigned int (*funcion)(void);
funcion pepe;
unsigned char juan[]={0xb8,9,0,0,0,0xc3};
pepe=(unsigned int (*)(void))(void*)juan;
printf("Es un 9?:%d\n",pepe());


Lo que hemos hecho es llamar a una dirección de memoria que contenia una ristra de bytes, los cuales son significativos para el microprocesador. En el ejemplo hemos asignado al registro EAX (registro que almacena siempre lo que devuelve una función) el número 9 y a continuación ejecutamos un RET para retornar de la llamada de la función. Así hemos simulado una llamada a una función tal y como lo habría hecho el compilador, pudiendo incluso modificar el código (el contenido de la variable) en tiempo de ejecución sin problemas de violaciones de memoria o similares. Este código funciona tanto en Linux como en Windows siempre que sea un micro intel x86, aunque se puede usar en un motorola, power pc, o lo que querais siempre que conozcais el
lenguaje maquina del micro.

Este artículo dará pie a otro mucho más avanzado sobre como lograr que un programa original pueda acceder a un web service sin que otros se aprovechen de esa información (si usar contraseñas ni nada parecido).

» Leer más, comentarios, etc...