Декомпиляция программы на C#
Можно ли после применения Net Reflector и получения исходного кода программы, использовать редактор формы, если декомпилируемой программой было WinForm приложение? Сейчас я не вижу редактор формы.
Отслеживать
user177221
задан 23 мая 2015 в 13:17
24.9k 13 13 золотых знаков 67 67 серебряных знаков 166 166 бронзовых знаков
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Обновление
Новая версия дизайнера Windows Forms (Visual Studio 2015) стала умнее, и разбирает код за вас (смотрите ответ @Sergey Rufanov).
В ней редактирование должно работать без дополнительных усилий. Что, кстати, очень сложно с точки зрения имплементации.
Оставшаяся часть ответа относится к старым версиям Visual Studio.
Декомпиляторы восстанавливают код — и только это является их задачей. Они не восстановят исходный код приложения, они лишь найдут исходный код, который будет компилироваться в такой же (или примерно такой же) файл. Вот обсуждение вопроса на форуме поддержки Рефлектора.
Они не восстанавливают внутреннюю структуру файлов, нужную для Forms Editor’а, не восстанавливают комментарии и имена внутренних переменных, не разбивают классы на partial-части, как этого хочет Windows Forms Editor.
Вам придётся разобраться, как устроен код, который требует Forms Editor, и привести декомпилированный код к этому виду вручную. Посмотрите, как справился с задачей Stephen Cleary, он описывает, какие изменения в коде проводил он.
Никто не говорил, что reverse engineering — лёгкая задача.
Общие сведения о триггерах UpdatePanel ASP.NET AJAX
При работе в редакторе разметки в Visual Studio вы можете заметить (от IntelliSense), что элемент управления UpdatePanel имеет два дочерних элемента. Одним из которых является элемент Triggers, который задает элементы управления на странице (или пользовательский элемент управления, если вы используете его), который активирует частичную отрисовку элемента управления UpdatePanel, в котором находится элемент .
Введение
Технология microsoft ASP.NET предоставляет объектно-ориентированную и управляемую событиями модель программирования и объединяет ее с преимуществами скомпилированного кода. Однако ее модель обработки на стороне сервера имеет несколько недостатков, присущих технологии, многие из которых можно устранить с помощью новых функций, включенных в расширения MICROSOFT ASP.NET 3.5 AJAX. Эти расширения обеспечивают множество новых функциональных возможностей клиента, включая частичную отрисовку страниц без полного обновления страницы, возможность доступа к веб-службам через клиентский скрипт (включая API профилирования ASP.NET) и обширный КЛИЕНТСКИй API, предназначенный для зеркало многих схем управления, которые можно увидеть в ASP.NET наборе элементов управления на стороне сервера.
В этом техническом документе рассматриваются функциональные возможности триггеров XML компонента ASP.NET AJAX UpdatePanel . Триггеры XML предоставляют детализированный контроль над компонентами, которые могут вызвать частичную отрисовку для определенных элементов управления UpdatePanel.
Этот технический документ основан на бета-версии 2 платформа .NET Framework 3.5 и Visual Studio 2008. Расширения ASP.NET AJAX, ранее сборка надстройки, предназначенная для ASP.NET 2.0, теперь интегрированы в библиотеку базовых классов платформа .NET Framework. В этом техническом документе также предполагается, что вы будете работать с Visual Studio 2008, а не Visual Web Developer Express, и предоставляет пошаговые руководства в соответствии с пользовательским интерфейсом Visual Studio (хотя списки кода будут полностью совместимы независимо от среды разработки).
Триггеры
Триггеры для заданного UpdatePanel по умолчанию автоматически включают все дочерние элементы управления, вызывающие обратную передачу, включая (например,) элементы управления TextBox со свойством AutoPostBack true. Однако триггеры также можно включить декларативно с помощью разметки; Это делается в разделе объявления элемента управления UpdatePanel. Хотя доступ к триггерам можно получить через Triggers свойство коллекции, рекомендуется регистрировать все триггеры частичной отрисовки во время выполнения (например, если элемент управления недоступен во время разработки) с помощью RegisterAsyncPostBackControl(Control) метода объекта ScriptManager для страницы в Page_Load рамках события . Помните, что pages не имеют отслеживания состояния, поэтому необходимо повторно регистрировать эти элементы управления при каждом их создании.
Автоматическое включение дочерних триггеров также можно отключить (чтобы дочерние элементы управления, создающие обратную передачу, не запускали автоматически частичные отрисовки), установив для ChildrenAsTriggers свойства значение false. Это обеспечивает максимальную гибкость при назначении конкретных элементов управления, которые могут вызывать отрисовку страницы, и рекомендуется, чтобы разработчик мог реагировать на событие, а не обрабатывать любые события, которые могут возникнуть.
Обратите внимание, что при вложенных элементах управления UpdatePanel, если параметру UpdateMode присвоено значение Условный, если активируется дочерний элемент UpdatePanel, а родительский — нет, то обновляется только дочерний элемент UpdatePanel. Однако при обновлении родительского элемента UpdatePanel также будет обновлен дочерний Элемент UpdatePanel.
Элемент
При работе в редакторе разметки в Visual Studio вы можете заметить (из IntelliSense), что элемент управления имеет два дочерних UpdatePanel элемента. Наиболее часто встречающимся элементом является элемент , который по сути инкапсулирует содержимое, которое будет храниться на панели обновления (содержимое, для которого мы включаем частичную отрисовку). Другим элементом является элемент , который задает элементы управления на странице (или пользовательский элемент управления, если вы используете его), который активирует частичную отрисовку элемента управления UpdatePanel, в котором .
Элемент может содержать любое число каждого из двух дочерних узлов: и . Они принимают два атрибута, ControlID и , и EventName могут указывать любой элемент управления в текущей единице инкапсуляции (например, если элемент управления UpdatePanel находится в пользовательском веб-элементе управления, не следует пытаться ссылаться на элемент управления на странице, на котором будет находиться пользовательский элемент управления).
Элемент особенно полезен тем, что он может нацелиться на любое событие из элемента управления, существующего как дочерний элемент любого элемента управления UpdatePanel в блоке инкапсуляции, а не только на UpdatePanel, под которым этот триггер является дочерним. Таким образом, можно сделать любой элемент управления для активации частичного обновления страницы.
Аналогичным образом, элемент можно использовать для запуска частичной отрисовки страницы, но для этого требуется полный круговой путь к серверу. Этот элемент триггера также можно использовать для принудительной отрисовки полной страницы, когда элемент управления в противном случае обычно активирует частичную отрисовку страницы (например, если элемент Button управления существует в элементе элемента управления UpdatePanel). Опять же, элемент PostBackTrigger может указать любой элемент управления, который является дочерним по отношению к любому элементу управления UpdatePanel в текущей единице инкапсуляции.
| Тег | Описание |
|---|---|
| Указывает элемент управления и событие, которые вызовут частичное обновление страницы для UpdatePanel, содержащего эту ссылку на триггер. | |
| Указывает элемент управления и событие, которое приведет к полному обновлению страницы (полного обновления страницы). Этот тег можно использовать для принудительного полного обновления, если элемент управления в противном случае активирует частичную отрисовку. |
Пошаговое руководство. Триггеры cross-UpdatePanel
- Создайте страницу ASP.NET с объектом ScriptManager, заданным для частичной отрисовки. Добавьте на эту страницу два элемента обновления UpdatePanels. В первом включите элемент управления Label (Label1) и два элемента управления Button (Button1 и Button2). Button1 должен иметь значение Click to Update Both (Нажмите, чтобы обновить оба), а Button2 — кнопку Click to Update This (Нажмите, чтобы обновить это) или что-то в этом направлении. Во втором UpdatePanel включите только элемент управления Label (Label2), но задайте для его свойства ForeColor значение, отличное от значения по умолчанию.
- Задайте для свойства UpdateMode обоих тегов UpdatePanel значение Условный.
Листинг 1. Разметка для default.aspx:
Untitled Page
- В обработчике событий Click для Button1 задайте для параметра Label1.Text и Label2.Text значение, зависящее от времени (например, DateTime.Now.ToLongTimeString()). Для обработчика событий Click для Button2 задайте только значение Label1.Text, зависящее от времени.
Листинг 2. Код программной части (обрезанный) в файле default.aspx.cs:
public partial class _Default : System.Web.UI.Page < protected void Button1_Click(object sender, EventArgs e) < Label1.Text = DateTime.Now.ToLongTimeString(); Label2.Text = DateTime.Now.ToLongTimeString(); >protected void Button2_Click(object sender, EventArgs e) < Label1.Text = DateTime.Now.ToLongTimeString(); >>
- Нажмите клавишу F5 для сборки и запуска проекта. Обратите внимание, что при нажатии кнопки Обновить обе панели обе метки изменяют текст; Однако при нажатии кнопки Обновить эту панель обновляется только Label1.

