• Как работает декомпиляция в .Net или Java на примере .Net

    • Tutorial

    Сегодня хотелось бы поговорить про декомпиляцию приложений (все применительно к той же Java, да и любому языку с некоторыми допущениями и ограничениями, но поскольку сам я — .Net разработчик, примеры будут совсем немного MSIL'овизированы :) ).

    Для вводной, перечислю текущие средства декомпиляции в мире .Net:
    • JetBrains dotPeek (поддержка R# хоткеев, сервер символов)
    • Telerik JustDecompile (также не плохой, множество хоткеев)
    • RedGate Reflector (аналог dotPeek, но платный. Изначально был основным в мире .Net, но пока был бесплатным)
    • icsharpcode ILSpy (хороший, opensource. Полезен, когда вы сами пишете код, использующий Mono.Cecil, т.к. Это даст лучшее понимание его работы)
    • 9rays Spices .Net Decompiler
    • Dis# с функцией inplace editor

    Для программной декомпиляции:
    • Mono.Cecil (основной, самый крутой декомпилятор в мире .Net. На выходе получаете объектное «зеркало» содержимого сборки. Т.е. Максимально-упрощенно, без наворотов типа конвертации массива IL в DOM).
    • ICSharpCode.Decompiler (надстройка над mono.cecil, переводящая array[MSIL] в DOM, где есть циклы, switches и if'ы. Является частью SharpDevelop/ILSpy)
    • Harmony Core (аналогичное от меня, но сохраняющее информацию о символах. В среднем состоянии, не готова для прода, помощь приветствуется).


    А теперь, хотелось бы описать как они работают (вам же интересно, как работает машинка от JetBrains?). Чтобы как минимум понять, насколько это сложно: написать свой декомпилятор .Net сборки обратно в код на C#.



    Читать дальше →
  • Снимаем дамп объектов с памяти .Net приложения

      Продолжаем тему интересного на .Net, от чего мир Java будет посмеиваться (хотя у них это также возможно сделать), а приверженцы С++ говорить: «чего они только не сделают чтобы не учить C++».

      В данной заметке мы напишем по сути – простенькое ядрышко профилировщика памяти для платформы .Net, который будет снимать дамп с SOH кучи (а в перспективе и с LOH).

      Для написания статьи нам понадобится код из статьи Получение указателя на объект .Net и Ручное клонирование потока (измерение размера объектов).

      Наши цели на сегодня:
      • Научиться итерировать кучу .Net
      • Научиться находить начало кучи .Net
      • Попробовать сытерировать все объекты чужого домена.


      Ссылка на проект в GitHub: DotNetEx

      Читать дальше →
      • +23
      • 19k
      • 6
    • Семинар по анатомии .Net, Roslyn, CoreCLR, CoreFX, декомпиляции, хакерству



        Наверняка, прочитав заголовок, вы уже поняли, что речь идет про CLRium, который уже анонсирован в Москве (03-04 апреля) и Санкт-Петербурге(29-30 мая). Но теперь его оффлайн могут посетить жители города Екатеринбурга.

        CLRium — два вечера, время проведения которых подобраны так, чтобы не отвлекать людей от работы и от запланированных на выходные, развлечений и домашних хлопот. Это два вечера, на которых будет рассказано множество эксклюзивного материала, которого нет нигде.

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

        Темы семинара — хобби его авторов, не работа. Потому мы приготовили его с большой любовью к деталям и хотим рассказать максимально глубоко про все, что успели узнать.

        Чем мы еще выделяемся? Ценой! Всего за 2,000 можно сходить на семинар и, возможно, получить новое хобби, которое отогреет вас, как программиста и даст не один день беспрерывного кодинга нового расширения на Студию или копания в ядре CoreCLR.

        cool Полный список тем выступлений и ссылки на регистрацию — под катом
        Читать дальше →
        • +13
        • 5,9k
        • 2
      • Disposable ref structs в C# 8.0

        • Перевод

        Давайте посмотрим, что об этом сказано в блоге о предстоящих изменениях в С# 8.0 (версия Visual Studio 2019 Preview 2):


        «stack-only структуры появились в С# 7.2. Они чрезвычайно полезны, но при этом их использование тесно связано с ограничениями, например невозможностью реализовывать интерфейсы. Теперь ссылочные структуры можно очищать с помощью метода Dispose внутри них без использования интерфейса IDisposable».


        Так и есть: stack-only ref структуры не реализуют интерфейсы, иначе возникала бы вероятность их упаковки. Следовательно, они не могут реализовывать IDisposable, и мы не можем использовать эти структуры в операторе using:


        class Program
        {
           static void Main(string[] args)
           {
              using (var book = new Book())
              {
                 Console.WriteLine("Hello World!");
              }
           }
        }
        
        ref struct Book : IDisposable
        {
           public void Dispose()
           {
           }
        }

        Попытка запустить этот код приведёт к ошибке компиляции

        Читать дальше →
      • Оптимизация программ под Garbage Collector

          Не так давно на Хабре появилась прекрасная статья Оптимизация сборки мусора в высоконагруженном .NET сервисе. Эта статья очень интересна тем, что авторы, вооружившись теорией сделали ранее невозможное: оптимизировали свое приложение, используя знания о работе GC. И если ранее мы не имели ни малейшего понятия, как этот самый GC работает, то теперь он нам представлен на блюдечке стараниями Конрада Кокоса в его книге Pro .NET Memory Management. Какие выводы почерпнул для себя я? Давайте составим список проблемных областей и подумаем, как их можно решить.


          На недавно прошедшем семинаре CLRium #5: Garbage Collector мы проговорили про GC весь день. Однако, один доклад я решил опубликовать с текстовой расшифровкой. Это доклад про выводы относительно оптимизации приложений.


          Читать дальше →
          • +40
          • 8,6k
          • 4
        • Асинхронные Stream в C# 8

          • Перевод
          • Tutorial

          Функционал Async/Await появился в C# 5, чтобы улучшить скорость отклика пользовательского интерфейса и веб-доступ к ресурсам. Другими словами, асинхронные методы помогают разработчикам выполнять асинхронные операции, которые не блокируют потоки и возвращают один скалярный результат. После многочисленных попыток Microsoft упростить асинхронные операции, шаблон async/await завоевал хорошую репутацию среди разработчиков благодаря простому подходу.


          Существующие асинхронные методы значительно ограничены тем, что должны возвращать только одно значение. Давайте рассмотрим некий обычный для такого синтаксиса метод async Task<int> DoAnythingAsync(). Результатом его работы является некоторое одно значение. Из-за такого ограничения нельзя использовать эту функцию с ключевым словом yield и асинхронным интерфейсом IEnumerable<int> (чтобы вернуть результат асинхронного перечисления).


          Читать дальше →
        • Инструментарий для анализа и отладки .NET приложений

          • Перевод

          Заглянуть «под капот» кода или посмотреть на внутреннее устройство CLR можно с помощью множества инструментов. Этот пост родился из твита, и я должен поблагодарить всех, кто помог составить список подходящих инструментов. Если я пропустил какие-то из них, напишите в комментариях.


          Во-первых, я должен упомянуть, что хороший отладчик уже присутствует в Visual Studio и VSCode. Также существует множество хороших (коммерческих) профилировщиков .NET и инструментов мониторинга приложений, на которые стоит взглянуть. Например, недавно я попробовал поработать с Codetrack и был впечатлён его возможностями.


          Однако оставшийся пост посвящён инструментам для выполнения отдельных задач, которые позволят лучше понять, что происходит. Все инструменты имеют открытый исходный код.


          Читать дальше →
          • +50
          • 15,8k
          • 9
        • Инъекции MSIL кода в стороннюю сборку при помощи Mono.Cecil. Реализация принципов АОП в NET

          Введение


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

          Многие .NET разработчики знают, что для доступа к объектам чужой сборки можно использовать Reflection. С помощью типов из System.Reflection мы можем получить доступ ко многим объектам .NET сборки, просмотреть их метаданные, и даже использовать те объекты, доступ к которым ограничен (например, private методы чужого класса). Но использование Reflection имеет свои ограничения и главная причина этому — данные, с котороми вы работаете через Reflection, все еще считаются кодом. Таким образом, вы, к примеру, можете получить CodeAccessSecurity exception, если сборка, к которой вы пытаетесь применить Reflection, запрещает это. По этой же причине Reflection работает довольно медленно. Но наиболее важным для данной статьи является то, что стандартный Reflection не позволяет изменять существующие сборки, только генерировать и сохранять новые.

          Mono.Cecil


          Качественно иной подход предлагает бесплатная библиотека с открытым исходным кодом Mono.Cecil. Главное отличие подхода Mono.Cecil от подхода Reflection в том, что данная библиотка работает с NET сборкой как с потоком байт. При загрузке сборки, Mono.Cecil разбирает PE заголовок, CLR заголовок, MSIL код классов и методов и т.д. работая напрямую с потоком байтов, представляющим сборку. Таким образом, с помощью данной библиотеки можно как угодно (в пределах предусмотренного) изменять имеющуюся сборку.
          Читать дальше →
        • На спор: прочитав до конца, вы поймёте, как и почему именно так работает GC

            Скажу сразу: я никогда не жду развёрнутого ответа на этот вопрос на собесах. Это глупо и в моем случае — эгоистично. Однако, на мой взгляд, помимо общего интереса к платформе, знать, как он работает очень полезно, т.к. это снимает целый ряд вопросов. Например, исключает вариант, когда разработчик считает, что Dispose вызывается автоматически и вызывать его самому не надо. Или же если разработчик более опытен, помогает ему автоматически, на уровне мышечной памяти писать код, приводящий к наименьшему количеству проблем.


            Другой вопрос, что мне субъективно не очень нравится, как объясняется его работа. Потому, предлагаю альтернативный подход, описанный в моей книге, .NET Platform Architecture.


            Если мы с вами будем досконально разбираться, почему были выбраны именно эти два алгоритма управления памятью: Sweep и Compact, нам для этого придётся рассматривать десятки алгоритмов управления памятью, которые существуют в мире: начиная обычными словарями, заканчивая очень сложными lock-free структурами. Вместо этого, оставив голову мыслям о полезном, мы просто обоснуем выбор и тем самым поймём, почему выбор был сделан именно таким. Мы более не смотрим в рекламный буклет ракеты-носителя: у нас на руках полный набор документации.


            Спор взаимовыгоден: если будет не понятно, я подправлю не ясные моменты в книге, маленькой частью которой является данный текст.


            Читать дальше →
          • Unsafe.AsSpan: Span<T> как замена указателям?


              C# — невероятно гибкий язык. На нем можно писать не только бэкэнд или десктопные приложения. Я использую C# для работы, в том числе, и с научными данными, которые накладывают определенные требования на инструменты, доступные в языке. Хотя netcore захватывает повестку дня (учитывая, что после netstandard2.0 большинство фич как языков, так и рантайма, не бэк-портируются в netframework), я продолжаю работать и с легаси-проектами.


              В этой статье я рассматриваю одно неочевидное (но, наверное, желаемое?) применение Span<T> и отличие реализации Span<T> в netframework и netcore из-за особенностей clr.

              Добро пожаловать под кат
            • Подробно о dynamic: подковерные игры компилятора, утечка памяти, нюансы производительности

                Прелюдия



                Рассмотрим следующий код:

                //Any native COM object
                var comType = Type.GetTypeFromCLSID(new Guid("E13B6688-3F39-11D0-96F6-00A0C9191601"));
                
                while (true)
                {
                    dynamic com = Activator.CreateInstance(comType);
                
                    //do some work
                
                    Marshal.FinalReleaseComObject(com);
                }


                Сигнатура метода Marshal.FinalReleaseComObject выглядит следующим образом:

                public static int FinalReleaseComObject(Object o)


                Создаем простой COM-объект, выполняем какую-то работу и тут же его освобождаем. Казалось бы, что может пойти не так? Да, создание объекта внутри бесконечного цикла — не очень хорошая практика, но GC возьмет на себя всю грязную работу. Реальность оказывается несколько иной:



                Чтобы понять, почему утекает память, нужно разобраться в том, как работает dynamic. На Хабре уже есть несколько статей на эту тему, например эта, но они не углубляются в детали реализации, так что проведем собственное исследование.

                Читать дальше →
                • +23
                • 6,3k
                • 1
              • Как я провел лето с C# 8

                  В недавнем выпуске подкаста DotNet & More Blazor, NetCore 3.0 Preview, C#8 и не только мы лишь вскользь упомянули такую животрепещущую тему, как C#8. Рассказ об опыте работы с C# 8 был недостаточно большим, что-бы посвящать ему отдельный выпуск, так что было решено поделиться им средствами эпистолярного жанра.


                  В данной статье я бы хотел рассказать о своем опыте использования C#8 на продакшене в течение 4 месяцев. Ниже Вы сможете найти ответы на следующие вопросы:


                  • Как "пишется" на новом C#
                  • Какие возможности оказались действительно полезными
                  • Что разочаровало
                  Читать дальше →
                • Nullable Reference типы в C# 8.0 и статический анализ

                    Picture 9


                    Не секрет, что Microsoft достаточно давно работает над выпуском восьмой версии C#. В недавно состоявшемся релизе Visual Studio 2019 новая версия языка (C# 8.0) уже доступна, но пока ещё только в качестве beta релиза. В планах этой новой версии есть несколько возможностей, реализация которых может показаться не совсем очевидной, или точнее, не совсем ожидаемой. Одним из таких нововведений стала возможность использования Nullable Reference типов. Заявленным смыслом данного нововведения является борьба с Null Reference Exception'ами (NRE).
                    Читать дальше →
                    • +30
                    • 9,2k
                    • 7