elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Guía rápida para descarga de herramientas gratuitas de seguridad y desinfección


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Código de una máquina virtual simple
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Código de una máquina virtual simple  (Leído 2,831 veces)
Miky Gonzalez

Desconectado Desconectado

Mensajes: 87

http://mikygonzalez.comule.com/blog/


Ver Perfil WWW
Código de una máquina virtual simple
« en: 6 Marzo 2013, 21:55 pm »

Estoy haciendo un manual de la creación de una máquina virtual, no creo que tenga que decir que en C... por algo estamos en el foro: "Programación C/C++"  ::). A continuación pongo el código fuente totalmente creado por mí basandomes en diversa información:
Código
  1. /*
  2.  * Miky Gonzalez Virtual Machine - Segunda revisión
  3.  * Compilar con: gcc -o vm vm.c -O2
  4.  * Para más información y futuras versiones visita:
  5.  * http://mikygonzalez.16mb.com/
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10.  
  11. #define MAXIMOS_NODOS 100
  12.  
  13. typedef struct _nodo {
  14. int reg_pila;
  15. struct _nodo *siguiente_nodo;
  16. } nodo;
  17.  
  18. typedef nodo *__nodo;
  19. typedef nodo *__pila;
  20.  
  21. typedef struct _cpu {
  22. int reg[16];
  23. unsigned short int reg_temp[5];
  24. unsigned short int estado;
  25. unsigned int instruction_pointer;
  26. __pila pila_cpu;
  27. } cpu;
  28.  
  29. /*! FUNCIONES DE LA PILA */
  30. void push(__pila *pila, int num) {
  31. __nodo nodo_push;
  32.  
  33. nodo_push = (__nodo) malloc(sizeof(nodo));
  34. if(nodo_push != NULL) {
  35.     nodo_push->reg_pila = num;
  36.     nodo_push->siguiente_nodo = *pila;
  37.     *pila = nodo_push;
  38.    }
  39. }
  40.  
  41. int pop(__pila *pila) {
  42. __nodo nodo_pop;
  43. int valor_nodo_pop = 0;
  44.  
  45. nodo_pop = *pila;
  46. valor_nodo_pop = (*pila)->reg_pila;
  47. *pila = (*pila)->siguiente_nodo;
  48. free(nodo_pop);
  49.  
  50. return valor_nodo_pop;
  51. }
  52.  
  53. unsigned int contar_nodos(__nodo nodo_pila) {
  54. unsigned int valor_temporal = 0;
  55.  
  56. if(nodo_pila == NULL)
  57. return valor_temporal;
  58. while(nodo_pila != NULL) {
  59. nodo_pila = nodo_pila->siguiente_nodo;
  60. valor_temporal++;
  61. }
  62.  
  63. return valor_temporal;
  64. }
  65.  
  66. /*! FUNCIONES DEL CPU */
  67. void iniciar_datos(cpu* CPU) {
  68. unsigned short int bucle_i;
  69.  
  70. for(bucle_i = 0; bucle_i < 16; bucle_i++)
  71. CPU->reg[bucle_i] = 0;
  72.  
  73. CPU->estado = 1;
  74. CPU->instruction_pointer = 0;
  75. CPU->pila_cpu = NULL;
  76. }
  77.  
  78. void mostrar_datos(cpu* CPU) {
  79. unsigned short int bucle_i;
  80.  
  81. for(bucle_i = 0; bucle_i < 16; bucle_i++)
  82. printf("REG %d == %d\n", bucle_i, CPU->reg[bucle_i]);
  83.  
  84. printf("CPU ejecutandose: %s", CPU->estado ? "Si\n" : "No\n");
  85. printf("Instruction Pointer: %d\n", CPU->instruction_pointer);
  86. }
  87.  
  88. void preparar_cpu(cpu* CPU, unsigned short int instruccion) {
  89. CPU->reg_temp[0] = (instruccion & 0xF000) >> 12;
  90. CPU->reg_temp[1] = (instruccion & 0xF00) >> 8;
  91. CPU->reg_temp[2] = (instruccion & 0xF0) >> 4;
  92. CPU->reg_temp[3] = (instruccion & 0xF);
  93. CPU->reg_temp[4] = (instruccion & 0xFF);
  94. }
  95.  
  96. void ejecutar_cpu(unsigned int programa[], cpu* CPU) {
  97. int valor_temporal = 0;
  98.  
  99. while(CPU->estado) {
  100. preparar_cpu(CPU, programa[CPU->instruction_pointer]);
  101. switch(CPU->reg_temp[0]) {
  102. case 0: /*! halt */
  103. CPU->estado = 0;
  104. break;
  105. case 1: /*! setr */
  106. // Comprobar si los datos estan dentro de los registros accesibles
  107. if(0x0 > CPU->reg_temp[1] > 0xF) {
  108. printf("Error: setr espera un registro valido\n");
  109. CPU->estado = 0;
  110. break;
  111. }
  112. CPU->reg[CPU->reg_temp[1]] = CPU->reg_temp[4];
  113. break;
  114. case 2: /*! push */
  115. // Comprobar si los datos estan dentro de los registros accesibles
  116. if(0x0 > CPU->reg_temp[1] > 0xF) {
  117. printf("Error: push espera un registro valido\n");
  118. CPU->estado = 0;
  119. break;
  120. }
  121. // Comprobar elementos maximos de la pila
  122. if(contar_nodos(CPU->pila_cpu) == MAXIMOS_NODOS) {
  123. printf("Error: desbordamiento de pila. MAX: %d\n", MAXIMOS_NODOS);
  124. CPU->estado = 0;
  125. break;
  126. }
  127. push(&CPU->pila_cpu, CPU->reg[CPU->reg_temp[1]]);
  128. break;
  129. case 3: /*! pop */
  130. // Comprobar existe almenos un elemento en pila_cpu
  131. if(CPU->pila_cpu == NULL) {
  132. printf("Error: pop espera un elemento en pila\n");
  133. CPU->estado = 0;
  134. break;
  135. }
  136. pop(&CPU->pila_cpu);
  137. break;
  138. case 4: /*! move */
  139. // Comprobar existe almenos un elemento en pila_cpu
  140. if(CPU->pila_cpu == NULL) {
  141. printf("Error: move espera un elemento en pila\n");
  142. CPU->estado = 0;
  143. break;
  144. }
  145. // Comprobar si los datos estan dentro de los registros accesibles
  146. if(0x0 > CPU->reg_temp[1] > 0xF) {
  147. printf("Error: move espera un registro valido\n");
  148. CPU->estado = 0;
  149. break;
  150. }
  151. valor_temporal = CPU->reg[CPU->reg_temp[1]];
  152. CPU->reg[CPU->reg_temp[1]] = CPU->pila_cpu->reg_pila;
  153. CPU->pila_cpu->reg_pila = valor_temporal;
  154. break;
  155. default:
  156. printf("Instruccion %d no implementada...\n", CPU->reg_temp[0]);
  157. break;
  158. }
  159. valor_temporal = 0;
  160. CPU->instruction_pointer++;
  161. }
  162. }
  163.  
  164. /*! INICIO DE MG-VM */
  165. int main(int argc, char *argv[]) {
  166. cpu CPU;
  167. unsigned int programa[] = {
  168. 0x1010, // setr 0 10
  169. 0x2000, // push 0
  170. 0x4100, // move 1
  171. 0x2100, // push 1
  172. 0x3000, // pop
  173. 0x3000, // pop
  174. 0x0000  // halt
  175. };
  176.  
  177. iniciar_datos(&CPU);
  178. mostrar_datos(&CPU);
  179.  
  180. ejecutar_cpu(programa, &CPU);
  181. mostrar_datos(&CPU);
  182.  
  183. return 0;
  184. }

