ptrace es una llamada al sistema que se encuentra en Unix y en varios sistemas operativos similares a Unix . Al utilizar ptrace (abreviatura de "process trace"), un proceso puede controlar a otro, lo que permite al controlador inspeccionar y manipular el estado interno de su objetivo. Los depuradores y otras herramientas de análisis de código utilizan ptrace , principalmente como ayuda para el desarrollo de software.
Los depuradores (como gdb y dbx ), las herramientas de rastreo como strace y ltrace y las herramientas de cobertura de código utilizan ptrace . Los programas especializados también utilizan ptrace para aplicar parches a programas en ejecución, evitar errores no corregidos o superar las características de seguridad. También se puede utilizar como un entorno aislado [1] [2] y como un simulador de entorno de ejecución (como emular el acceso root para software que no es root [2] [3] ).
Al conectarse a otro proceso mediante la llamada ptrace, una herramienta tiene un amplio control sobre el funcionamiento de su objetivo. Esto incluye la manipulación de sus descriptores de archivos , memoria y registros . Puede recorrer paso a paso el código del objetivo, puede observar e interceptar llamadas del sistema y sus resultados, y puede manipular los controladores de señales del objetivo y tanto recibir como enviar señales en su nombre. La capacidad de escribir en la memoria del objetivo permite no solo cambiar su almacén de datos, sino también el propio segmento de código de la aplicación , lo que permite al controlador instalar puntos de interrupción y parchear el código en ejecución del objetivo. [4]
Como la capacidad de inspeccionar y alterar otro proceso es muy poderosa, ptrace puede adjuntarse solo a procesos a los que el propietario puede enviar señales (normalmente solo sus propios procesos); la cuenta de superusuario puede realizar ptrace en casi cualquier proceso (excepto init en núcleos anteriores a 2.6.26). En sistemas Linux donde se utilizan capacidades POSIX , la capacidad de realizar ptrace está limitada aún más por la capacidad CAP_SYS_PTRACE [5] o por el módulo de seguridad de Linux YAMA . [6] En FreeBSD , está limitada por las cárceles de FreeBSD y las políticas de control de acceso obligatorio .
Las comunicaciones entre el controlador y el objetivo se llevan a cabo utilizando llamadas repetidas de ptrace, pasando un pequeño bloque de tamaño fijo de memoria entre los dos (lo que requiere dos cambios de contexto por llamada); esto es extremadamente ineficiente cuando se accede a grandes cantidades de memoria del objetivo, ya que esto solo se puede hacer en bloques del tamaño de una palabra (con una llamada a ptrace para cada palabra). [7] Por esta razón, la octava edición de Unix introdujo procfs , que permite a los procesos permitidos acceder directamente a la memoria de otro proceso; le siguió 4.4BSD, y el uso de /proc
para el soporte del depurador fue heredado por Solaris, BSD y AIX, y mayormente copiado por Linux. [7] Algunos, como Solaris , han eliminado ptrace como una llamada al sistema por completo, manteniéndolo como una llamada a la biblioteca que reinterpreta las llamadas a ptrace en términos del procfs de la plataforma. [8] Dichos sistemas utilizan ioctls en el descriptor de archivo del /proc
archivo abierto para emitir comandos al proceso controlado. [8] FreeBSD , por otro lado, amplió ptrace para eliminar los problemas mencionados y declaró obsoleto a procfs debido a sus problemas de diseño inherentes. [ vago ] [ cita requerida ]
ptrace sólo proporciona la interfaz más básica necesaria para soportar depuradores y herramientas similares. Los programas que lo utilizan deben tener un conocimiento profundo de los detalles del sistema operativo y la arquitectura, incluyendo el diseño de la pila, la interfaz binaria de la aplicación , el mecanismo de llamada del sistema , la manipulación de nombres , el formato de cualquier dato de depuración , y son responsables de comprender y desensamblar el código de la máquina ellos mismos. Además, los programas que inyectan código ejecutable en el proceso de destino o (como gdb) permiten al usuario ingresar comandos que se ejecutan en el contexto del destino deben generar y cargar ese código ellos mismos, generalmente sin la ayuda del cargador de programas .
ptrace se implementó por primera vez en la versión 6 de Unix , [9] y estaba presente en las ramas SVr4 y 4.3BSD de Unix. [5] ptrace está disponible como una llamada al sistema en IRIX , [10] IBM AIX , [11] NetBSD , [12] FreeBSD , [13] OpenBSD , [14] y Linux . [5] ptrace se implementa como una llamada a la biblioteca en Solaris, construida sobre el sistema de archivos procfs del núcleo Solaris; Sun señala que ptrace en Solaris está pensado para la compatibilidad, y recomienda que las nuevas implementaciones utilicen en su lugar la interfaz más rica que proporciona proc. [8] UnixWare también presenta un ptrace limitado [15] pero al igual que Sun, SCO recomienda que los implementadores utilicen en su lugar las características procfs subyacentes. [16] HP-UX admitió ptrace hasta la versión 11i v3 (quedó obsoleto en favor de ttrace, una llamada similar específica del sistema operativo, en 11i v1). [17]
El sistema operativo macOS de Apple también implementa ptrace como una llamada al sistema. La versión de Apple agrega una opción especial PT_DENY_ATTACH: si un proceso invoca esta opción sobre sí mismo, los intentos posteriores de ptrace sobre el proceso fallarán. [18] Apple usa esta función para limitar el uso de depuradores en programas que manipulan contenido DRM , incluido iTunes . [19] PT_DENY_ATTACH también deshabilita la capacidad de DTrace para monitorear el proceso. [20] Los depuradores en OS X generalmente usan una combinación de ptrace y las API de subprocesos y VM de Mach . [21] ptrace (nuevamente con PT_DENY_ATTACH) está disponible para desarrolladores para el iPhone de Apple . [22]
Linux también da a los procesos la capacidad de evitar que otros procesos se adhieran a ellos. Los procesos pueden llamar a la prctl
llamada al sistema y borrar su PR_SET_DUMPABLE
bandera; en kernels posteriores esto evita que los procesos que no son root rastreen el proceso que llama; el agente de autenticación OpenSSH usa este mecanismo para evitar el secuestro de sesiones ssh a través de ptrace. [23] [24] [25] Las versiones posteriores de Ubuntu se entregan con un kernel Linux configurado para evitar que ptrace se adhiera a procesos que no sean el padre del proceso rastreado; esto permite que gdb y strace sigan funcionando cuando se ejecuta un proceso de destino, pero evita que se adhieran a un proceso en ejecución no relacionado. [23] El control de esta característica se realiza a través de la /proc/sys/kernel/yama/ptrace_scope
configuración. [23] En sistemas donde esta característica está habilitada, los comandos como " gdb --attach
" y " strace -p
" no funcionarán.
A partir de Ubuntu 10.10 , solo se puede llamar a ptrace en procesos secundarios. [23]
En algunos teléfonos Android con un cargador de arranque bloqueado, se utiliza ptrace para obtener control sobre el proceso de inicio para habilitar un "segundo arranque" y reemplazar los archivos del sistema. [ cita requerida ]