ptrace — это системный вызов , встречающийся в Unix и некоторых Unix-подобных операционных системах . Используя ptrace (сокращение от «трассировка процесса»), один процесс может управлять другим, позволяя контроллеру проверять и манипулировать внутренним состоянием своей цели. ptrace используется отладчиками и другими инструментами анализа кода, в основном как вспомогательное средство при разработке программного обеспечения.
ptrace используется отладчиками (такими как gdb и dbx ), инструментами трассировки, такими как strace и ltrace , а также инструментами покрытия кода . ptrace также используется специализированными программами для исправления запущенных программ, чтобы избежать неисправленных ошибок или обойти функции безопасности. В дальнейшем его можно использовать как песочницу [1] [2] и как симулятор среды выполнения (например, эмуляцию root-доступа для программного обеспечения без полномочий root [2] [3] ).
Присоединяясь к другому процессу с помощью вызова ptrace, инструмент получает обширный контроль над работой своей цели. Это включает в себя манипулирование его файловыми дескрипторами , памятью и регистрами . Он может пошагово выполнять код цели, может наблюдать и перехватывать системные вызовы и их результаты, а также может манипулировать обработчиками сигналов цели , а также получать и отправлять сигналы от ее имени. Возможность записи в память цели позволяет изменять не только ее хранилище данных, но и собственный сегмент кода приложения , позволяя контроллеру устанавливать точки останова и исправлять работающий код цели. [4]
Поскольку возможность проверять и изменять другой процесс очень мощная, ptrace можно прикреплять только к процессам, которым владелец может отправлять сигналы (обычно только к своим собственным процессам); учетная запись суперпользователя может отслеживать практически любой процесс (кроме init в ядрах до 2.6.26). В системах Linux, где используются возможности POSIX , возможность ptrace дополнительно ограничивается возможностью CAP_SYS_PTRACE [5] или модулем безопасности YAMA Linux . [6] Во FreeBSD это ограничено тюрьмами FreeBSD и политиками обязательного контроля доступа .
Связь между контроллером и целью осуществляется с использованием повторяющихся вызовов ptrace, при этом между ними передается небольшой блок памяти фиксированного размера (что требует двух переключений контекста на каждый вызов); это крайне неэффективно при доступе к большим объемам целевой памяти, поскольку это можно сделать только блоками размером в слово (с вызовом ptrace для каждого слова). [7] По этой причине в 8-м издании Unix появилась procfs , которая позволяет разрешенным процессам прямой доступ к памяти другого процесса - последовала версия 4.4BSD, а использование /proc
поддержки отладчика было унаследовано Solaris, BSD и AIX, и в основном скопирован Linux. [7] Некоторые, такие как Solaris , вообще удалили ptrace как системный вызов, сохранив его как библиотечный вызов, который переинтерпретирует вызовы ptrace с точки зрения procfs платформы. [8] Такие системы используют ioctls в файловом дескрипторе открытого /proc
файла для выдачи команд контролируемому процессу. [8] FreeBSD , с другой стороны, расширила ptrace для устранения упомянутых проблем и объявила procfs устаревшим из-за присущих ему проблем проектирования. [ неопределенно ] [ нужна ссылка ]
ptrace предоставляет только самый простой интерфейс, необходимый для поддержки отладчиков и подобных инструментов. Программы, использующие его, должны иметь глубокие знания особенностей ОС и архитектуры, включая структуру стека, двоичный интерфейс приложения , механизм системных вызовов , искажение имен , формат любых отладочных данных , а также нести ответственность за понимание и дизассемблирование машинного кода . Кроме того, программы, которые внедряют исполняемый код в целевой процесс или (например, gdb) позволяют пользователю вводить команды, которые выполняются в контексте целевого процесса, должны сами генерировать и загружать этот код, как правило, без помощи загрузчика программ .
ptrace был впервые реализован в версии 6 Unix [ 9] и присутствовал как в SVr4 , так и в 4.3BSD ветках Unix. [5] ptrace доступен как системный вызов в IRIX , [10] IBM AIX , [11] NetBSD , [12] FreeBSD , [13] OpenBSD , [14] и Linux . [5] ptrace реализован как вызов библиотеки в Solaris, построенной на файловой системе procfs ядра Solaris; Sun отмечает, что ptrace в Solaris предназначен для обеспечения совместимости, и рекомендует новым реализациям вместо этого использовать более богатый интерфейс, предоставляемый proc. [8] UnixWare также имеет ограниченный ptrace [15] , но, как и Sun, SCO рекомендует вместо этого использовать базовые функции procfs. [16] HP-UX поддерживал ptrace до версии 11i v3 (он был устаревшим в пользу ttrace, аналогичного вызова, специфичного для ОС, в 11i v1). [17]
MacOS от Apple также реализует ptrace как системный вызов. В версии Apple добавлена специальная опция PT_DENY_ATTACH — если процесс вызывает эту опцию для себя, последующие попытки ptrace процесса потерпят неудачу. [18] Apple использует эту функцию, чтобы ограничить использование отладчиков в программах, которые манипулируют контентом с DRM , включая iTunes . [19] PT_DENY_ATTACH on также отключает возможность DTrace отслеживать процесс. [20] Отладчики в OS X обычно используют комбинацию ptrace, API Mach VM и потоков. [21] ptrace (опять же с PT_DENY_ATTACH) доступен разработчикам для Apple iPhone . [22]
Linux также дает процессам возможность предотвращать присоединение к ним других процессов. Процессы могут вызвать prctl
системный вызов и очистить свой PR_SET_DUMPABLE
флаг; в более поздних ядрах это не позволяет некорневым процессам отслеживать вызывающий процесс; Агент аутентификации OpenSSH использует этот механизм для предотвращения перехвата сеанса ssh через ptrace. [23] [24] [25] Более поздние версии Ubuntu поставляются с ядром Linux, настроенным на предотвращение подключения ptrace от процессов, отличных от родительского отслеживаемого процесса; это позволяет gdb и strace продолжать работать при запуске целевого процесса, но предотвращает их подключение к несвязанному работающему процессу. [23] Управление этой функцией осуществляется через /proc/sys/kernel/yama/ptrace_scope
настройки. [23] В системах, где эта функция включена, такие команды, как « gdb --attach
» и « strace -p
» не будут работать.
Начиная с Ubuntu 10.10 , ptrace разрешено вызывать только для дочерних процессов. [23]
На некоторых телефонах Android с заблокированным загрузчиком ptrace используется для получения контроля над процессом инициализации, включения «второй загрузки» и замены системных файлов. [ нужна цитата ]