Comments 21
Интересует не намеренное ломание логики приложения, т.к. если есть возможность подменить DLL, то просто сломать можно простым ее переименованием. Интересует защита именно проверкой загружаемой библиотеки.
К слову у DLL прокси, после реализации всех экспортных методов, с помощью мусорного кода, можно и MD5 нужный подобрать. Тут лучше 2 хеша разных сразу проверить.
Вы между тем забыли упомянуть о KnownDLLs в который внесены основные системные dll-ки. Так что трюк с version.dll не пройдёт. А ещё есть CWDIllegalInDllSearch который тоже меняет порядок поиска dll-ок… Это правда редко кем-либо настраивается, скорее в корпоративных окружениях.
Но все же, version.dll не входит в список KnownDLLs (по крайней мере на ближайших доступных мне машинах). И инъекция отлично работает (на гитхабе выложены билды dll, опыт ставится легко).
![](https://habrastorage.org/webt/vi/br/dn/vibrdnriaqhmfnrwrpztdbtjknw.png)
![](https://habrastorage.org/webt/ks/z0/gy/ksz0gyits9j9uyh3ryarnsrafkm.png)
Как уже написали выше, про KnownDLLs хорошо бы указать в самой статье, а это важное место с точки зрения защиты.
WinSxS redirect (aka “DotLocal”).
Это не "aka", а лишь один из способов. Не освещен другой механизм: ApiSetSchema — набор маршрутов загрузки dll по спец именам (типа api-ms-win-core-errorhandling-l1-1-0.dll), присутствующий в Win7 и выше. Тут хайджекинг не сработает.
До сих пор встречаю инсталляторы, которые распаковываются в Temp и запускаются оттуда.
Запомните: корень папки Temp — это помойка, в ней может лежать что угодно, в том числе и любые dll, которые запущенная оттуда программа радостно подхватит. Если вам нужно распаковаться во временное хранилище и запустить оттуда код — создавайте хотя-бы подпапку со случайным именем.
И то, даже в этом случае будет состояние гонки, так что по-хорошему на эту папку нужно ещё и правильный дескриптор безопасности навесить. Естественно, это относится к ситуации, когда пользователь работает со включённым UAC в Admin Approval Mode, ведь в этом случае папка Temp является общей для программ, работающих с разными уровнями привилегий.
BOOL WINAPI SetDllDirectory(LPCTSTR lpPathName);
Добавляет произвольный путь к местам поиска DLL и меняет порядок (после папки с приложением поиск будет в папке, указанной в lpPathName); это влияет на все последующие вызовы LoadLibrary[Ex].
upd: Когда-то я так делал для BDE (IDAPI32.dll), теперь — для sqlite. В моих заголовочниках импорт статический, переписывать на динамический лень. Потому я просто заменил импорт на отложенный импорт, чтоб виндовый загрузчик не ругался, а при старте приложения читаю путь к DLL из реестра и передаю в SetDllDirectory. Можно, конечно, положить DLL в папку к каждому приложению (и не забывать их обновлять) или же нагадить в System32, но мне так больше нравится.
Создание прокси-dll для проверок эксплуатации dll hijack