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