[C][APORTE] Máquina Virtual -- Orientada a cálculos

Iniciado por Miky Gonzalez, 19 Marzo 2013, 21:39 PM

0 Miembros y 1 Visitante están viendo este tema.

Miky Gonzalez

Hace aproximadamente un par de semánas (estamos hablando de principio de marzo) publiqué el código fuente de una máquina virtual con un par de funciones.
Actualicé la máquina y tiene un juego de instrucciones como sigue:

halt    Detener la máquina virtual
setr    Establecer un valor inmediato en un registro
push    Almacena en la pila el valor de un registro
pop    Elimina el TOS (primer elemento de pila)
move    Intercambia los valores entre el TOS y un registro
sum    Suma el valor de un registro y otro, el valor se almacena en el primer registro
div    Divide el valor de un registro y otro, el valor se almacena en el primer registro
mod    Divide el valor de un registro y otro, el valor del resto de división se almacena en el primer registro
mult    Multiplica el valor de un registro y otro, el valor se almacena en el primer registro
not    Niega un elemento
xor    Operación OR condicional con dos registros. El valor se almacena en el primer registro
shl    Mueve los bits de un registro hacia la izquierda un numero de veces como marque el segundo registro.
shr    Mueve los bits de un registro hacia la derecha un numero de veces como marque el segundo registro.
ife    Si los dos registros especificados son iguales, ejecuta la siguiente accion. En caso contrario la salta.
goto    Establece el 'ip' al valor inmediato dado.

El código fuente puede obtenerse de aquí

Unos ejemplos tambien pueden obtener desde aquí (con los opcodes correspondientes)

Un saludo, espero que les sirve de alguna utilidad. Un ejemplo de su uso podría ser por ejemplo para utilizar en algoritmo de cifrado, es mucho más difícil saber de donde sale un dato si este se está ejecutando virtualmente.

Puede obtener más información en: artículo
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN

85

gracias por tu trabajo , se nota que hubo dedicación. En algún momento se que voy a leer las notas al respecto en tu blog. Sobre la utilidad, vistes esos programas como son Armadillo o más conocido es el Winlicense, que utiliza una vm y tiene opciones como virtualizar instrucciones en el entrypoint y otras opciones más, eso me parece más interesante , como se puede orientar a la seguridad de una aplicación. Seguridad contra lo que llama ingeniería inversa, a eso me refiero
Me cerraron el Windows Live Spaces, entonces me creé un WordPress XD
http://etkboyscout.wordpress.com/

amchacon

En la división, se te ha olvido comprobar si el divisor es cero. Otro detalle:

Código (cpp) [Seleccionar]
reg[CPU->reg_temp[4]] > sizeof programa
programa es un puntero unsigned int, por tanto sizeof siempre devolverá 4 bytes.

Si quieres comprobar que no se salga del array, tienes que hacer que el usuario introduzca su tamaño por adelantado. O bien colocar algun byte distintivo al final (cuidado con esto, si el usuario se le olvida colocarlo puede dar lugar a desbordamientos de pila).

Además si no colocas halt el proceso puede llegar a ser un bucle infinito.

Aquí dejo la implementación en C++:
https://dl.dropbox.com/u/69551225/Maquina_Virtual%20%2820130320%29.rar



Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

Miky Gonzalez

Solucionado el problema de la división; simplemente añadir en el código de la instrucción:

if(CPU->reg[CPU->reg_temp[2]] == 0) {
printf("Error: División por 0.\n");
CPU->estado = 0;
break;
}


Estoy pensando como solucionar el problema que calcular elementos del array. Yo probé con:

unsigned int array[] = {0x00, 0x01, 0x02, 0x03, 0x04};
num_elementos = sizeof(array) / 4;

pero no devuelve el tamaño total del array, siempre devuelve 4. Según la especificación de C si llamo a sizeof(xxxx) me devuelve el tamaño de la variable, pero no lo hace.

En cuanto a no colocar halt en el programa como fin de la ejecución por ello el código halt tiene como código OP: 0x00. Se supone que si se ejecuta una sección fuera del tamaño de variable finalizará.

La nueva versión está subida con la correción de la división por cero y la comprobación de errores en la instrucción goto eliminada, cuidado entonces. Intentaré hacer de una forma sencilla la cantidad de elementos de un array sin intervención del usuario.

Gracias por comentar y por buscar fallos. Saludos!
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN

amchacon

Cita de: Miky Gonzalez en 20 Marzo 2013, 15:23 PMEstoy pensando como solucionar el problema que calcular elementos del array. Yo probé con:

unsigned int array[] = {0x00, 0x01, 0x02, 0x03, 0x04};
num_elementos = sizeof(array) / 4;

pero no devuelve el tamaño total del array, siempre devuelve 4. Según la especificación de C si llamo a sizeof(xxxx) me devuelve el tamaño de la variable, pero no lo hace.
No se pueden pasar array a funciones, lo que haces es crear un puntero al primer elemento del vector. De modo que esta declaración:

Código (cpp) [Seleccionar]
void Ejecutar_Programa(unsigned int array[])

Es una convección sintáctica, lo que en realidad quiere decir:

Código (cpp) [Seleccionar]
void Ejecutar_Programa(unsigned int* array)

Y el tamaño de un puntero unsigned int* es efectivamente de 4 bytes.

CitarEn cuanto a no colocar halt en el programa como fin de la ejecución por ello el código halt tiene como código OP: 0x00. Se supone que si se ejecuta una sección fuera del tamaño de variable finalizará.
Eso ocurriría si todos los elementos estuviesen inicializados a cero, pero no hay garantía.

En la implementación en C++ he resuelto esto pidiendole al usuario que te de cuantas instrucciones tiene su programa. Además así puedo implementar el goto sin problemas.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

Miky Gonzalez

Solucionaré los problemas, en cuanto a pedir el número de elementos en la matriz se solucionan los problemas, pero me gustaría hacer todo más automático. He estado pensando en leer el programa desde un archivo y reservar para programa[] tantos elementos como líneas tenga el archivo (por ejemplo).

Espero que no te importe que ponga la implementación en C++ en mi página.
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN

0xDani

Esta bastante interesante esta maquina virtual  ;) Y un detalle de estilo:

#define IS_CORRECT_PILA() /* ... */

El nombre de esa macro queda horroroso, mezclar los dos idiomas asi xD

De todas formas es un gran aporte  ;-)

PD: Pila en ingles: stack
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

Miky Gonzalez

Soy consciente que pila es stack en ingles  ;D bueno, es una gran ignorancia, pero sinceramente, soy algo obsesivo con la palabra stack del inglés xD. Aunque si duelen muchos los ojos no me molestaría cambiar por stack :P
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN