Любая из этих инструкций может #PF
(исключение сбоя страницы) для операнда памяти (или другими способами в зависимости от инструкции) и изменять CS: EIP на абсолютно новое значение, загруженное из IDT. например, push dword [0]
. Это может включать изменение EIP более чем на 100, если ваш текущий EIP не находится в пределах 100 байтов от адреса обработчика исключений ошибки страницы.
Или если мы говорим о том, куда возвращается обработчик исключения, если ваш процесс имел * Обработчик сигнала установлен для SIGSEGV, ядро может доставить этот сигнал, эффективно меняя EIP в вашем процессе на ваш обработчик сигнала segfault.
Но я думаю, что цель вопроса заключается в изменении EIP с помощью конкретная c требуемая относительная сумма, например, для достижения другого блока кода. (Также не изменяя CS, кодовый сегмент, поэтому вы останетесь в пользовательском режиме, если бы вы были там с самого начала.) Т.е. 100 байтов от от текущего EIP. Формулировка неуклюжа и может быть прочитана как установка EIP для любого абсолютного значения> 100, но ветви x86 являются относительными, и вопрос имеет больше смысла в этом смысле.
Как указывает @ zx485, вам нужна инструкция передачи управления, иначе говоря, переход или ветка. 386 (т. Е. Любая машина с EIP, а не только 16-битным IP) поддерживает условный jcc rel32
условный ближний переход и более короткий jcc rel8
короткий прыжок, поэтому условные переходы могут достигаться где угодно во всем 32-разрядном адресном пространстве, так же как jmp rel32
и call rel32
. https://www.felixcloutier.com/x86/jcc.
Но даже кодирование jcc rel8
(например, JZ или JNZ) или jmp rel8
может достигать от -128 до +127 байт относительно конца инструкции. (Смещение 8-битной ветки дополнения до 2-х знаков.)