Ось ще одна стратегія, яка може потребувати налаштування, але повинна бути більш ефективною з великими фрагментами даних. Ідея полягає у виконанні системних викликів у віддаленому процесі, щоб отримати вміст стеку. Він буде потребувати конкретного архітектурного коду, але якщо ви орієнтуєтеся лише на x86 / x86_64, це не повинно бути зайвим.
- Створіть названу трубу, наприклад,
"/tmp/fifo"
у процесі виклику.
- Крок до простеженого процесу, поки він не повернеться з системного виклику, використовуючи
PTRACE_SYSCALL
крок, waitpid()
щоб зачекати та PTRACE_GETREGS
/ PTRACE_PEEKTEXT
перевірити поточно виконаний кодекс.
- Створіть резервні копії регістрів віддаленого процесу та невелику область його стека.
- Виконання системних викликів на віддаленому процесі, перекриваючи його стек з вашими власними даними:
open("/tmp/fifo")
, write()
вміст стека, close()
дескриптор.
- Відновлення стану віддаленого процесу.
- Прочитайте дані фіфо в процесі дзвінка.
Можуть бути і більш елегантні альтернативи названій трубі, але я зараз не можу придумати жодної. Причиною того, що я використовую лише системні дзвінки, є те, що віддалене введення коду в сучасних системах досить ненадійне через різні засоби захисту. Недолік полягає в тому, що він зависне, поки віддалений процес не здійснить системний виклик (що може бути проблемою для деяких програм, які в основному роблять обчислення).
Ви можете побачити деякий безкоштовний код, який реалізує більшу частину роботи у цьому вихідному файлі . Відгуки про код вітаються!
waitpid
міжptrace(PTRACE_ATTACH,…)
іread
(інакше можливий стан гонки)? Яка помилкаread
повертається? Чи дитина робить щось особливе зі своїм відображенням пам’яті - чи можете ви спробувати свій код із такою простою дитиноюsleep
?