2008-11-06 11 views
17

En Linux (o Solaris) hay una manera mejor que el análisis a mano /proc/self/maps repetidamente para averiguar si puede o no leer, escribir o ejecutar lo que está almacenado en una o más direcciones en la memoria?¿Hay alguna manera mejor que analizar/proc/self/maps para descubrir la protección de memoria?

Por ejemplo, en Windows tiene VirtualQuery.

En Linux, puedo mprotect para cambiar esos valores, pero no puedo leerlos.

Además, ¿hay alguna manera de saber cuándo cambian esos permisos (por ejemplo, cuando alguien usa mmap en un archivo detrás de mi espalda) aparte de hacer algo terriblemente invasivo y usar ptrace en todos los hilos en el proceso e interceptar cualquier intento de hacer un syscall que podría afectar el mapa de memoria?

Actualización:

Por desgracia, estoy usando esto dentro de un JIT que tiene muy poca información sobre el código que se ejecuta para obtener una aproximación de lo que es constante. Sí, me doy cuenta de que podría tener un mapa constante de datos mutables, como la página vsyscall utilizada por Linux. I puede recurrir a la suposición de que todo lo que no está incluido en el análisis inicial es mutable y peligroso, pero no estoy del todo contento con esa opción.

En este momento lo que hago es leer /proc/self/maps y crear una estructura en la que pueda realizar búsquedas binarias para la protección de una dirección determinada. Cada vez que necesito saber algo sobre una página que no está en mi estructura, vuelvo a leer/proc/self/maps suponiendo que se haya agregado mientras tanto o de todos modos estaría a punto de fallar.

Parece que el análisis de texto para obtener esta información y no saber cuándo cambia es tremendamente difícil. (/dev/inotify no funciona en casi nada en /proc)

Respuesta

6

No conozco un equivalente de VirtualQuery en Linux. Sin embargo, algunas otras maneras de hacerlo, que puede o no puede trabajar son:

  • a configurar un manejador de señales atrapando SIGBUS/SIGSEGV y seguir adelante con su lectura o escritura. Si la memoria está protegida, se invocará el código de captura de señal. Si no es así, no se llama al código de interceptación de señal. De cualquier manera que ganes.

  • puede rastrear cada vez que llame al mprotect y crear una estructura de datos correspondiente que le ayude a saber si una región está protegida de lectura o escritura. Esto es bueno si tiene acceso a todo el código que usa mprotect.

  • puede controlar todas las llamadas mprotect en su proceso vinculando su código con una biblioteca que redefine la función mprotect. A continuación, puede crear la estructura de datos necesaria para saber si una región está protegida contra lectura o escritura y luego llamar al sistema mprotect para establecer realmente la protección.

  • puede intentar usar /dev/inotify y controlar el archivo /proc/self/maps para cualquier cambio. Supongo que este no funciona, pero debería valer la pena intentarlo.

+1

Por el momento Recibo un SIGSEGV es demasiado tarde. Necesito saber si algunos datos son constantes para saber que puedo "doblarlos" constantemente a través de ellos. Con los hacks apropiados para los datos no constantes mmap'ed constantes y la página vsyscall. –

Cuestiones relacionadas