Любая из этих инструкций может #PF
(исключение ошибки страницы) в операнде памяти (или другими способами, в зависимости от инструкции) и изменить CS:EIP на совершенно новое значение, загруженное из IDT. например push dword [0]
. Это будет включать изменение EIP более чем на 100, если только ваш текущий EIP не находится в пределах 100 байтов от адреса обработчика исключений сбоя страницы.
Или, если мы говорим о том, куда возвращается обработчик исключений, если в вашем процессе был установлен обработчик сигнала для SIGSEGV, ядро могло бы доставить этот сигнал, фактически изменив EIP в вашем процессе на обработчик сигнала segfault.
Но я думаю, что цель вопроса заключается в изменении EIP на определенную желаемую относительную сумму, например. для достижения другого блока кода. (Также не изменяя 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.)
person
Peter Cordes
schedule
15.01.2020