Si encuentran una manera mejor de hacer las cosas, o más optimizada, porfavor, puedes comentar que propones. Cualquier sugerencia o queja son bienvenidas.
La máquina virtual sólo cuenta con funciones de manejo de la pila y registros. No tiene funciones artiméticas, en la próxima versión entrarán las demás funciones aritméticas. En total tengo un máximo de 16 funciones.

Un saludo, espero que les agrade el código. Intenté escribirlo para que pudiera entenderlo bien, aún siendo principiante en programación.

Para obtener más información del tutorial ó próximas revisiones del código: http://mikygonzalez.16mb.com/


En línea

Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:


EN CONSTRUCCIÓN
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: Código de una máquina virtual simple
« Respuesta #1 en: 7 Marzo 2013, 00:16 am »

Interesante.

He intentado hacer una implementación en C++. Lo dejo por aquí, me falta testearlo:
https://dl.dropbox.com/u/69551225/Maquina%20Virtual.rar

Para usarlo, teneis que añadir el archivo "CPU.hpp" y crear un objeto CPU. Despues llamais al metodo ejecutar.



En línea

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

Desconectado Desconectado

Mensajes: 87

http://mikygonzalez.comule.com/blog/


Ver Perfil WWW
Re: Código de una máquina virtual simple
« Respuesta #2 en: 7 Marzo 2013, 15:23 pm »

