Принудительный выход из функции - часть 3
00401323 call 00401BC4
00401328 pop esi
00401329 add esp,64h
0040132C ret
0040132C
0040132D push 0
0040132D ; эта ветка получает управление, если Функция 401350h вернет FFh
0040132F push 0
00401331 push 405048h
00401336 mov ecx,esi
00401338 call 00401BC4
0040133D pop esi
0040133E add esp,64h
00401341 ret
Листинг 7 дизассемблерный листинг материнской функции
Смотрите: если регистр EAX равен FFh, то материнская функция передает управление на ветку 40132Dh и спустя несколько машинных команд завершает свою работу, передавая бразды правления функции более высокого уровня. Напротив, если EAX != FFh, то его значение передается функции 4033B4h. Следовательно, мы можем предположить, что FFh –— это флаг ошибки и есть. Возвращаемся в подопытную функцию, нажав <Ctrl>+<-G> и "EIP", переходим в окно "Registers" и меняем значение регистра EAX на FFh.
Теперь необходимо найти подходящую точку возврата из функции. Просто перейти к машинной команде "RET" нельзя, поскольку перед выходом из функции следует в обязательном порядке сбалансировать стек или нас "выбросит" неизвестно куда и программа "обрушится" окончательно.
В общем случае число PUSH-команд должно в точности соответствовать количеству POP (также учитывайте, что PUSH DWORD X эквивалентен SUB ESP, 4, а POP DWORD X –—
ADD ESP, 4). Проанализировав дизассемблерный листинг функции, мы приходим к выводу, что для достижения "гармонии добра и зла" мы должны "стащить" с вершины стека два двойных слова, соответствующие машинным командам 40135С:PUSH ESI и 401361:PUSH EDI. Это достигается передачей управления по адресу 40136Dh, где "живут" дваа "добродушныхех" команды POP'a'а, приводящие стек в равновесное состояние.Подводим сюда курсор и уверенным щелчком правой клавиши мыши вызываем контекстное меню, среди пунктов которого выбираем "Set Next Statement". Как вариант можно перейти в окно регистров и изменить значение регистра EIP с 401362h на 40136Dh.
Нажатием клавиши <F5> мы заставляем процессор продолжить выполнение программы и… о чудо! Она действительно продолжает свою работу ("незлобное ругательство" на ошибку последней операции –— не в счет!). Несохраненные данные спасены!