Я в середине написания собственной версии Windows Loader (хотя и очень простой версии), и до сих пор все получилось достаточно хорошо. Тем не менее, я столкнулся с небольшой проблемой, когда речь идет о рекурсивном ходьбе таблицы Import для загруженного модуля.Разрешение импорта PE SxS Windows
Для большинства зависимостей все работает хорошо, и я могу просто рекурсивно загрузить модуль. Однако для некоторых зависимостей это просто нарушает целевой процесс. После дальнейших исследований я понял, что это из-за сборок Windows Side-by-side. По сути, зависимость в загруженном PE была другой версией SxS модуля, используемой в целевом процессе.
В одном случае DLL загружалась с ссылкой msvcr90.dll, но в целевом процессе использовалась более ранняя версия среды выполнения: msvcr71.dll.
Теперь загрузчик окон может справиться с этим штрафом, так что, очевидно, есть «правильный» способ сделать это. Я немного прочитал об активационных контекстах, но они не помогли мне понять проблему.
Вызов сам LoadLibrary не решает DLL к правильной версии либо
LoadLibraryW(L"msvcr90.dll");
Просто возвращает 0. Кто-нибудь знает
а) Как определить, если импорт является сборка SxS
b) Как разрешить импорт в правильную версию SxS для процесса.
Я действительно зациклен на том, как это сделать. В настоящее время я знаю большую часть формата файла PE из исследования, но я уверен, что SxS выходит за рамки структуры PE.
Если вам нужна дополнительная информация, просто комментарий. Исполняемый файл не имеет внешнего манифеста, а встроенный манифест не указывает версию исполнения. Однако он содержит копию msvcr71.dll в своем рабочем каталоге, если это помогает кому угодно.
Cheers.
Вы просто видите вершину айсберга, который затонул «Титаник». Вам также придется иметь дело с манифестами, либо встроенными в качестве ресурсов, либо предоставленными на диске, политиками издателя, переадресацией связывания, безрезультатным COM, динамической активацией через CreateActCtx, настраиваемые пути поиска DLL, установленные с помощью SetDllDirectory. Документация паршивая. –
@HansPassant Мне удалось получить эту работу. Вы были правы в том, что это был только кончик айсберга ха-ха. В конце концов мне пришлось написать Resource Walker, чтобы найти внутренний манифест '.dll' (RT_MANIFEST). Затем мне пришлось написать заглушку для сборки, которая обрабатывала все материалы «Контекст активации». Конечно, я мог бы просто написать его на C++ и обернуть его в .dll со статической связью (т. Е. Без SxS), а затем использовать его для загрузки всех следующих библиотек, но он казался излишним, поэтому я сделал это в сборке. В принципе, я подаю функцию сборки нулевую строку необходимых зависимостей ... –
, а также путь к манифесту (я извлек внутренний манифест во временный файл, «CreateActCtx» нуждается в пути к манифесту). Затем он создает контекст активации, проходит через список модулей с нулевым разделением и называет «GetModuleHandle» для каждого. Если 'GetModuleHandle' возвращает' 0', он переходит к вызову 'LoadLibrary'. Если все еще 0, он выходит из функции. Я знаю, что я пропустил самую сложную задачу, просто используя «LoadLibrary» в «Контексте активации», но я действительно хотел использовать собственный загрузчик для основной dll, а не для его зависимостей. –