amchacon: Vi la implementación en C++, cuando tenga tiempo de probarla, siempre y cuando tenga permiso para ello, la pondré en el artículo que escribí en mi web como código alternativo. Saludos.
En línea

Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:


EN CONSTRUCCIÓN
Khronos14


Desconectado Desconectado

Mensajes: 443


A lie is a lie


Ver Perfil WWW
Re: Código de una máquina virtual simple
« Respuesta #3 en: 7 Marzo 2013, 15:36 pm »

Yo estoy haciendo una máquina virtual que emula el juego de instrucciones del procesador MIPS y un ensamblador. La máquina virtual y el ensamblador están en C, todavía me faltan instrucciones por implementar pero ya es algo funcional.

Puedes encontrar todo el código fuente aquí:

https://github.com/tanisperez/MIPS-Virtual-Machine

Lo estoy haciendo para el Concurso Universitario de Software Libre, puedes seguir todos mis progresos en el blog:

http://mipsvirtualmachine.wordpress.com/

Saludos.
En línea

amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: Código de una máquina virtual simple
« Respuesta #4 en: 7 Marzo 2013, 16:36 pm »

amchacon: Vi la implementación en C++, cuando tenga tiempo de probarla, siempre y cuando tenga permiso para ello, la pondré en el artículo que escribí en mi web como código alternativo. Saludos.
Sin problemas, lo acabo de revisar y he corregido bastantes bugs. También he añadido una documentación con Doxygen (aunque no hacía falta porque es bastante simple: Construir el objeto CPU, llamar a su método para ejecutar un programa y capturar las excepciones):
https://dl.dropbox.com/u/69551225/Maquina%20Virtual.rar

PD: Mirare lo de MIPS y te cuento ;)
En línea

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

Desconectado Desconectado

Mensajes: 87

http://mikygonzalez.comule.com/blog/


Ver Perfil WWW
Re: Código de una máquina virtual simple
« Respuesta #5 en: 7 Marzo 2013, 18:46 pm »

Khronos14:
Muy interesante el emulador de MIPS. Pretendo hacer un pequeño tutorial sobre como crear una máquina virtual, está más bien orientado a la seguridad informática en programas (rutinas de cifrado, generador de seriales...).

amchacon:
Puedes visitar mikygonzalez.16mb.com. Espero que en un momento publiqué el código fuente alternativo en C++ y la documentación del código para verse disponible online.

Saludos!
En línea

Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:


EN CONSTRUCCIÓN
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: Código de una máquina virtual simple
« Respuesta #6 en: 7 Marzo 2013, 19:57 pm »

Se me olvidó un detalle importante... Los destructores, menudas fugas de memoria xDD

Actualizado:
https://dl.dropbox.com/u/69551225/Maquina%20Virtual.zip
En línea

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

Desconectado Desconectado

Mensajes: 87

http://mikygonzalez.comule.com/blog/


Ver Perfil WWW
Re: Código de una máquina virtual simple
« Respuesta #7 en: 7 Marzo 2013, 20:08 pm »

amchacon: Very Good!!  ;D que cierto es!
En línea

Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:


EN CONSTRUCCIÓN
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
pregunta sobre Maquina virtual-virtual pc
Software
T0rete 4 2,903 Último mensaje 5 Octubre 2011, 16:10 pm
por zosemu
¿Cuál es la diferencia entre código objeto, código máquina y código binario?
Programación General
Aikanáro Anário 9 28,974 Último mensaje 23 Diciembre 2010, 15:19 pm
por pucheto
traducir ensamblador a codigo maquina
ASM
m@o_614 2 4,786 Último mensaje 27 Septiembre 2013, 21:32 pm
por xv0
[Código fuente][C] Máquina virtual
Programación C/C++
Miky Gonzalez 8 3,384 Último mensaje 2 Octubre 2013, 14:01 pm
por Miky Gonzalez
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines