Рассмотрим простое консольное приложение .NET, которое содержит только автоматически сгенерированный и пустой метод Main Visual Studio.
Согласно "CLR via C #" Джеффри Рихтера в контексте mscorlib.dll
: " Эта сборка автоматически загружается, когда CLR инициализирует ". Вполне понятно, учитывая, что эта сборка содержит, среди прочего, основные типы.
Запуск приложения и настройка фильтра для поиска ссылок на файлы «mscorlib» дает совпадения как для mscorlib.dll
, так и для mscorlib.ni.dll
:
«ni» обозначает нативный образ, и, учитывая, что сборка mscorlib.dll
настолько интенсивно используется, имеет смысл сделать из него нативный образ - mscorlib.ni.dll
-, который CLR будет загружать вместо "классический", mscorlib.dll
один.
Ожидается тот факт, что к обоим файлам обращаются, поскольку CLR будет использовать только собственное изображение, пока оно синхронизируется с исходной сборкой, из которой оно было сгенерировано. Например, если изменяется исходная сборка, собственный образ больше не используется . Поэтому оба должны быть проверены перед загрузкой родного. Пока все ясно.
Собственные изображения, как заявляет Microsoft здесь , " - это файлы, содержащие скомпилированный машинный код ".
Предполагая, что собственное изображение только содержит машинный код, я попытался открыть mscorlib.ni.dll
с помощью дизассемблера ( ILSpy ), просто ожидая, что "PE-файл не содержит любые управляемые метаданные "ошибка, которая будет выброшена. Однако я был удивлен, увидев, что ILSpy правильно загружает сборку, содержит манифест, элементы типа, а также код IL , отображаемый для методов:
Я подозревал, что каким-то образом используется ссылка на mscorlib.dll
, и все данные фактически извлекаются оттуда. Однако Process Monitor, отфильтрованный по имени образа ILSpy, доказал, что я ошибался: нет даже одной попытки открыть mscorlib.dll
; Есть только несколько попыток получить файл .pdb, который, скорее всего, ищет символы, который потерпел неудачу из-за того, что этот файл не существует.
Фактически обе сборки - mscorlib.dll
и mscorlib.ni.dll
- выглядят одинаково, с той лишь разницей, что IL_ONLY и IL_LIBRARY в структуре Corflags.
Попытка загрузить другие собственные изображения из NIC (Native Image Cache) привела к аналогичному поведению.
Я мог бы найти подробную информацию о том, как нативное изображение все еще считается действительным ( здесь ), но не так много о моем реальном вопросе:
Каким образом собственные изображения могут быть разобраны до уровня кода IL? Сохранены ли IL и машинный код в исходном изображении?
Обновление 5/27/2019 : Кажется, что определение Microsoft несколько неуловимо. Вероятно, его следует интерпретировать как собственные изображения: « - это файлы, содержащие скомпилированный машинный код для конкретного процессора », , за исключением метаданных обычной сборки и кода IL . «Нативная» частица внутри термина, по-видимому, приводит к неправильному значению.
Полученные 2 хороших комментария приводят к следующему естественному вопросу: Где машинный код фактически хранится в самом файле изображения?
Что касается подробностей о содержимом файла изображения, CFF Explorer показал немного больше, чем JetBrain dotPeek, и выделил 2 дополнительных раздела, довольно большую запись каталога перемещений и загадочный собственный заголовок в пользу родное изображение, но это было довольно много.
Стандарт ECMA 335 введите здесь описание ссылки содержит лишь несколько слов о физической разметке файла изображения относительно самого кода в разделе II.25.4.Помимо того факта, что тело метода следует непосредственно за заголовком метода, и что иногда имеется дополнительная секция данных метода при обработке исключений, стандарт на самом деле ничего не говорит о местонахождении самого машинного кода.