Para mi tesis de licenciatura, quiero visualizar la remanencia de datos de la memoria y cómo persiste después de reiniciar un sistema.Cómo obtener una dirección de memoria específica usando C
Tuve la idea simple de mapear una imagen en la memoria, apagar mi computadora, esperar x segundos, iniciar la computadora y ver si la imagen aún está allí.
int mmap_lena(void) { FILE *fd = NULL; size_t lena_size; void *addr = NULL; fd = fopen("lena.png", "r"); fseek(fd, 0, SEEK_END); lena_size = ftell(fd); addr = mmap((void *) 0x12345678, (size_t) lena_size, (int) PROT_READ, (int) MAP_SHARED, (int) fileno(fd), (off_t) 0); fprintf(stdout, "Addr = %p\n", addr); munmap((void *) addr, (size_t) lena_size); fclose(fd); fclose(fd_log); return EXIT_SUCCESS; }
Omití valores de retorno de comprobación para mayor claridad.
Así que después de la mmap intenté de alguna manera obtener la dirección, pero generalmente termino con una falla de segmentación en cuanto a mi comprensión de que la memoria está protegida por mi sistema operativo.
int fetch_lena(void) { FILE *fd = NULL; FILE *fd_out = NULL; size_t lenna_size; FILE *addr = (FILE *) 0x12346000; fd = fopen("lena.png", "r"); fd_out = fopen("lena_out.png", "rw"); fseek(fd, 0, SEEK_END); lenna_size = ftell(fd); // Segfault fwrite((FILE *) addr, (size_t) 1, (size_t) lenna_size, (FILE *) fd_out); fclose(fd); fclose(fd_out); return 0; }
También observe por favor que yo no modificable las direcciones en este ejemplo, por lo que cada vez que se ejecuta mmap_lena el valor que utilizo en fetch_lena podría estar equivocado como el sistema operativo toma el primer parámetro a mmap sólo como una pista (en mi sistema siempre tiene un valor predeterminado de 0x12346000 de alguna manera).
Si hay algún error de codificación trivial lo siento porque mis habilidades C no se han desarrollado completamente.
Me gustaría ahora si hay alguna forma de obtener los datos que deseo sin implementar ningún gancho malloc o hacks de asignador de memoria.
Gracias de antemano, David
En primer lugar, un proceso estándar de Linux no tiene acceso a la memoria bruta (física) para acceder fácilmente a una dirección dada de la memoria física de su proceso (consulte MMU, memoria virtual). Además, el kernel de Linux pone a cero la memoria (como en memset 0) antes de darle un proceso. – ysdx