Под капотом
Используя только что созданный пример, мы можем взглянуть на то, что делает ASP.NET AJAX и как работают наши межпанельные триггеры UpdatePanel. Для этого мы будем работать с созданным html-кодом страницы, а также с расширением Mozilla Firefox с именем FireBug . С его помощью мы можем легко изучить обратные передачи AJAX. Мы также будем использовать инструмент .NET Reflector от Lutz Roeder. Оба этих средства находятся в свободном доступе в Интернете, и их можно найти с помощью поиска в Интернете.
Изучение исходного кода страницы не показывает почти ничего необычного; Элементы управления UpdatePanel отображаются в виде контейнеров, и мы видим, что ресурс скрипта включает в себя . Существуют также некоторые новые вызовы, относящиеся к AJAX, к PageRequestManager, которые являются внутренними для клиентской библиотеки сценариев AJAX. Наконец, мы видим два контейнера UpdatePanel — один с кнопками отображения с двумя элементами управления, отображаемыми в виде контейнеров. (Если проверить дерево DOM в FireBug, вы увидите, что метки неактивны, чтобы указать, что они не создают видимое содержимое.
Нажмите кнопку Обновить эту панель и обратите внимание, что в верхней части UpdatePanel будет обновлено текущее время сервера. В FireBug выберите вкладку Консоль, чтобы изучить запрос. Сначала изучите параметры запроса POST:

Обратите внимание, что UpdatePanel указал в коде AJAX на стороне сервера, какое дерево элементов управления было запущено с помощью параметра Button1 UpdatePanel1 ScriptManager1 элемента управления. Теперь нажмите кнопку Обновить обе панели. Затем, проверив ответ, мы увидим ряд переменных, разделенных каналом, заданных в строке; В частности, мы видим, что top UpdatePanel, , содержит полный html-код, UpdatePanel1 отправленный в браузер. Клиентская библиотека скриптов AJAX заменяет исходное HTML-содержимое UpdatePanel новым содержимым через .innerHTML свойство , поэтому сервер отправляет измененное содержимое с сервера в виде HTML.
Теперь нажмите кнопку Обновить обе панели и проверьте результаты с сервера. Результаты очень похожи : оба Элемента Обновления получают новый HTML-код с сервера. Как и при предыдущем обратном вызове, отправляется дополнительное состояние страницы.
Как мы видим, так как для обратной передачи AJAX не используется специальный код, библиотека клиентских скриптов AJAX может перехватывать обратные передачи форм без дополнительного кода. Серверные элементы управления автоматически используют JavaScript, чтобы не отправлять форму автоматически. ASP.NET автоматически внедряет код для проверки формы и состояния, в основном благодаря автоматическому включению ресурсов скрипта, классу PostBackOptions и классу ClientScriptManager.
Например, рассмотрим элемент управления CheckBox; проверьте дизассемблированное представление класса в отражателе .NET. Для этого убедитесь, что сборка System.Web открыта, и перейдите к классу System.Web.UI.WebControls.CheckBox , открыв RenderInputTag метод . Найдите условный объект, проверяющий AutoPostBack свойство :

Если для элемента управления включена CheckBox автоматическая обратная передача (с помощью свойства AutoPostBack имеет значение true), результирующий тег отображается с ASP.NET скриптом обработки событий в его onclick атрибуте. Таким образом, перехват отправки формы позволяет ASP.NET AJAX внедряться на страницу неинструзивно, что помогает избежать любых возможных критических изменений, которые могут произойти, используя замену строки, возможно, неточным. Кроме того, это позволяет любому пользовательскому элементу управления ASP.NET использовать возможности ASP.NET AJAX без дополнительного кода для поддержки его использования в контейнере UpdatePanel.
Функциональные возможности соответствуют значениям, инициализированным в вызове PageRequestManager для _updateControls (обратите внимание, что клиентская библиотека сценариев AJAX ASP.NET использует соглашение о том, что методы, события и имена полей, начинающиеся с символа подчеркивания, помечаются как внутренние и не предназначены для использования за пределами самой библиотеки). С его помощью мы можем наблюдать, какие элементы управления предназначены для обратной передачи AJAX.
Например, давайте добавим на страницу два дополнительных элемента управления, оставив один за пределами UpdatePanels, а один — в UpdatePanel. Мы добавим элемент управления CheckBox в верхнюю область UpdatePanel и удалите DropDownList с несколькими цветами, определенными в списке. Вот новая разметка:
Листинг 3. Новая разметка
Untitled Page
А вот новый код программной части:
Листинг 4. Код программной части
public partial class _Default : System.Web.UI.Page < protected void Button1_Click(object sender, EventArgs e) < if (cbDate.Checked) < Label1.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss"); Label2.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss"); >else < Label1.Text = DateTime.Now.ToLongTimeString(); Label2.Text = DateTime.Now.ToLongTimeString(); >> protected void Button2_Click(object sender, EventArgs e) < if (cbDate.Checked) < Label1.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss"); >else < Label1.Text = DateTime.Now.ToLongTimeString(); >> protected void cbDate_CheckedChanged(object sender, EventArgs e) < cbDate.Font.Bold = cbDate.Checked; >protected void ddlColor_SelectedIndexChanged(object sender, EventArgs e) < Color c = Color.FromName(ddlColor.SelectedValue); Label2.ForeColor = c; >>
Идея этой страницы заключается в том, что раскрывающийся список выбирает один из трех цветов для отображения второй метки, что поле проверка определяет, является ли он полужирным, и отображает ли метки дату и время. Поле проверка не должно вызывать обновление AJAX, но раскрывающийся список должен, даже если он не размещен в UpdatePanel.

Как видно на приведенном выше снимке экрана, последняя кнопка для нажатия была правильной кнопкой Обновить эту панель, которая обновила верхний момент независимо от нижнего времени. Дата также была отключена между щелчками, так как дата отображается в нижней метке. Наконец, интерес представляет цвет нижней метки: он был обновлен позднее, чем текст метки, который показывает, что состояние элемента управления важно, и пользователи ожидают, что оно будет сохранено с помощью обратной передачи AJAX. Однако время не было обновлено. Время автоматически повторялось за счет сохранения поля __VIEWSTATE страницы, интерпретируемого средой выполнения ASP.NET при повторной отрисовки элемента управления на сервере. Код сервера ASP.NET AJAX не распознает, в каких методах изменяется состояние элементов управления; он просто повторяется из состояния представления, а затем запускает соответствующие события.
Следует отметить, однако, что если бы я инициализировал время в рамках события Page_Load, время было бы правильно увеличено. Следовательно, разработчикам следует опасаться, что соответствующий код выполняется во время соответствующих обработчиков событий, и избегать использования Page_Load, когда обработчик событий элемента управления будет подходящим.
Итоги
Элемент управления UpdatePanel ASP.NET расширений AJAX является универсальным и может использовать ряд методов для определения событий элемента управления, которые должны привести к его обновлению. Он поддерживает автоматическое обновление дочерними элементами управления, но также может реагировать на события элементов управления в других местах на странице.
Чтобы уменьшить потенциальную нагрузку на серверную обработку, рекомендуется ChildrenAsTriggers задать свойству false UpdatePanel значение , а события должны быть выбраны, а не включены по умолчанию. Это также предотвращает ненужные события, которые могут вызвать потенциально нежелательные последствия, включая проверку и изменения полей ввода. Эти типы ошибок может быть трудно изолировать, так как страница обновляется прозрачно для пользователя, и поэтому причина может быть неясным.
Изучив внутреннюю работу модели после перехвата ASP.NET ajax, мы смогли определить, что в ней используется платформа, уже предоставляемая ASP.NET. При этом он сохраняет максимальную совместимость с элементами управления, разработанными на той же платформе, и минимально вторгается в любой дополнительный Код JavaScript, написанный для страницы.
Реверсинг .Net приложений. Часть 0
Перед вами первая статья из цикла «Реверсинг .Net приложений», в которой мы не будем работать с MSIL, не будем снимать пакеры и протекторы, и не встретимся с обфусцированным кодом. Всем этим мы займемся в будущих статьях, а пока мы пощупаем несколько основных инструментов и по традиции решим несложный крэкми.
Платформа .Net в текущем состоянии крайне уязвима:
1. Программы, написанные для .Net, компилируются не в native, а в байт-код платформы .Net, названный MSIL (MicroSoft Intermediate Language).
IL код компилируется непосредственно перед запуском. Такая технология получила название Just-in-time compilation (JIT, компиляция «на лету»).
2. Все программы содержат метаданные.
«Метаданные (metadata) — это данные, описывающие другие данные. В нашем контексте — это набор программных элементов ЕХЕ-файла, таких как типы и реализации методов.»
Именно благодаря метаданным, а точнее их особым свойствам в среде .Net мы можем с легкостью получить исходники программ.
2.1 Метаданные в .Net обязательны и универсальны.
«Каждая программа в среде .Net, помимо кода на языке MSIL обязательно содержит метаданные, описывающие как её в целом (манифест), так и каждый тип, содержащийся в ней.»
2.2 Метаданные в .Net общедоступны.
«Доступ к метаданным могут получить любые программные компоненты и любые инструменты программирования.»
2.3 Метаданные в .Net исчерпывающи.
«Метаданные содержат подробнейшую информацию о каждом типе: его имя, типы и имена его полей, описание свойств и методов со всеми их параметрами и возвращаемыми значениями. Здесь же хранится информация о доступности (видимости) всех членов класса и об их атрибутах. Метаданные хранят не только информацию о интерфейсе экспортируемых классов. Такие детали реализации, как структура защищённых полей, описания защищённых методов и других компонентов, также могут быть извлечены из метаданных.»
- .Net reflector
- Visual C# Express(или другая удобная для вас IDE)
- Минимальное знание любого ЯП с C-подобным синтаксисом, либо понимание «как оно там происходит»(для анализа и редактирования кода)
- DisSharp Decompiler (http://netdecompiler.com) — платный, в наличии деобфускатор, разработчики заявляют, что работает в несколько раз быстрее аналогов. Лично мне не понравился, хотя и справился с несколькими подопытными программами.
- Salamander .Net decompiler (http://www.remotesoft.com/salamander/) — может когда-то и был конкурентом рефлектору, но сейчас мы его отправим в архив, Change Log обрывается в начале 2008 года. Платный.
- Spices.Net Decompiler (http://www.9rays.net/Downloads.aspx) — единственный из нашего списка, способный потягаться с рефлектором. В наличии неплохой деобфускатор, оптимизатор кода, интеграция с VS и прочие плюшки. Минус — платный.
- Если вы по каким-то причинам не можете воспользоваться рефлектором, в вашем распоряжении несколько подобных программ, но будьте готовы к тому, что результат декомпиляции в каждой из них может отличаться.
Скачиваем архив с crackme. Внутри, помимо нужного нам файла, лежит readme.txt с «брифингом». Запускаем .Net reflector, далее File -> Open -> ReWrit’s Crackme #9 noob challenge.exe, после этого в поле программы появится открытый нами файл.

Далее ПКМ -> Disassemble, и мы почти у цели.

Как и заявлено разработчиком, reflector может с одинаковым успехом декомпилировать .net приложения на разные ЯП. Чтобы убедиться в этом, выделите любой метод, и в выпадающем списке смените C#, к примеру, на Delphi. Также reflector может быть использован для эффективной конвертации кода между C# и VB.Net.
Вернемся к нашему crackme, для достижения цели остался всего один шаг. ПКМ на ReWrits cm9 Noob Challenge -> Export…

Проект экспортирован без ошибок, но так бывает не всегда, в некоторых случаях рефлектор может потребовать недостающие файлы или библиотеки. В таком случае придется указать к ним путь вручную. Теперь запускаем IDE, в моем случае это Visual C# Express 2010, открываем экспортированный из рефлектора проект, студия предлагает преобразовать проект под текущую версию среды, соглашаемся. С ходу нажимаем F5 и вуаля, программа работает. В «боевых» условиях так бывает не всегда, то рефлектор неправильно экспортирует, то проект криво преобразуется в студии, то и вовсе в системе не хватает какого-то компонента. Но все это не имеет значения, если мы получили львиную долю исходного кода.
Итак, на этом основная часть статьи завершатся. Мы узнали, почему же так уязвима платформа .Net, познакомились с одним из множества способов получить исходный код программ, написанных для .Net, а также получили навыки работы с очень мощной утилитой .Net Reflector. Дальше идет необязательная часть, в которой будет решение трех уровней crackme, а оставшиеся два вам предстоит решить самостоятельно.
Теперь мы можем закрыть запущенный из студии крекми и вернуться к коду программы. Двойной щелчок по Form1.cs и неожиданно видим ошибку:

но нас это не пугает, нажимаем «Перейти к коду». Заостряем свое внимание на обработчиках нажатия кнопок, в них происходит все самое интересное. Обусловимся, что button’ы будем называть кнопками, textbox’ы — ТБ, а messagebox’ы так и оставим в покое. Запускаем оригинальный crackme, в нем мы будем проверять полученные решения, пока его свернем и вернемся к коду программы. Обработчик нажатия первой кнопки выглядит следующим образом:
private void button1_Click(object sender, EventArgs e)
string str = «486752416871754464»;
string str2 = «»;
while (str.Length > 0)
str2 = str2 + Convert.ToChar(Convert.ToUInt32(str.Substring(0, 2), 0x10)).ToString();
str = str.Substring(2, str.Length — 2);
>
if (this.textBox1.Text == str2)
this.Nag_Timer1.Start();
this.textBox2.ReadOnly = false;
>
else
MessageBox.Show(«Wrong Password!», «Error»);
>
>
Тут введенная нами строка после преобразования и некоторых операций сравнивается с изначально заданной строкой, которая также терпит преобразования. В случае их равенства стартует таймер нага и снимается атрибут readonly со следующего ТБ, во всех остальных — выскакивает messagebox с уведомлением о неправильном пароле. Заменяем MessageBox.Show(«Wrong Password!», «Error»); на MessageBox.Show(str2, «Error»); нажимаем F5, вводим что-нибудь в первый ТБ, нажимаем «Ок» и получаем messagebox с правильным паролем. Вводим его в ТБ измененной программы, нажимаем ок, после чего станет доступен второй ТБ. Но пока не спешим вводить пароль в свернутый оригинал crackme. В измененной программе тем временем стартует таймер, вызывающий наг.
Наг — назойливое окно, выскакивающее через определенный промежуток времени (либо при запуске), призывающее зарегистрировать программу. Встречается в основном в триальных программах и «шароварах».
У нас уже выскочило несколько нагов и пора бы их убрать. Не закрывая программу, смотрим на обработчик второй кнопки и видим прямое сравнение введенного текста с переменной, содержащей «0x7fffffff». Число в переменной указано в шестнадцатеричной форме, нам же нужна десятеричная запись этого числа. Можно воспользоваться стандартным калькулятором. Сначала перевести в режим «Программист»(в Win7 это так называется), нажимаем «Hex» вводим «0x7fffffff», тыкаем «Dec». 2147483647 и является паролем, который отключает наг и дает доступ к третьему ТБ. Третье задание предлагаю вам решить самостоятельно.
Надеюсь, что вы уже решили третье задание, значит мы можем продолжать. В readme сказано, что на четвертом уровне нам предстоит патчить файл, так и поступим. Смотрим обработчик четвертой кнопки, недолго думая, меняем «if (this.textBox6.Text == str2)» на if (this.textBox6.Text == «crack»), пароль для четвертого уровня — crack. Пятый вам предстоит решить самостоятельно.
На этом статья заканчивается, благодарю за внимание.
- реверсинг .net
- вскрытие .net приложений
Обратная инженерия с помощью Reflector. Часть 1
Целью данной работы было объяснить и научить вас сложным техникам обратной инженерии (в основном, с использованием Red Gate Reflector). В данной статье я шаг за шагом развею миф о невозможности дизассемблирования и взлома .NET файлов для получения конфиденциальной информации.
Автор: Ajay Yadav
- Red Gate Reflector
- .NET Framework 2.x version
- VC 2010 IDE
- ILDASM.exe (не обязательно)
Reflector относится к средствам дизассемблирования. Он разработан компанией Red Gate. Хотя раньше эта программа распространялась бесплатно, теперь разработчик коммерциализировал ее. Reflector используется для декомпиляции или дизассемблирования .NET файлов (к которым могут относиться как исполняемый файлы, так и DLL).
Функционал данной программы ограничен, и она может применяться только к файлам, созданным под CLR, она не сможет декомпилировать прочие неизвестные ей сборки. Но ограничение становится преимуществом, если мы можем легко предсказать фреймворк DLL или EXE. Если бинарный файл открыт или декомпилирован в Reflector IDE, тогда он является сборкой .NET.
Для профессионалов в сфере обратной инженерии Reflector имеет ряд преимуществ. Он предоставляет возможность по IL дизассемблированию. Открывать ILDASM.EXE отдельно нет необходимости. Он может быть интегрирован с Visual Studio 2010 или 2012 в качестве дополнения, которое может конвертировать декомпилированный код к другим языкам, поддерживаемым .NET, например VB.NET или Delphi. Мы можем запустить командную строку Visual Studio прямо из Reflector’а для тестирования или выполнения файла прямо из программы после декомпиляции сборки. И наконец, мы можем просмотреть декомпилированный код любого NET framework от версии 4.5 до 1.0.
После того, как вы скачаете и установите IDE, вы увидите нечто похожее:

Помимо описания преимуществ и возможностей, я бы хотел упомянуть об общем заблуждении, что Reflector не может редактировать исходный код или коды операций.NET. В отличие от других дизассемблеров (CFF, IDA pro или Ollydbg), он не может сохранять свой проект в качестве сборки, он может только декомпилировать. Что касается редактирования .NET-файлов, появляется необходимость в установке открытого дополнения в среду разработки Reflector’а. Можно найти много разных полезных дополнений, позволяющих, например, редактировать шестнадцатеричный код или коды операций. Изменения можно будет сохранить в отдельный файл.
В статье мы не будем полагаться на уже готовое ПО или прочие сторонние файлы для демонстрации дизассемблированного исходного кода. Вместо этого, мы разработали свое приложение.
Я назвал его «Champu» в честь домашнего питомца моего сына. Программу можно запустить, когда инициируется тест, и она будет работать в триальном режиме 15 дней. Это первая особенность, касающаяся безопасности. Второй же особенностью является то, что для доступа в приложение необходимо ввести имя пользователя, пароль и лицензионный ключ. Это позволяет защититься от пиратов. Начальное окно триальной версии выглядит следующим образом.

Пользователь может запустить ознакомительная версию, нажав кнопку «Continue». Далее вы должны будете задать имя пользователя и пароль.

Если пользователь захочет приобрести полную версию продукта, он должен перейти на сайт производителя и получить там лицензионный ключ. Этот ключ должен вводиться в следующем окне:

Вы спросите, есть ли другой способ получить полную версию, без оплаты? Да, обратная инженерия – лучший способ для взлома проприетарной программы.
Дизассемблирование.
Как можно заметить, в диалоговом окне кнопка «Continue» неактивна и показано сообщение об истечении пробного периода. У нас нет исходного кода программы, чтобы мы могли модифицировать его для получения полной версии. Остается только купить ключ…

Что ж, пришло время действовать! Все что у нас есть – это champu.exe, а большего нам и не надо. Запустим Reflector IDE и откроем в нем Champu.exe. Когда файл будет открыт, вы увидите следующий график. Мы знаем, что файл был создан с помощью .NET фреймворка, так как мы смогли его открыть.
Исполняемый файл автоматически преобразуется в соответствующие файлы исходного кода. В нем есть начальная информация о сборке, типе приложения, версии, криптографическом ключе, копирайте, GUID’е и используемом фреймворке.

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

Достаточно просто можно получить большое количество информации о программе. Далее кликнем правой кнопкой мыши по файлу champu.exe, и среда разработки предложит вам различные инструменты для работы, как, например, анализатор, ILDASM, командная строка и запуск приложения.

Можно заметить, что champu.exe содержит пространства имен, которое в свою очередь содержит классы C_Trial, Login и Register и статические классы Program и gData. Можно предположить, что данные классы реализуют весь функционал и ответственны за логику работы программы.
Сборка может содержать множество классов, и они будут содержать два разных типа реализованной логики. Таким образом, очень сложно определить точку входа для трассировки, но нам необходимо это сделать. Нужно кликнуть правой кнопкой мыши на champu.exe, а затем перейти по ссылке «Go To Entry Point». Справа отобразится функция сборки Main(), и будет загружен класс C_Trail.

Теперь мы определили точку входа – класс C_Trail, в котором реализована логика триального срока действия. Выбираем нужный класс в левой панели при раскрытии пространства имен Champu. Он позволит нам определить логику контроля лицензии, используемую в программе. Этот класс содержит два метода: RegisteredUser() и TrailCheck().

Перейдем в тело метода TrailCheck(). Здесь находится часть, отвечающая за логику триального периода. Можно понять, что программа будет работать 15 дней с 5.10.2013. Кроме того, в исходном коде мы можем найти сообщение об истечении пробного периода пользования программой.

Вот и код этого метода. Нельзя с уверенностью сказать о срабатывании основного условия. Выберем TrailCheck() в левой панели и воспользуемся анализатором. Здесь я покажу кое-какую полезную информацию, такую как условие срабатывания (On_Load()) и зависимости.

По умолчанию Reflector показывает код программы на C#. Некоторые программисты не очень хорошо знают этот язык, специально для них существует возможность изменить язык на другой, поддерживаемый .NET, например, VB.NET.

Если вы хотите изучить инструкции кодов операций MSIL, вы можете использовать соответствующий IL код. Использовать ILDASM нет необходимости.

Reflector также предоставляет возможность экспорта/импорта исходного кода в/из XML файла.

Иногда нам необходимо видеть состояние глобального кэша сборок – хранилища всех .NET сборок. Утилита GAC в Reflector предоставляет нам такую возможность, как показано ниже.

Данная статья показывает процесс дизассемблирования кода с помощью Reflector. Как уже говорилось ранее, эта программа не является средством изменения кода, она лишь проводит декомпиляцию для последующего анализа логики работы программы. Кроме того, в данной работе рассматриваются несколько возможностей Reflector’а, например экспорт/импорт сборки, GAC, анализатор, а также конвертация кода (очень полезная в ходе дизассемблирования особенность). Также в целях поиска интересующей нас информации был проанализирован класс C_Trail. В следующей статье мы проведем анализ остальных классов для последующего взлома приложения.