пятница, 29 мая 2009 г.

Опять играем со стеком

По ходу экспериментов над нашим мутантом, пришла в голову мысль создать еще один штамм мутантика. Идея состояла в следующем: изменить непосредственно в стеке адрес возврата из подпрограммы, так чтобы подпрограмма вернула управление не на следующую команду после вызвавшей ее команды call, а на команду, указанную нами. Для этого, конечно, пришлось немного забежать вперед по тексту учебника, чтобы найти подходящие для реализации этого финта ушами команды (я так подозреваю, что не самые оптимальные, но замысел удался! :) Вот наш новый мутантик:

Теперь смотрим листинг:

Погружаемся в медитацию...
Команда call subp теперь имеет код E8FFE4. Складываем FFE4h+1Ch получаем 0 (проверьте в калькуляторе Windows предварительно выставив длину 2 байта). Команда jmp finish имеет вид EBF7, где собственно F7 отрицательное (в данном случае) смещение равное -9. То есть эта команда вычитает 9 из следующего после нее адреса (вернее она складывает шестнадцатеричные значения). Проверяем 25h+F7=1C (проверьте в калькуляторе Windows, предварительно выставив длину 1 байт). Почему выставляем длину, то один, то два байта – это тема для медитации :)
Теперь посмотрим прогу в hiew...

Внимательно медитируем на стрелочки :) И далее погружаемся в глубокую медитацию на прогу в отладчике...

Скриншот сделан после выполнения команды call subp (call 0000). Обращаем внимание, что адрес возврата из подпрограммы помещен в стек и равен 001C, как и должно быть. Дебагим нашу прогу дальше до команды ret (ее не выполняем):

Как видим, наш код поменял непосредственно в стеке адрес возврата из подпрограммы, поэтому команда ret извлечет из стека уже не адрес 001С, а адрес 0021, передав таким образом управление уже на этот адрес.

Ну и приведем вывод нашей программы:

C:\ASM\HELLO\TASM>hello10
-=* Hello World *=--=* Hello World *=--=* Hello World *=-
C:\ASM\HELLO\TASM>

Комментариев нет: