Многие компиляторы позволяют нам исправлять работающий двоичный файл, резервируя некоторое пространство для NOP, которое будет заменено инструкциями ветвления для перенаправления на недавно исправленную функцию.Например, MSVC поддерживает оперативное исправление , оставляя 2 байта для mov edi, edi
в начале функции и 6 байтов заполнения для jmp new_func
до этого, а в gcc у вас есть -fpatchable-function-entry
опция
-fpatchable-function-entry=N[,M]
- Генерировать
N
NOP непосредственно в начале каждой функции, с точкой входа в функцию перед M
th NOP,Если M
опущено, по умолчанию используется значение 0, поэтому вход функции указывает на адрес только в первом NOP.Инструкции NOP резервируют дополнительное пространство, которое можно использовать для исправления в любом желаемом инструментарии во время выполнения, при условии, что сегмент кода доступен для записи.
Но если старая функция глючит, почему можетмы просто уничтожаем его и перезаписываем запись с помощью инструкции перехода?Или мы можем написать новую функцию на месте, если она меньше, чем старая.Даже в редких случаях, когда мы хотим вернуться к старой версии, мы можем просто зарезервировать некоторое пространство перед исправленной функцией и создать резервную копию перезаписанных байтов или просто перезагрузить их из исполняемого файла.
Зачем нам нужносохранить старый двоичный файл при исправлении?