Программирование arrow .NET Framework arrow Инъекции CLR: замена методов во время выполнения

Инъекции CLR: замена методов во время выполнения

Оглавление

Многие из нас, наверняка, были заинтересованы в том, как работает универсальный язык CLR. Одной из наиболее интересных вещей является динамический компилятор JIT (Just In Time Compiler). Мы рассмотрим то, как JIT компилирует MSIL и создадим утилиту, которая позволяет программным образом заменить любой метод (JIT) другим во время выполнения. Мы также создадим отладочную утилиту, которая прехватывает JIT-вызовы и выводит в консоль информацию о диагноcnbrt.

Компилятор JIT

Microsoft Intermediate Language или MSIL (более известен как Common Intermediate Language (CIL)) является языком низшего уровня, типа ассемблера. Все языки .NET компилируются в MSIL (с некоторыми исключениями C++/CLI). Процессоры не могут выполнять MSIL напрямую (может, для .NET в будущем появится технология типа ARM Jazelle). Компилятор JIT используется для преобразования MSIL в машинный код. Метод будет скомпилирован единожды компилятором JIT, а CLR сохранит (кэширует) машинный код, который произведет JIT, для последующих вызовов.

Процесс компиляции должен быть очень быстрым, поскольку он происходит во время выполнения. Поскольку MSIL является языком низшего уровня, его система кодов операций с легкостью преобразуется в машинную специфическую систему кодов операций. Сам процесс компиляции использует кое-что под названием JITStub. JITStub - это блок вспомогательного машинного кода, которым обладает каждый метод. JITstub в исходной версии содержит код, который вызывает JIT для метода. После того, как метод будет скомпилирован при помощи JIT, JITstub будет заменен кодом, который вызывает машинный код, созданный JIT .
000EFA60 E86488D979       call        79E882C9  // До JIT.  Вызов метода JIT
000EFA60 E97BC1CB00       jmp         00DABBE0 // После JIT.  Переход к ассемблерному коду, созданному JIT
Каждый класс имеет таблицу методов. Таблица методов имеет адреса всех JITStub для методов класса. Таблица метода используется во время компиляции JIT для разрешения вспомогательного кода JIT. Метод, который уже был откомпилирован JIT, не будет включен в эту таблицу, машинный код, созданный JIT, вызовет адрес вспомогательного кода напрямую. Далее мы привели выходную информацию таблицы методов из SOS. Колонка entry содержит адреса кодов.
MethodDesc Table
   Entry MethodDesc      JIT Name
79371278   7914b928   PreJIT System.Object.ToString()
7936b3b0   7914b930   PreJIT System.Object.Equals(System.Object)
7936b3d0   7914b948   PreJIT System.Object.GetHashCode()
793624d0   7914b950   PreJIT System.Object.Finalize()
000efa60   00d77ce0      JIT ReplaceExample.StaticClassB.A()
000efa70   00d77ce8     NONE ReplaceExample.StaticClassB.B()
Также есть возможность вызвать компилятор JIT из управляемого кода без вызова самого метода. Метод System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod заставит JIT скомпилировать метод.


 
« Предыдущая статья   Следующая статья »


  • .NET Framework, Оптимизация сериализации в .NET
    Приводятся код и методы, позволяющие разработчикам оптимизировать сериализацию данных....
  • .NET Framework, Плавающая точка в .NET - часть 1: принципы и форматы
    Данная статья представит основные принципы арифметических операций с плавающей точкой: числовые форматы, точности и достоверность, погрешности округления. Также в статью включено обсуждение типов плавающей запятой в .NET....
  • .NET Framework, JIT-оптимизации
    Компилятор .NET Just-In-Time Compiler (JIT) считается многими одним из основных преимуществ производительности CLR по сравнению с JVM и другими управляемыми средами, которые используют двоичный код, скомпилированный компилятором JIT. ...
  • .NET Framework, Оптимизация запуска приложений .NET
    Ждать, пока приложение запустится, неприятно для многих пользователей, поэтому ускорение запуска приложений клиентов может значительно улучшить первое впечатление от вашей работы. И так как скорость запуска имеет значение, следует знать факторы, которые на нее влияют, чтобы избежать распространенных ошибок....
  • .NET Framework, Создание компилятора языка для .NET Framework
    Эксперты по компиляторам являются знаменитостями в компьютерном мире. Я видел, как Андерс Хейльсберг (Anders Hejlsberg) представлял презентацию на конференции разработчиков Professional Developers Conference и когда он сошел со сцены, его встретила целая орда мужчин и женщин, просящих поставить автограф на книгу, или сняться на фотографии вместе с ними. Люди, посвящающие свое время изучению и пониманию всех тонкостей лямбда-выражений, систем типов и языков сборки, кажутся своего рода носителями ...
  • .NET Framework, Маршалинг данных между управляемым и неуправляемым кодом
    Посмотрим правде в глаза: нет в мире совершенства. Мало кто при разработке использует только управляемый код. А между тем, тяжким грузом лежат устаревшие неуправляемые приложения, с которыми приходится мириться. Есть ли способ интегрировать проекты, в которых задействован как управляемый, так и неуправляемый код? Какой вид принимает этот способ: вызов неуправляемого кода из управляемого приложения или вызов управляемого кода из неуправляемого приложения?...
  • .NET Framework, IronPython как движок для макросов в .NET приложениях
    Подозреваю, многие из вас задумывались — как можно в .NET приложение добавить поддержку макросов — чтобы можно было расширять возможности программы без ее перекомпиляции и предоставить сторонним разработчикам возможность легко и просто получить доступ к API вашего приложения? В статье рассмотрено, как в качестве основы для выполнения макросов использовать IronPython — реализацию языка Python на платформе .NET....
  • .NET Framework, Xml сериализация в .Net Framework 2.0
    Xml широко используется в .Net приложениях, и .Net framework предоставляет богатые возможности по работе с Xml. Среди них: поддержка Xml DOM (System.Xml.XmlDocument), последовательное чтение - запись Xml, поддержка xPath и xQuery, поддержка XSLT, богатые возможности DataSet по работе с Xml и, наконец, Xml сериализация. ...