Как стать автором
Обновить

Комментарии 29

Еще есть библиотека dynamix для изменения поведения «на ходу». .На с++ russia 2018 был хороший доклад от автора. Он привел несколько хороших «наглядных» примеров из мира геймдева.
Интересно, посмотрим, спасибо. Бросается в глаза то, что библиотека в некотором роде диктует архитектуру приложения. Но сам подход выглядит необычно для c++
1. Останавливаем целевой процесс через ptrace
2. Подливаем обновленный объектник по-живому в память (при необходимости выделяем ещё или используем пустые хвосты в конце последних страниц секций)
3. Ручками разрешаем символы как это делает динамический загрузчик в подлитом объектнике превращая его в рабочий код
4. Перекидываем на него GOT/PLT
5. Восстанавливаем работу процесса
6. Все это делается внешним относительно пациента приложением

Ну это так. Очень мазками по верхам. Когда-то давно приходилось автоматически патчить по-живому. После определенных трахов вполне работает.
Это тоже вариант. Может вы еще знаете, как остановить все потоки, кроме текущего, на время патчинга, хотя бы на linux? Чтобы не прибегать к помощи внешней программы

Отправить им SIGSTOP?

В смысле через pthread_kill? Вы пробовали провернуть такое? Из того, что удалось нагуглить, это не сработает, но надо пробовать

Ну типа
for pid in thread_list
kill(pid, SIGSTOP)
И еще завернуть это в цикл, пока что-то было остановлено

Думаю нет.
kill — send signal to a process

Ну я не уверен, насколько мой вариант хорош, но суть ваших претензий не совсем понимаю. В linux потоки — нечто, не слишком отличное от процесса, и запуск потока это вроде как clone(CLONE_VM|CLONE_THREAD).

man7.org/linux/man-pages/man3/pthread_kill.3.html
Signal dispositions are process-wide: if a signal handler is
installed, the handler will be invoked in the thread thread, but if
the disposition of the signal is «stop», «continue», or «terminate»,
this action will affect the whole process.


Поэтому и сомневаюсь

А, ну тогда вообще круто — один kill, и все потоки остановлены.

Задача в том, чтобы остановить все потоки, кроме того, который патчит код.
Поэтому остановка всего процесса со всеми потоками не подходит
1. В библиотеке — если вы таки на этом так настаиваете — создаете дочерний процесс
2. Выносите в него всю логику отслеживания изменений объектников
3. В нем через ptrace(2) останавливаете родительский процесс и патчите как вам хочется
Видимо это единственный вариант, спасибо
Скорее -fpatchable-function-entry=N[,M]

Generate N NOPs right at the beginning of each function, with the function entry point before the Mth NOP. If M is omitted, it defaults to 0 so the function entry points to the address just at the first NOP. The NOP instructions reserve extra space which can be used to patch in any desired instrumentation at run time, provided that the code segment is writable. The amount of space is controllable indirectly via the number of NOPs; the NOP instruction used corresponds to the instruction emitted by the internal GCC back-end interface gen_nop. This behavior is target-specific and may also depend on the architecture variant and/or other compilation options.

Собственно то, чего не хватало автору на сколько я понимаю

А это вообще звучит, как то, чего автор не нашёл — gj:)

А ведь правда, спасибо за наводку! Жалко в clang этот флаг еще не реализовали
У меня мозг завис на заголовке) Если я правильно понял ситуацию, то речь о подмене нативного или управляемого кода, С++ там уже нет ни капли. На мой взгляд, заголовок не совсем корректен.
Не совсем вас понял. В статье идет речь о том, как без перезапуска приложения обновить в нем работающий машинный код, исходником которого является код на c или c++. Формально в машинный код можно скомпилировать не только код на c или c++, но в описанном подходе используется инструментарий для сборки кода именно на этих двух языках. Или я неправильно вас понял?
В статье идет речь о том, как без перезапуска приложения обновить в нем работающий машинный код

Во, все-таки обновляется машинный код, а не С++, а по заголовку кажется не так…
Ладно, это я уже придираюсь, наверное. Статья весьма интересная, плюсанул )
А что там такое, что специфично именно для С++? Ну разве что манглинг. Без смены типов параметров заменится любой язык.
Хорошо, если вам и правда это принципиально.
Библиотека, которая реализует эту функциональность, написана на c++, пользовательское приложение, к которому линкуется библиотека, должно инстанциировать экземаляр c++ класса, вызывать методы этого c++ класса, возможно реализовать обработку коллбеков от библиотеки в виде наследования от класса-делегата, который тоже является c++ классом. Конечно, при большом желании это можно делать и из не-c++ кода, и перезагружать не-c++ код, но конкретно в этой статье речь идет о c++.
Предлагаю закрыть тему с названием статьи.
Ну то есть часть приложения на С++, поэтому рантайм должен быть совместимым с С++. Но Си явно подходит.

Чтобы два раза не вставать — почему вы сделали все в одном приложении, а не два разных процесса? Вроде с двумя процессами часть проблем уходит.
Да, си без проблем подойдет.

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

Ну и в итоге можно будет в отлаживаемом приложении ограничиться (при минимальной функциональности) сишными вызовами, а это уже огромная куча языков.
При большом желании это все можно завернуть в c-api, делов на пару часов. Если вам это будет интересно, пожалуйста заведите issue на гитхабе, сделаем
Мне интересно под FreeRTOS, а это значит — делать самому. :-) Но свой загрузчик у нас уже есть.

Напомнило gdb code injections, ещё из полезных фитч есть запись трассе и шаг назад, вроде бы это называется back in time debagger. Помню ещё давно школьник писал статью про модификацию того же gdb где программа форкалась. Из интересного но врядли имеющего отношение к делу есть обратное исполнение, вроде бы был даже коммерческий дебагер с такой возможность, заранее извиняюсь, в плане технологий я больше каталог. Точно помню что это было у меня в заметках года два три назад, пороюсь отпишусь. Конечно мало отношения к тематике стать, но вдруг кого заинтересует

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории