пятница, 14 октября 2016 г.

Алгоритм поиска путей не является алгоритмом поиска с откатом

Это перевод The path-searching algorithm is not a backtracking algorithm. Автор: Реймонд Чен.

Предположим, ваша переменная PATH выглядит примерно так:
C:\dir1;\\server\share;C:\dir2
Также предположим, что вы вызываете LoadLibrary('foo.dll'), желая загрузить библиотеку C:\dir2\foo.dll. Если при этом сетевой сервер будет не в сети, то вызов LoadLibrary вернёт ошибку. Почему LoadLibrary просто не пропустит некорректные каталоги в PATH и продолжит искать далее?

Предположим, что LoadLibrary сделала именно это: пропустила недоступный каталог и продолжила искать. Предположим, что код, вызвавший LoadLibrary('foo.dll') в действительности хотел загрузить \\server\share\foo.dll. Просто убрав сервер из сети, вы обманом вынудили LoadLibrary загрузить C:\dir2\foo.dll (а, может, в этом и состоял ваш план атаки внедрения DLL: если вам удастся убедить систему игнорировать все папки в PATH, то в итоге LoadLibrary будет загружать DLL из текущего каталога, куда вы бы поместили свою foo.dll).

Такое поведение приведёт к очень странным эффектам, если эти две копии DLL не идентичны друг другу, потому что тогда программа запустится с версией foo.dll, для которой она не была спроектирована. Как вам такая жалоба пользователя? "Твоя программа работает днём, но возвращает неверные данные после полуночи". Причина: каждую ночь сервер выключается для обслуживания ровно в полночь, поэтому программа начинает использовать C:\dir2\foo.dll, с которой она не совместима.

Когда LoadLibrary не может заглянуть в каталог \\server\share\, она не может сказать, была ли это ситуация "не волнуйся, я и не ожидал найти там файл" или "я надеялся именно на ту версию файла". Поэтому она предпочитает перестраховаться и считает, что файл в той папке всё же был. После этого программа вольна обработать ошибку отсутствия файла foo.dll, как она сочтёт нужным.

Рассмотрите и другой вариант. Предположим, существует файл C:\dir1\foo.dll, но он повреждён (прим. пер.: а также, к примеру, не той разрядности). Если вы вызовите LoadLibrary('foo.dll'), то получите ошибку ERROR_BAD_EXE_FORMAT, потому что LoadLibrary найдёт файл C:\dir1\foo.dll и определит, что он недопустим. LoadLibrary не станет искать более подходящую версию файла. Алгоритм поиска путей не является алгоритмом поиска с откатом. Как только файл найден, алгоритм попытается загрузить файл, а если это не получится, алгоритм не станет делать откат к предыдущему состоянию, чтобы найти другой файл.

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

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.

Примечание. Отправлять комментарии могут только участники этого блога.