La página de manual de Linuxproc(5) me dice que /proc/$pid/mem"se puede usar para acceder a las páginas de la memoria de un proceso". Pero un intento directo de usarlo solo me da
$ cat /proc/$$/mem /proc/self/mem
cat: /proc/3065/mem: No such process
cat: /proc/self/mem: Input/output error
¿Por qué no catpuede imprimir su propia memoria ( /proc/self/mem)? ¿Y cuál es este extraño error de "no hay tal proceso" cuando intento imprimir la memoria del shell ( /proc/$$/mem, obviamente, el proceso existe)? ¿Cómo puedo leer /proc/$pid/mem, entonces?

Respuestas:
/proc/$pid/maps/proc/$pid/memmuestra el contenido de la memoria de $ pid mapeado de la misma manera que en el proceso, es decir, el byte en el desplazamiento x en el pseudoarchivo es el mismo que el byte en la dirección x en el proceso. Si una dirección no está asignada en el proceso, la lectura del desplazamiento correspondiente en el archivo devuelveEIO(error de entrada / salida). Por ejemplo, dado que la primera página de un proceso nunca se asigna (por lo que la eliminación de la referencia a unNULLpuntero falla de manera limpia en lugar de acceder involuntariamente a la memoria real), leer el primer byte/proc/$pid/memsiempre produce un error de E / S.La manera de averiguar qué partes de la memoria de proceso están mapeadas es leer
/proc/$pid/maps. Este archivo contiene una línea por región asignada, con este aspecto:Los dos primeros números son los límites de la región (direcciones del primer byte y el byte después del último, en hexa). La siguiente columna contiene los permisos, luego hay información sobre el archivo (desplazamiento, dispositivo, inodo y nombre) si se trata de una asignación de archivo. Consulte la
proc(5)página de manual o Understanding Linux / proc / id / maps para obtener más información.Aquí hay un script de prueba de concepto que volca el contenido de su propia memoria.
/proc/$pid/memSi intentas leer el
mempseudoarchivo de otro proceso, no funciona: obtienes unESRCHerror (No hay tal proceso).Los permisos en
/proc/$pid/mem(r--------) son más liberales de lo que debería ser el caso. Por ejemplo, no debería poder leer la memoria de un proceso setuid. Además, tratar de leer la memoria de un proceso mientras el proceso lo modifica podría darle al lector una visión inconsistente de la memoria, y lo que es peor, había condiciones de carrera que podían rastrear versiones anteriores del kernel de Linux (de acuerdo con este hilo lkml , aunque yo No sé los detalles). Por lo tanto, se necesitan verificaciones adicionales:/proc/$pid/memdebe adjuntarse al proceso usandoptracecon laPTRACE_ATTACHbandera. Esto es lo que hacen los depuradores cuando comienzan a depurar un proceso; también es lo questracehace a las llamadas al sistema de un proceso. Una vez que el lector haya terminado de leer/proc/$pid/mem, debe separarse llamandoptracecon laPTRACE_DETACHbandera.ptrace(PTRACE_ATTACH, …)detendrá el proceso de destino (envía unaSTOPseñal), pero hay una condición de carrera (la entrega de la señal es asíncrona), por lo que el rastreador debe llamarwait(como se documenta enptrace(2)).Un proceso que se ejecuta como root puede leer la memoria de cualquier proceso, sin necesidad de llamar
ptrace, pero el proceso observado debe detenerse o la lectura aún regresaráESRCH.En la fuente del kernel de Linux, el código que proporciona entradas por proceso
/procestá enfs/proc/base.c, y la función para leer/proc/$pid/memesmem_read. La verificación adicional es realizada porcheck_mem_permission.Aquí hay un código C de muestra para adjuntar a un proceso y leer un fragmento de su
memarchivo (se omite la comprobación de errores):Ya publiqué un script de prueba de concepto para descargar
/proc/$pid/memen otro hilo .fuente
/proc/$pid/memdirectamente (ya sea concato conddcualquier otra cosa) no funciona. Lee mi respuesta./proc/self/mem. Un proceso puede leer su propio espacio de memoria bien, está leyendo el espacio de memoria de otro proceso que requierePTRACE_ATTACH.process_vm_readv()llamada al sistema (Linux 3.2).ESRCHerror en este escenario.Este comando (de gdb) volca la memoria de manera confiable:
Los volcados pueden ser grandes, úselos
-o outfilesi su directorio actual no tiene suficiente espacio.fuente
Cuando ejecuta
cat /proc/$$/memla variable$$es evaluada por bash que inserta su propio pid. Luego ejecuta locatque tiene un pid diferente. Terminascattratando de leer la memoria debashsu proceso padre. Dado que los procesos no privilegiados solo pueden leer su propio espacio de memoria, el núcleo lo niega.Aquí hay un ejemplo:
Tenga en cuenta que se
$$evalúa a 17823. Veamos qué proceso es ese.Es mi caparazón actual.
Aquí nuevamente se
$$evalúa a 17823, que es mi caparazón.catNo puedo leer el espacio de memoria de mi shell.fuente
$pidsea. Como explico en mi respuesta, leer la memoria de un proceso diferente requiere que lo trates.$$cuando escribes (y lees)$pid?$$y poniendo$pidal final. Lo transpuse en mi cabeza sin darme cuenta. Toda mi respuesta debería referirse$$, no$pid.Aquí hay un pequeño programa que escribí en C:
Uso:
El programa usa / proc / $ pid / maps para encontrar todas las regiones de memoria mapeadas del proceso, y luego lee esas regiones de / proc / $ pid / mem, una página a la vez. esas páginas se escriben en stdout o la dirección IP y el puerto TCP que especificó.
Código (probado en Android, requiere permisos de superusuario):
fuente
write to stdoutinmediatamente arribafwrite(..., stdout). Ver programmers.stackexchange.com/questions/119600/…