Аннотация:
В статье описываются таблицы метаданных, правила вычисления их размеров, показывается, каким образом от таблиц можно перейти к логической организации данных. В частности, в статье показано, каким образом можно получить доступ к управляемому коду, что невозможно при использовании Reflection.
Re: Физическая организация метаданных в исполняемых файлах .
Здравствуйте, Павел Румянцев, Вы писали:
ПР>Статья: ПР>Физическая организация метаданных в исполняемых файлах .NET
ПР>Авторы: ПР> Павел Румянцев
ПР>Аннотация: ПР>В статье описываются таблицы метаданных, правила вычисления их размеров, показывается, каким образом от таблиц можно перейти к логической организации данных. В частности, в статье показано, каким образом можно получить доступ к управляемому коду, что невозможно при использовании Reflection.
Одного вот только не пойму — нахрен это надо знать???? свои фреймворки вроде никто писать не собираеться... а простому програмеру это обсолютно до фени, потому как на ни на что не влияет.
Интересно — но безполезно!
Re[2]: Физическая организация метаданных в исполняемых файла
Добрый день. Постараюсь ответить на явно и неявно поставленные вопросы.
1. Появление статьи на сайте не предполагает, что посетители сайта ОБЯЗАНЫ эту статью изучать. Не хочется — просто не читайте. Возможно, статья будет полезна ещё кому-то. Однако, наверное, не секрет, что перед опубликованием все статьи проходят определённую обработку, причём, не только чисто техническую. В частности, каждая из статей обсуждается группой программистов, в которую входят специалисты в самых разных областях программирования. Если статья кажется заслуживающей внимания, то она публикуется.
2. Обычно в сугубо специализированном издании любому читателю интересны 10, много 20 процентов материалов. Попробуйте представить, что моя статья входит в те 80 процентов, которые Вам не интересны. Если же Вам интересны не 20 процентов, а более, то я могу только порадоваться.
3. Любая статья, с моей точки зрения, должна вызывать либо определённый интерес, либо мысль, что, мол, нужно будет хоть когда-нибудь познакомиться с предметом поближе... Вам было интересно читать, Вы об этом написали. Я благодарен Вам за отзыв о статье. Значит, я работал не зря.
С уважением,
Павел Румянцев aka OldDino
AK>Здравствуйте, Павел Румянцев, Вы писали:
ПР>>Статья: ПР>>Физическая организация метаданных в исполняемых файлах .NET
ПР>>Авторы: ПР>> Павел Румянцев
ПР>>Аннотация: ПР>>В статье описываются таблицы метаданных, правила вычисления их размеров, показывается, каким образом от таблиц можно перейти к логической организации данных. В частности, в статье показано, каким образом можно получить доступ к управляемому коду, что невозможно при использовании Reflection.
AK>Одного вот только не пойму — нахрен это надо знать???? свои фреймворки вроде никто писать не собираеться... а простому програмеру это обсолютно до фени, потому как на ни на что не влияет.
AK>Интересно — но безполезно!
Re[3]: Физическая организация метаданных в исполняемых файла
AK>Одного вот только не пойму — нахрен это надо знать???? свои фреймворки вроде никто писать не собираеться... а простому програмеру это обсолютно до фени, потому как на ни на что не влияет.
Это выленки на заваленке простые... тут народ разный тусуется.
AK>Интересно — но безполезно!
"...Каждому свое..." (r).
Мне например интересно, хотя статья несколько запаздала — все в доках до этого перечитал несколько раз
Re[3]: Физическая организация метаданных в исполняемых файла
Здравствуйте, AndrewVK, Вы писали:
AVK>А как по твоему достать IL-код?
Ну кто занимаеться хакингом — может ему и полезно, а мне как девелоперу статья абсолютно ничего не дала... ну знаю я теперь как организованы мето данные в EXE файле... а толку, то!..
AVK>Ты знаешь, может это и плохо, но статьи пишут по большей части непростые программеры
Вот это местами и плохо. потому как в основном "крутые" программеры часто залазят в дебри, которые далеки от народа... в частности это статья и есть яркий пример хорошой работы, над определеннным направлением, абсолютно не дающая чего-то полезного другим... (за исключением хакерской братии.)
в любом случае считайте это чисто моим профисиональным мнением
простите за "бедный" русский (языки без компайлера мне редко удаються)
На будущее маленькое предложение:
— часто на рассмотрение поситителей выставляют набор тем из которых могут общим голосованием выбрать нужную
— потом автору (профи) даеться заказ на такую статью...
как на меня это профисиональный подход к теме обучения... конечно ни кто не запрещает вести что-то на подобии своей колонки, в которой постоянно рассматриваеться программинг под "пределенным углом". ( Bugs Slayer, Dr. GUI, etc.)
Хвала:
На сколько я вижу RSDN плавно перехоит в Профи лигу... собственный журнал (означает что есть команда которая этим постоянно занимаеться). Есть собственные проекты (народ заинтересован в инфе размещенной на сайте). и т.д. и т.п. Я хочу чтобы так дальше и шло!
В ru.net не хватает хороших профи сайтов.
Re: Физическая организация метаданных в исполняемых файлах .
Павел, спасибо за статью, хорошая. Приятно, что в России идут в ногу с современными технологиями. Я немного изучал предмет, о котором вы пишите, и мне кажется что документация дает достаточно хорошее представление о внутренних структурах .NET PE файлов. Говоря о документации, я имею ввиду ECMA спецификации — http://msdn.microsoft.com/net/ecma/. К примеру, у меня получилось написать парсер метаданных и IL дизассемблер, пользуясь только этими документами, пример программы можно посмотреть тут — http://www.winisp.net/virgo/mangler.htm.
--Иван http://blogs.gotdotnet.com/ivanmed
Re[2]: Физическая организация метаданных в исполняемых файла
Иван, благодарю за добрые слова. Вашу страничку уже посещал. Интересно. Кстати, заметил, что Ваш viewer разбирает некоторые файлы, на которых ILDasm "падает". Как говорится, мелочь, а приятно.
А при написании статьи я пользовался только ECMA-спецификациями и заголовочными файлами .NET Framework и Rotor'а. Грешен, люблю разбирать исходники.
С уважением,
Павел Румянцев
V>Павел, спасибо за статью, хорошая. Приятно, что в России идут в ногу с современными технологиями. Я немного изучал предмет, о котором вы пишите, и мне кажется что документация дает достаточно хорошее представление о внутренних структурах .NET PE файлов. Говоря о документации, я имею ввиду ECMA спецификации — http://msdn.microsoft.com/net/ecma/. К примеру, у меня получилось написать парсер метаданных и IL дизассемблер, пользуясь только этими документами, пример программы можно посмотреть тут — http://www.winisp.net/virgo/mangler.htm. V>--Иван V>http://blogs.gotdotnet.com/ivanmed
Re[2]: Физическая организация метаданных в исполняемых файла
Здравствуйте, AlexK, Вы писали:
AK>Здравствуйте, Павел Румянцев, Вы писали:
AK>Одного вот только не пойму — нахрен это надо знать???? свои фреймворки вроде никто писать не собираеться... а простому програмеру это обсолютно до фени, потому как на ни на что не влияет.
AK>Интересно — но безполезно!
Мне вот было интересно как интерпертируются те или иные таблицы, у меня есть своя интерпретация, в чем-то не совпадающая с этой интерпретацией.
Несколько имхо-дополнений —
1. В последнем Роторе содержатся комментарии кторые говорят что часть таблиц использоваться не будет.
2. Может быть я пропустил чего, но изначально для парсинга PE файла (в частности — таблиц метаданных)надо знать что за формат файла используется — tiny или fat.
3. Количество записей в таблице можно узнать вычислив по формату полей длину одной записи и поделив размер таблицы на нее, размер записи может также зависеть от формата tiny или fat.
Формат PE.Net файла вообще содержит в себе много всяких условностей, так как есть еще mixed images — содержащие managed и unmanaged код — его легко получить собрав managed С++ сборку не позаботившись о том чтобы она была 100% managed — unmanaged методы могут быть впихнуты компилятором через таблицы релокаций — об этом автор не упомянул,так как исследование mscorlib — это не все. Лучше всего исследовать 3 типа сборки — от VB.Net, C#, и managed C++ (для очистки совести можно еще и от компилятора Borland C#Builder привести). Наиболее соответствовать ECMA будут первые два типа (и Borland-вский).
Конечно до кода добраться можно и сделать его дизассемблинг тоже легко, но вот даже здесь есть темные пятна, так как managed метод тоже можно "спрятать" через таблицу релокаций.
Одна статья конечно мало чего дает заинтересованному читателю, тут стоит посвятить этому вопросу цикл статей, так как ответ на вопрос "легко ли добраться до кода методов" уже давно дан тем же самым ILDASM.
И я бы назвал бы структуру метаданных, содержащихся в PE.Net реляционной базой данных, которую можно проверить утилитой PEVerify на "правильность", правда тут тоже есть обход — можно выставить SkipVerification атрибут для ублажения этой утилитки. Так что интересно было бы поставить вопрос — насколько совместимы собранные тем или иным компилятором сборки с положениями ECMA. У меня напрашивается только один ответ — C# compiler это может.
Кстати в Роторе представлены несколько подходов по парсингу PE, самый неструктурированный — это в ILDASM. Оба подхода достаточно трудны для изучения.
WBR,
Harley
Re[3]: Физическая организация метаданных в исполняемых файла
Благодарю за комментарии. Однако, у меня есть несколько вопросов:
Здравствуйте, Harley, Вы писали:
H>2. Может быть я пропустил чего, но изначально для парсинга PE файла (в част-ности — таблиц метаданных)надо знать что за формат файла используется — tiny или fat.
О формате tiny и fat методов я написал. Но, честно говоря, о таких форматах файла ничего не знаю. Если есть возможность, укажите, пожулуйста, ссылку, где можно найти эту информацию. Самому искать не лень, просто нет времени.
H>3. Количество записей в таблице можно узнать вычислив по формату полей длину одной записи и поделив размер таблицы на нее, размер записи может также зави-сеть от формата tiny или fat.
Наверное, можно и так. Но число записей в каждой таблице определено и в мета-данных, не так ли?
H>Формат PE.Net файла вообще содержит в себе много всяких условностей, так как есть еще mixed images — содержащие managed и unmanaged код — его легко получить собрав managed С++ сборку не позаботившись о том чтобы она была 100% managed — unmanaged методы могут быть впихнуты компилятором через таблицы релокаций — об этом автор не упомянул,так как исследование mscorlib — это не все. Лучше всего исследо-вать 3 типа сборки — от VB.Net, C#, и managed C++ (для очистки совести можно еще и от компилятора Borland C#Builder привести). Наиболее соответствовать ECMA будут первые два типа (и Borland-вский).
Проверял ВСЕ сборки, которые оказались доступны. Сейчас ищу такие сборки, на которых мой Researcher "упадёт", то есть окажутся неправильными мои представления о формате PE-файла. Пока таковых не нашёл, но нашёл много интересного. В частности, заметил, что г. Рихтер в своей книге не совсем прав, когда говорит, что метаданные пи-шутся только в сегмент .text. По моим данным, в случае MC++ код пишется в сегмент .text, метаданные — в сегмент .rdata. Находил случаи, когда часть метаданных оказывалась в сегменте .data (ISysWrapper.dll). Других случаев просто не встречал. Если Вы встречали, пришлите, пожалуйста, мне эти файлы, ладно?
H>Конечно до кода добраться можно и сделать его дизассемблинг тоже легко, но вот даже здесь есть темные пятна, так как managed метод тоже можно "спрятать" через таблицу релокаций.
Недьзя ли привести пример? Интересно, как мой Researcher определит, где этот код находится?
H>Одна статья конечно мало чего дает заинтересованному читателю, тут стоит по-святить этому вопросу цикл статей, так как ответ на вопрос "легко ли добраться до кода методов" уже давно дан тем же самым ILDASM.
Ну, тут я не совсем согласен. С моей точки зрения, ILDasm специально написан так, чтобы, раскрыв внутренности, не раскрывать, как все эти внутренности расположены. Но, это только IMHO.
H>И я бы назвал бы структуру метаданных, содержащихся в PE.Net реляционной базой данных, которую можно проверить утилитой PEVerify на "правильность", правда тут тоже есть обход — можно выставить SkipVerification атрибут для ублажения этой ути-литки. Так что интересно было бы поставить вопрос — насколько совместимы собранные тем или иным компилятором сборки с положениями ECMA. У меня напрашивается только один ответ — C# compiler это может.
Не совсем понял, что Вы имеете в виду. ТОЛЬКО С#-компилятор это может? Если Вы имели в виду именно это, тогда я (на основе опыта, полученного при анализе массы файлов) согласен.
H>Кстати в Роторе представлены несколько подходов по парсингу PE, самый не-структурированный — это в ILDASM. Оба подхода достаточно трудны для изучения.
Какие ещё подходы имеются? Расскажите вкратце, Ок?
Ещё раз благодарю за отзыв.
С уважением,
Павел Румянцев aka OldDino
Re[4]: Физическая организация метаданных в исполняемых файла
H>> Так что интересно было бы поставить вопрос — насколько совместимы собранные тем или иным компилятором сборки с положениями ECMA. У меня напрашивается только один ответ — C# compiler это может.
OD>Не совсем понял, что Вы имеете в виду. ТОЛЬКО С#-компилятор это может? Если Вы имели в виду именно это, тогда я (на основе опыта, полученного при анализе массы файлов) согласен.
Насколько я понимаю, все компиляторы, пишущие PE через Reflection.Emit делают 100% verifiable файлы, совместимые с ECMA.
H>>Кстати в Роторе представлены несколько подходов по парсингу PE, самый не-структурированный — это в ILDASM. Оба подхода достаточно трудны для изучения.
OD>Какие ещё подходы имеются? Расскажите вкратце, Ок?
В gotdotnet.com есть пример, что-то вроде PEReaderWriter. Там даже реализация на C#/VB присутствует. Правда, код мне не очень понравился, грязновато как-то всё реализовано. Хотя, даже простенький аналог ILDasm'а есть.
... << RSDN@Home 1.1 beta 1 >>
Re[5]: Физическая организация метаданных в исполняемых файла
Здравствуйте, mihailik, Вы писали:
M>Насколько я понимаю, все компиляторы, пишущие PE через Reflection.Emit делают 100% verifiable файлы, совместимые с ECMA.
А такие вообще есть (в смысле чтобы пользовались эмитом)? И почему собственно из эмита нельзя задудить небезопасный код?
M>>Насколько я понимаю, все компиляторы, пишущие PE через Reflection.Emit делают 100% verifiable файлы, совместимые с ECMA.
AVK>А такие вообще есть (в смысле чтобы пользовались эмитом)?
JScript.NET из Rotor'а точно эмитом работает. Да, наверное, и VB через Emit. В Mono все компиляторы через Emit сделаны.
Не-эмитовские компиляторы бывают, наверное, только для скорости и какой-нибудь особой безопасности. Или просто Микрософт писал С#-компилятор, когда эмит ещё не существовал, а теперь переписывать лень. Это на них похоже
AVK>И почему собственно из эмита нельзя задудить небезопасный код?
Да, пожалуй, ты прав. Не обязательно он verifiable. Но уж совместимый с ECMA так наверняка.
AVK>Влад.
... << RSDN@Home 1.1 beta 1 >>
Re[7]: Физическая организация метаданных в исполняемых файла
Здравствуйте, mihailik, Вы писали:
M>JScript.NET из Rotor'а точно эмитом работает. Да, наверное, и VB через Emit. В Mono все компиляторы через Emit сделаны.
Компилятор VB был создан раньше Шарпового.
M>Не-эмитовские компиляторы бывают, наверное, только для скорости и какой-нибудь особой безопасности.
Для скорости и гибкости. На этом эмите оптимизациями заняться будет не просто.
M>Да, пожалуй, ты прав. Не обязательно он verifiable. Но уж совместимый с ECMA так наверняка.
Дык, мсил вроде как ECMA-совместим. Так что по барабану.
AVK>>Влад. M>
Интерестно. А что это за пласт информации, мне на тему VB.NET почти никаких Internals неизвестно.
M>>Не-эмитовские компиляторы бывают, наверное, только для скорости и какой-нибудь особой безопасности.
AVK>Для скорости и гибкости. На этом эмите оптимизациями заняться будет не просто.
Насчёт гибкости — это вряд ли. Reflection.Emit довольно удобен. Кроме того, Assembly и AssemblyBuilder родственники, что помогает при резолвинге членов. (В Mono C# это используют).
А с оптимизацией почему непросто? Оптимизации касаются только IL-инструкций в методах. Их можно хранить и оптимизировать отдельно, вписывая в MethodBuilder уже в конце, когда всё будет готово.
AVK>>>Влад. M>>
AVK>Что-то смущает?
AVK>VladD2
Кому цыферки ставить, вот в чём вопрос.
... << RSDN@Home 1.1 beta 1 >>
Re[9]: Физическая организация метаданных в исполняемых файла
Здравствуйте, mihailik, Вы писали:
M>Интерестно. А что это за пласт информации, мне на тему VB.NET почти никаких Internals неизвестно.
На МС был опубликован так сказать чат в котором пытали разриботчиков дотнета. Там орел из группы ВБ проговорился. Да и оно не странно. Все же компилятор ВБ был уже давно. Переделать его на дотнет было не так сложно. Другое дело, что Шпрповый компилятор тоже из Явы вышел (не на пустом месте).
M>Насчёт гибкости — это вряд ли. Reflection.Emit довольно удобен.
Эмит это нечто типа print-а или (если тебе ближе) WriteLine. А генерация промежуточного кода — это отдельная дисциплина. И удобнее держать этот код в массивах (чтобы манипулировать им по проще было).
M>А с оптимизацией почему непросто? Оптимизации касаются только IL-инструкций в методах. Их можно хранить и оптимизировать отдельно, вписывая в MethodBuilder уже в конце, когда всё будет готово.
Это означает двойную генерацию кода. Что плохо по соображениям скорости.
M>Кому цыферки ставить, вот в чём вопрос.
А тебе не терпится.
... << RSDN@Home 1.1 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Физическая организация метаданных в исполняемых файл
M>>Насчёт гибкости — это вряд ли. Reflection.Emit довольно удобен.
VD>Эмит это нечто типа print-а или (если тебе ближе) WriteLine. А генерация промежуточного кода — это отдельная дисциплина. И удобнее держать этот код в массивах (чтобы манипулировать им по проще было).
С кодом вопросов нет, массивы. А метаданные всё равно не оптимизируются. Классы — они и есть классы, методы тоже как прописаны так должны быть и реализованы.
M>>А с оптимизацией почему непросто? Оптимизации касаются только IL-инструкций в методах. Их можно хранить и оптимизировать отдельно, вписывая в MethodBuilder уже в конце, когда всё будет готово.
VD>Это означает двойную генерацию кода. Что плохо по соображениям скорости.
По соображениям скорости — да. А насчёт гибкости всё пучком.
Открываем mscorlib, смотрим в таблицу методов. Смотрим на тип данных поля Name — почему-то USHORT, хотя следующее поле Signature идёт через 4 байта. Меня сначала это обстоятельство напугало в таблице TypeDef: Name — USHORT, Namespace — ULONG.