Estoy tratando de leer la pila de un proceso secundario pero sin suerte. Sé que es posible usarlo ptrace
, pero ptrace
la interfaz le permite leer solo una palabra a la vez, y estoy tratando de escanear porciones más grandes de la pila.
También intenté leer los /proc/$pid/mem
límites de la pila extraídos del /proc/$pid/maps
archivo después de usar ptrace para adjuntarlo (como se sugiere aquí ), pero la lectura sigue fallando (incluso cuando se ejecuta como root) aunque el mismo código tiene éxito cuando se intenta lectura de diferentes partes del proceso (por ejemplo, montón).
¿Qué estoy haciendo mal? ¿Hay alguna otra opción?
waitpid
entreptrace(PTRACE_ATTACH,…)
yread
(de lo contrario, hay una posible condición de carrera)? ¿Qué errorread
devuelve? ¿El niño está haciendo algo peculiar con su mapeo de memoria? ¿Puede probar su código con un niño simple comosleep
?Respuestas:
Bueno, solo usa un bucle, entonces. Sinceramente, no veo cómo eso constituye un problema
ptrace
, lo uso todo el tiempo para acceder de forma remota a los procesos.Yo uso algo como esto:
fuente
Aquí hay otra estrategia que podría necesitar ajustes, pero debería ser más eficiente con grandes cantidades de datos. La idea es ejecutar syscalls en el proceso remoto para recuperar el contenido de la pila. Necesitará un código de arquitectura específico, pero si solo apunta a x86 / x86_64, no debería ser demasiado complicado.
"/tmp/fifo"
en su proceso de llamada.PTRACE_SYSCALL
paso,waitpid()
para esperar yPTRACE_GETREGS
/PTRACE_PEEKTEXT
o verificar el código de operación actualmente ejecutado.open("/tmp/fifo")
,write()
el contenido de la pila,close()
el descriptor.Puede haber alternativas más elegantes a la tubería con nombre, pero no puedo pensar en ninguna en este momento. La razón por la que solo uso syscalls es porque la inyección remota de código es poco confiable en los sistemas modernos debido a varias protecciones de seguridad. El inconveniente es que se bloqueará hasta que el proceso remoto realice una llamada al sistema (que puede ser un problema para algunos programas que en su mayoría realizan cálculos).
Puede ver un código gratuito que implementa la mayor parte del trabajo en este archivo fuente . Comentarios sobre el código son bienvenidos!
fuente
Otra sugerencia
Cuando / si se acepta en el árbol principal del kernel de Linux, podrá usar el parche Cross Memory Attach de Christopher Yeoh . Consulte la documentación de process_vm_readv, por ejemplo.
fuente
Puede leer fácilmente la pila de otro proceso utilizando el sistema de archivos proc (necesitará acceso de root para esto). Antes de leer arbitrariamente / proc / pid / mem, debe consultar los mapas / proc / pid /. Una simple lectura en este archivo muestra muchas entradas. Estamos interesados en la entrada marcada como stack. Una vez que obtenga esto, debe leer los límites inferior y superior de la pila. Ahora simplemente abra el archivo / proc / pid / mem, busque el límite inferior de la pila y lea el tamaño correcto de los datos.
fuente
mems
y nomaps
? (No puedo ver ningunamems
entrada en mi/proc
sistema de archivos). El OP ya mencionó la lectura de los límites de la pila/proc/$pid/maps
: ¿qué sugiere que hagan de manera diferente?Podrías probar lsstack . Utiliza ptrace, al igual que cualquier otro programa exitoso de "leer la pila de otro proceso". No pude obtener un programa usando / proc / $ pid / mem reading para trabajar. Creo que no puede hacerlo de esa manera, aunque, lógicamente, debería hacerlo.
fuente