Существует ли API для проверки MSIL динамической сборки во время выполнения?

При использовании Reflection.Emit для сборки сборки во время выполнения я хотел бы проверить сборку MSIL перед сохранением на диск. Аналогично PEVerify, но во время выполнения. Есть ли такой API?


person Stephen Swensen    schedule 03.09.2011    source источник
comment
Я полагаю, вы не хотите просто выполнить PEVerify после сохранения на диск?   -  person i_am_jorf    schedule 03.09.2011
comment
@jeffamaphone - я бы предпочел этого избежать, но это мой запасной план!   -  person Stephen Swensen    schedule 03.09.2011


Ответы (4)


Похоже, что peverify.exe является внешним интерфейсом к c:\Windows\Microsoft.NET\Framework\v4.0.30319\peverify.dll (или c:\Windows\Microsoft.NET\Framework\v2.0.50727\peverify.dll). для CLR 2.0), которая является собственной библиотекой DLL (на самом деле, peverify.exe также является родной)

Я нигде не вижу, чтобы это было задокументировано, поэтому, вероятно, это не общедоступный API. Возможно, вы сможете выяснить экспортированные функции из этой DLL, используя что-то вроде Dependency Walker, но я думаю, что это проще просто вызвать peverify.exe.

РЕДАКТИРОВАТЬ: неофициальные свидетельства:

person Mauricio Scheffer    schedule 05.10.2011
comment
Аккуратно, спасибо за советы, Маурисио - я проверю это, когда у меня будет возможность, и сообщу вам, как это работает. - person Stephen Swensen; 05.10.2011
comment
Спасибо, Маурисио. У меня до сих пор не было возможности получить доступ к peverify.dll непосредственно во время выполнения, но, основываясь на ваших анекдотических свидетельствах, я думаю, что буду следовать подходу save assembly to disc -> run peverify.exe, даже если он немного неуклюж. Этого должно быть достаточно для начала, и я вернусь к использованию pverify.dll во время выполнения, если возникнет необходимость на практике. - person Stephen Swensen; 16.12.2011

Вместо использования PEVerify вы можете использовать декомпилятор ILSpy для внутрипроцессного решения, как описано здесь: http://www.codeproject.com/Tips/659692/Automated-MSIL-PE-verification-using-ILSpy

Краткое содержание статьи:

  1. Соберите соответствующие библиотеки DLL для ссылки из вашего тестового проекта или в этом случае из средства проверки IL во время выполнения.
  2. Повторите методы для проверки с помощью Mono.Cecil.
  3. Для каждого метода добавьте его в AstBuilder, определенный в ICSharpCode.Decompiler, который выполняет проверку. Например.
var context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType };
var astBuilder = new AstBuilder(context);
astBuilder.AddMethod(method);

С точки зрения производительности я не проверял, какой метод быстрее. Хотя этот метод является внутрипроцессным, он может быть медленнее, поскольку абстрактное синтаксическое дерево строится по мере проверки IL (мне придется настроить тест производительности, чтобы проверить эту теорию).

Я обнаружил, что декомпилятор ILSpy более надежен, чем PEVerify, как указано в статье выше, в одном случае PEVerify объявил одну сборку допустимой, в то время как ILSpy правильно выдал красивую трассировку стека, указывающую на мою ошибку в генерации.

person ilen    schedule 30.09.2013
comment
Спасибо за информацию, @ilen, мне обязательно нужно это изучить! - person Stephen Swensen; 30.09.2013
comment
@StephenSwensen, Вау, вы готовы реорганизовать код через 2 года ;) .. Я снова прочитал ваш вопрос и заметил, что в идеале вы хотели бы избежать сохранения на диск. Для этого вам нужно либо портировать Reflection.Emit на Mono-Cecil emit, либо написать какой-нибудь транслятор - person ilen; 30.09.2013
comment
Ха-ха, да действительно. Это для продолжающегося хобби-проекта, над которым я работал вчера вечером (code.google .com/p/nl-compiler), так что все дело в изучении и применении лучших методов, которые я могу найти. - person Stephen Swensen; 01.10.2013
comment
Я забыл подробности, но, кажется, я решил использовать Reflection.Emit вместо Mono-Cecil из-за ограничений, которые он имел при запуске динамических сборок в процессе (этого было недостаточно для создания интерактивного компилятора). - person Stephen Swensen; 01.10.2013

Отладка LCG позволяет отлаживать сгенерированный код во время выполнения с помощью Windbg.

Может быть, это может помочь вам.

person masoud ramezani    schedule 03.09.2011

Вызов peverify действительно, вероятно, лучший подход, но peverify находится во многих разных каталогах в зависимости от работающей версии .NET. Вы можете попытаться перечислить все эти пути и проверить последний, но это было как минимум 6 разных путей по последнему счету IIRC, и он не является кросс-платформенным, т.е. не включает моно.

Недавно я обнаружил, что могу просто создать ссылку на сборку Microsoft.Build.Tasks, а затем создайте экземпляр Microsoft.Build.Tasks.GetFrameworkSdkPath и вызовите свойство Path. Одно странное поведение, которое я заметил, заключается в том, что доступ к пути в первый раз вызывает исключение, но если вы просто проглотите это исключение, вы сможете получить доступ к пути с этого момента.

Затем Peverify.exe становится Path.Combine(new GetFrameworkSdkPath().Path, "bin\peverify").

person naasking    schedule 17.11.2012