Передача управления ptrace другому процессу

Вопрос или проблема

Я задал этот вопрос на сайте reverse engineering stackexchange: https://reverseengineering.stackexchange.com/questions/15169/transferring-control-of-ptrace-to-another-process потому что подумал, что вопрос о ptrace будет наиболее уместным там.

Я не получил никаких ответов, не знаю, связано ли это с тем, что там слишком мало людей, или они не очень знакомы с linux. В любом случае, я подумал, что стоит спросить здесь.

Я хотел бы создать процесс A. В A я хотел бы запустить второй процесс B. Я хотел бы, чтобы A продолжал отслеживать системные ресурсы. Когда будут выполнены определенные условия, я хочу, чтобы A ptrace B, запустил gdb и передал управление ptrace в gdb.

Это возможно? Если нет, есть ли способ, чтобы A приостановил B, запустил gdb с прикрепленным B, а затем “развесил” B?

Не могу комментировать, но поскольку пока нет никаких ответов:

Самый большой вопрос — зачем вообще переключаться на gdb, почему бы не продолжить с ptrace?

Самая сложная часть — это, безусловно, передача управления от ptrace к gdb. В частности, как удерживать процесс в приостановленном состоянии и подключить GDB, чтобы продолжить отладку с этого момента; когда ptrace отключает, дочерний процесс продолжает выполнение, и, насколько я знаю, это неизбежно.

Возможно, есть другой способ это сделать. В любом случае, зависит ли условие для перехода к GDB от системных ресурсов, отслеживаемых A, или условие локально для B?

И похоже, что ваши варианты ‘возможно ли это’ и ‘если нет’ предполагают сделать одно и то же, если я не ошибаюсь.

Вы можете посмотреть, как работает разрешение ptrace: https://www.kernel.org/doc/Documentation/security/Yama.txt

Вкратце:

  • вы можете сделать, например, echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope. Это позволит любому процессу прикрепляться к любому другому процессу, однако ослабит безопасность.

Остальная часть этого ответа предполагает ptrace_scope = 1, что является значением по умолчанию на моей машине.


Таким образом, если вы хотите, чтобы gdb подключался к B, есть два способа:

  • Сделайте так, чтобы B разрешал прикрепление ptrace от процесса gdb. Используйте вышеупомянутый системный вызов.

    Вам не нужно модифицировать B, просто модифицируйте A, чтобы вызывать функцию после fork(), но до exec([B]).

  • Сделайте gdb родителем B.

    Это сложно, но план такой:

    • A сначала выполняет fork() на A1
    • A1 создает B, затем ожидает сигнала от A
    • A сигнализирует A1, чтобы exec(gdb), чтобы заменить себя на gdb

Полный пример кода.


Скорее всего, это лучшее, что вы можете получить. Потому что существуют только очень ограниченные способы изменить родительский процесс существующего процесса.

Ответ или решение

Передача контроля ptrace другому процессу

Введение

Запрос на передачу управления инструментом ptrace другому процессу является актуальной задачей для специалистов в области разработки программного обеспечения и реверс-инжиниринга. В этом ответе мы рассмотрим методику, с помощью которой можно наблюдать за процессом, а затем передать управление от одного процесса другому, используя gdb для дебага.

Предпосылки

Сначала уточним настройки, касающиеся безопасности в Linux, связанные с ptrace. По умолчанию система имеет параметры, которые мешают процессу A прикрепляться к процессу B, если A не является родительским процессом B. Мы рассмотрим различные подходы для решения данной задачи с учетом основных требований:

  1. Система должна быть настроена для разрешения использования ptrace.
  2. Процессы A и B должны быть правильно инициализированы.
  3. Возможность переключения контроля ptrace на gdb должна быть налажена.

Метод передачи управления

1. Разрешение на использование ptrace

Вы можете установить разрешения для ptrace, используя команду echo для изменения параметра ptrace_scope. Например, выполнение следующей команды позволит процессу A прикрепляться к процессу B:

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

Однако следует помнить, что это ослабляет безопасность системы. В большинстве случаев рекомендуется оставить значение по умолчанию (1).

2. Использование prctl для разрешения на ptrace

Есть два подхода для разрешения процессу A использовать ptrace на процессе B:

  1. A является родительским для B: В этом случае A может непосредственно использовать ptrace.

  2. B должен разрешить A: В этом случае процесс B может вызвать системный вызов:

prctl(PR_SET_PTRACER, [A], 0, 0, 0);

Этот вызов можно выполнить из процесса A непосредственно перед запуском процесса B с помощью fork().

3. Разрешение на подключение gdb

Теперь, когда процесс A может использовать ptrace с процессом B, необходимо разрешить gdb взаимодействовать с процессом B:

  • Позволить gdb подключиться к B через prctl: Это можно сделать, вызвав prctl из процесса B перед его запуском.

  • Являться родителем gdb: Можно добиться этого, создав промежуточный процесс. Для этого:

pid_t pid = fork();
if (pid == 0) {
    // A1 будет здесь
    pid_t b_pid = fork(); // запускаем B
    waitpid(b_pid, 0, 0); // ждем сигнал от A1
    execlp("gdb", "gdb", "-p", b_pid); // запускаем gdb с подключением к B
}

Заключение

Таким образом, передача управления инструментом ptrace другому процессу, такому как gdb, требует тщательной настройки и выполнения ряда шагов. Важным является установка правильных разрешений и использование системных вызовов для управления поведением процессов. Важно учитывать безопасность, так как изменения в ptrace_scope могут повлиять на систему в целом.

Это решение может быть адаптировано для различных сценариев, позволяя эффективно диагностировать проблемы в процессе B при помощи gdb, не потеряя управления.

Оцените материал
Добавить комментарий

Капча загружается...