Код IL (промежуточный язык) в собственных изображениях .NET - PullRequest
2 голосов
/ 21 мая 2019

Рассмотрим простое консольное приложение .NET, которое содержит только автоматически сгенерированный и пустой метод Main Visual Studio.

Согласно "CLR via C #" Джеффри Рихтера в контексте mscorlib.dll: " Эта сборка автоматически загружается, когда CLR инициализирует ". Вполне понятно, учитывая, что эта сборка содержит, среди прочего, основные типы.

Запуск приложения и настройка фильтра для поиска ссылок на файлы «mscorlib» дает совпадения как для mscorlib.dll, так и для mscorlib.ni.dll:

enter image description here

«ni» обозначает нативный образ, и, учитывая, что сборка mscorlib.dll настолько интенсивно используется, имеет смысл сделать из него нативный образ - mscorlib.ni.dll -, который CLR будет загружать вместо "классический", mscorlib.dll один.

Ожидается тот факт, что к обоим файлам обращаются, поскольку CLR будет использовать только собственное изображение, пока оно синхронизируется с исходной сборкой, из которой оно было сгенерировано. Например, если изменяется исходная сборка, собственный образ больше не используется . Поэтому оба должны быть проверены перед загрузкой родного. Пока все ясно.

Собственные изображения, как заявляет Microsoft здесь , " - это файлы, содержащие скомпилированный машинный код ".

Предполагая, что собственное изображение только содержит машинный код, я попытался открыть mscorlib.ni.dll с помощью дизассемблера ( ILSpy ), просто ожидая, что "PE-файл не содержит любые управляемые метаданные "ошибка, которая будет выброшена. Однако я был удивлен, увидев, что ILSpy правильно загружает сборку, содержит манифест, элементы типа, а также код IL , отображаемый для методов:

enter image description here

Я подозревал, что каким-то образом используется ссылка на 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 дополнительных раздела, довольно большую запись каталога перемещений и загадочный собственный заголовок в пользу родное изображение, но это было довольно много.

enter image description here

Стандарт ECMA 335 введите здесь описание ссылки содержит лишь несколько слов о физической разметке файла изображения относительно самого кода в разделе II.25.4.Помимо того факта, что тело метода следует непосредственно за заголовком метода, и что иногда имеется дополнительная секция данных метода при обработке исключений, стандарт на самом деле ничего не говорит о местонахождении самого машинного кода.

...