Фундаментальные основы хакерства




Идентификация функций - часть 7


Возникает резонный вопрос – чем же там плох CALL, и зачем прибегать к JMP? Дело в том, что функция, вызванная по CALL, после возврата управления материнской функции всегда передает управление команде, следующей за CALL. В ряде случаев (например, при структурной обработке исключений) возникает необходимость после возврата из функции продолжать выполнение не со следующей за CALL командой, а совсем с другой ветки программы. Тогда-то и приходится "вручную" заносить требуемый адрес возврата и вызывать дочернею функцию через JMP.

Идентифицировать такие функции (особенно если они не имею пролога – см. "Пролог") очень сложно – контекстный поиск ничего не даст, поскольку команд JMP, использующихся для локальных переходов, в теле любой программы очень и очень много – попробуй-ка, проанализируй их все! Если же этого не сделать – из поля зрения выпадут сразу две функции – вызываемая функция и функция, на которую передается управление после возврата. К сожалению, быстрых решений этой проблемы не существует – единственная зацепка – вызывающий JMP практически всегда выходит за границы функции, в теле которой он расположен. Определить же границы функции можно по эпилогу (см. "Эпилог").

Рассмотрим следующий пример:

funct();

main()

{

__asm

{

LEA ESI, return_addr

PUSH ESI

JMP funct

return_addr:

}

}

Листинг 11 Пример, демонстрирующий "ручной" вызов функции инструкцией JPM

Результат его компиляции в общем случае должен выглядеть так:

.text:00401000      push   ebp

.text:00401001      mov    ebp, esp

.text:00401003      push   ebx

.text:00401004      push   esi

.text:00401005      push   edi

.text:00401006      lea    esi, [401012h]

.text:0040100C      push   esi

.text:0040100D      jmp    401017

.text:0040100D ; Смотрите – казалось бы тривиальный условный переход, - что в нем

.text:0040100D ; такого? Ан, нет! Это не простой переход, - это замаскированный

.text:0040100D ; вызов функции! Откуда это следует? А давайте перейдем по адресу




Содержание  Назад  Вперед