2012-06-24 5 views
2

Я в середине написания собственной версии 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.

+0

Вы просто видите вершину айсберга, который затонул «Титаник». Вам также придется иметь дело с манифестами, либо встроенными в качестве ресурсов, либо предоставленными на диске, политиками издателя, переадресацией связывания, безрезультатным COM, динамической активацией через CreateActCtx, настраиваемые пути поиска DLL, установленные с помощью SetDllDirectory. Документация паршивая. –

+0

@HansPassant Мне удалось получить эту работу. Вы были правы в том, что это был только кончик айсберга ха-ха. В конце концов мне пришлось написать Resource Walker, чтобы найти внутренний манифест '.dll' (RT_MANIFEST). Затем мне пришлось написать заглушку для сборки, которая обрабатывала все материалы «Контекст активации». Конечно, я мог бы просто написать его на C++ и обернуть его в .dll со статической связью (т. Е. Без SxS), а затем использовать его для загрузки всех следующих библиотек, но он казался излишним, поэтому я сделал это в сборке. В принципе, я подаю функцию сборки нулевую строку необходимых зависимостей ... –

+0

, а также путь к манифесту (я извлек внутренний манифест во временный файл, «CreateActCtx» нуждается в пути к манифесту). Затем он создает контекст активации, проходит через список модулей с нулевым разделением и называет «GetModuleHandle» для каждого. Если 'GetModuleHandle' возвращает' 0', он переходит к вызову 'LoadLibrary'. Если все еще 0, он выходит из функции. Я знаю, что я пропустил самую сложную задачу, просто используя «LoadLibrary» в «Контексте активации», но я действительно хотел использовать собственный загрузчик для основной dll, а не для его зависимостей. –

ответ

2

На самом деле зависимости SxS зависят от сферы структуры PE! Как вы знаете, таблицы импорта PE перечисляют зависимости имена, но не их версии. При обработке этих таблиц зависимостей загрузчик также просматривает манифест зависимых от PE изображений. Если манифест документирует одну или несколько библиотек (например, msvcr90, advapi32, ....), загрузчик смотрит в папку winsxs, чтобы найти зависимость. Here an article, который дает обзор этой сборки и как собирать эту информацию на C++.

+0

На самом деле, вам не нужно самостоятельно создавать имя зависимостей WinSx. Все, что вам нужно сделать, это «зондировать» с помощью CreateActCtx. Если загрузчик найдет эту зависимость, он построит правильный путь (например, x86_microsoft-windows-msvcrt_31bf3856ad364e35_6.1.7601.17744_none_d33c3413fd4084d9) для вас! – mox

+0

Сборка сбоку сбоку (WinSxs) сложна. У меня была эта проблема во время моей реализации PeStudio (http://www.winitor.com) – mox

+0

Спасибо за ссылку, это делает вещи немного более ясными. Единственное, как вы проверяете, является ли данное имя импорта WinSxS? Я имею в виду, что в манифесте 'Microsoft.VC90.CRT' связан с' msvcr90.dll', но как эта ссылка установлена? Если я впервые прочитал манифест, чтобы определить импорт совместимых с WinSxS, как мне сопоставить их с конкретным именем импорта? –