RUS_-_Karejev_-_Razrabotka_Windows-prilozhenij
.pdf
Результатом запуска этого приложения будет вывод на экран строки Hellow World — результата метода HelloWorld сборки
SimpleAssembly.dll.
Рассматриваемые листинги предельно просты. Тем не менее на диске, прилагаемом к книге, вы найдете приложения
SimpleAssembly и UsingLoadFrom (Code\Glava9\ SimpleAssembly и UsingLoadFrom).
Сборки со строгим именем
Обычные сборки могут быть без труда декомпилированы, и код в них может быть повторно использован. Для коммерческих приложений это недопустимо. Сборки, подписанные строгим именем, позволяют обеспечить безопасность, защиту кода, облегчить применение их в несколько приложениях, а также управлять версионностью сборок. Строгое имя является уникальным обозначением сборки. Оно гарантирует невозможность замены вашей сборки другой.
Строгое имя сборки включает в себя частное имя сборки, ее версию, открытый ключ для клиентского приложения и цифровую подпись безопасности. Если сборка была локализована, то в нее также войдет описание культуры локализации.
При компиляции сборки данные о ней помещаются в зашифрованный файл, ключ которого и представляет собой цифровую подпись. Открытый ключ хранится в этом же файле, и с его помощью клиентское приложение расшифровывает цифровую подпись.
Строгое имя сборки гарантирует ее уникальность и защиту от декомпиляции.
Сборка со строгим именем должна ссылаться только на сборку со строгим именем. Когда мы используем сборку, подписанную строгим именем, мы надеемся получить все преимущества подписанных сборок. Если же подписанная сборка ссылается на частную, то в первую очередь под угрозу ставится конфиденциальность приложения, кроме того, возможен конфликт версий частных сборок. В обычной жизни это похоже на использование банковского хранилища с бронированными стенами и дверями, но слабыми окнами.
Сборка со строгим именем может располагаться в любых местах — корневой папке приложения, произвольной папке локального или удаленного компьютеров, в Интернете.
Одни и те же сборки могут быть использованы в нескольких приложениях. Можно не дублировать эти сборки, а разместить их в так называемом глобальном КЭШе сборок (Global Assembly Cache) — централизованном хранилище сборок. В результате получается значительный выигрыш в размере приложения. В GAC может храниться несколько версий одной сборки, и он может управлять ими. Если сборку разместили в GAC, то она автоматически становится публичной — доступной другим приложениям. Если, напротив, использование подписанной сборки другими приложениями не требуется — достаточно поместить ее в корневую папку приложения.
Приложение, использующее строгую сборку, содержит информацию о ее строгом имени и версии. В результате достигается невозможность подмены сборки в корневой папке приложения: если просто заменить сборку на более новую, приложение не будет запускаться, поскольку строгое имя и версия сборок будут отличаться.
Создание сборки со строгим именем
В комплект поставки Microsoft Visual Studio .NET входят утилиты Microsoft .NET Framework Tools, применяемые для дополнительной работы с приложениями и компонентами. Файлы большинства утилит располагаются в каталоге С\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin. Описание со ссылками на дополнительные справочные ресурсы находится в в папке Bin в документе StartTools.htm. В этой и следующей лекциях мы рассмотрим работу с несколькими утилитами.
Создание сборки со строгим именем сводится к созданию закрытого ключа для шифрования хэш-кода сборки. Для этого используется утилита sn.exe. Непосредственный запуск из папки Bin не позволит приступить к работе — подобно прочим утилитам,
ее функции доступны из командной строки. Для запуска sn.exe из командной строки Windows1) указываем путь к каталогу и название (рис. 9.3).
увеличить изображение
Рис. 9.3. Запуск sn.exe из командной строки Windows
Более удобный способ работы с утилитами — использование командной строки Visual Studio .NET. Для ее запуска выбираем Пуск\Все программы\ Microsoft Visual Studio .NET 2003 \ Visual Studio .NET Tools \ Visual Studio .NET 2003 Command Prompt и просто вводим название утилиты (рис. 9.4):
sn.exe
увеличить изображение
Рис. 9.4. Запуск sn.exe из командной строки Visual Studio.NET
Далее мы будем использовать командную строку Visual Studio .NET. В любом случае появляется справка утилиты, которую затем снова можно вывести, набрав одну из команд:
sn.exe - ? sn.exe –h
Для создания закрытого ключа вводим команду (рис. 9.5):
sn.exe – k "Путь к папке для сохранения ключа\Название ключа.Расширение"
увеличить изображение
Рис. 9.5. Ключ StrongKey.snk был записан в указанную директорию
Вместо расширения key можно поставить любое другое. Расширением по умолчанию является .snk. После того как закрытый ключ создан, необходимо прикрепить его к приложению. В окне Solution Explorer проекта дважды щелкаем на файле AssemblyInfo.cs. Если Атрибут [assembly: AssemblyKeyFile("")] содержит путь к закрытому ключу, компилятор использует его для шифрования
данных (рис. 9.6).
Рис. 9.6. Использование атрибута [assembly: AssemblyKeyFile("")] для прикрепления ключа к приложению
Также с помощью атрибута [assembly] можно указать версию сборки, настройки культуры и другие параметры (рис. 9.7).
увеличить изображение
Рис. 9.7. Информация о сборке в атрибутах [assembly]
Сборки, подписанные строгим именем, добавляются в проект так же, как и обычные сборки. Для этого в окне Solution Explorer щелкаем правой кнопкой мыши на папке References и в появившемся контекстном меню выбираем пункт Add Reference… . По умолчанию окно Add Reference открывается на вкладке .NET, в которой нажимаем на кнопку Browse и выбираем сборку. В листинг текущего приложения добавляем пространство имен, применяемое в сборке, используя ключевое слово using. После компиляции сборка будет добавлена в проект.
Защита сборок. Утилита ilasm.exe
Главное преимущество использования сборок, подписанных строгим именем, — защита их от декомпиляции. Запустим снова утилиту ildasm.exe и откроем приложение, выводящее на экран строку Hello World — SimpleApp. В меню "Файл" выбираем пункт Dump (или просто нажимаем Ctrl+D). В появившемся окне Dump options оставляем значения без изменений и нажимаем OK. Называем новый файл SimpleAppCrack.il и сохраняем его При этом мы сохранили содержимое нашего приложения в виде кода MSIL. Закрываем утилиту ildasm.exe.
Открываем файл SimpleAppCrack.il с помощью блокнота и изменяем строку Hello World на Hello World Cracked (рис. 9.8).
увеличить изображение
Рис. 9.8. Изменение MSIL-кода
Сохраняем файл и закрываем его. Теперь нам нужно преобразовать MSIL код в исполняемый exe-файл. Для этого воспользуемся еще одной утилитой — ilasm.exe. В командной строке Visual Studio .NET набираем название утилиты и путь к файлу с MSIL-кодом
(рис. 9.9):
ilasm.exe Путь к файлу\файл.il
увеличить изображение
Рис. 9.9. Использование утилиты ilasm.exe для преобразования кода MSIL в исполняемый exe-файл
В папке с исходным файлом SimpleAppCrack.il появится файл SimpleAppCrack.EXE. Для просмотра его содержимого в командной строке указываем путь к нему и его название (рис. 9.10).
увеличить изображение
Рис. 9.10. Запуск измененного файла SimpleAppCrack.EXE
Скопируйте всю папку с приложением SimpleApp и назовите его ProtectedSimpleApp. Откроем приложение и подпишем сборку
строгим именем StrongKey.snk. Далее проделаем те же самые действия и попытаемся запустить измененный файл — появляется исключение System.IO.FileLoadExeption (рис. 9.11).
увеличить изображение
Рис. 9.11. Ошибка при попытке запустить измененную сборку, подписанную строгим именем
На диске, прилагаемом к книге, вы найдете приложение ProtectedSimpleApp (Code\Glava9\ ProtectedSimpleApp).
Утилита .NET Reflector. Как вскрывать защищенныесборки
При использовании утилиты ildasm.exe бросается в глаза аскетичный дизайн приложения и неудобство работы с ней. Невозможность изменения размеров информационной панели сборки, расположенной внизу программы, открытие блоков кода в отдельных окнах, отображение только MSIL-кода наводит на мысль, что разработчики среды .NET сознательно оставили минимальную функциональность приложения для сведения общения с ним пользователей к минимуму. Программа .NET Reflector (версия 4.1.84.0) — единственный существующий браузер классов .NET-компонент, позволяющий просматривать метаданные, ILинструкции и XML-документацию сборок, а также декомпилировать их, – гораздо более удобная утилита. Она имеет статус freeware, поэтому вы можете найти ее на диске, прилагаемом к книге, — Code\Glava9\ Reflector.zip, или скачать с сайта разработчика — http://www.aisto.com/roeder/dotnet. Рассмотрим, как просмотреть содержимое сборки, подписанной строгим именем, и использовать код в своих целях. Запустим программу, откроем пункт меню File\Open и выберем файл ProtectedSimpleAppCrack.EXE, который нам не удалось запустить (см. рис. 9.11). Выделив название сборки, на панели Disassembler увидим содержимое значение атрибутов [assembly] (если у вас не открыта панель Disassembler, выберите Tools/Disassembler) (рис. 9.12).
увеличить изображение
Рис. 9.12. Главное окно программы .NET Reflector, на панели Disassembler выведены значения атрибутов [assembly]
Обратите внимание на параметр AssemblyKeyFile панели Disassembler — мы действительно работаем со сборкой, подписанной
строгим именем! Каждый объект, отображаемый на панели, является ссылкой, щелкая на которую, мы переходим к соответствующему классу. Открыв окно Options — в пункте меню View\Options, можно выбрать язык отображения объектов, что является своеобразным переводчиком (рис. 9.13)!
Рис. 9.13. Выбор языка в окне Options
Выбрав язык C# и перемещаясь по объектам любой сборки, можно копировать и вставлять код прямо в свой листинг (рис. 9.14).
увеличить изображение
Рис. 9.14. Представление кода сборки на языке C#
Утилита не имеет возможности сохранять изменения в сборках (по крайней мере, описываемая версия), но в большинстве случаев вполне достаточно просмотреть и при необходимости скопировать весь код или фрагмент.
Глобальный кэшсборок GAC (Global Assembly Cache). Утилита gacutil.exe
Глобальный кэш сборок (Global Assembly Cashe, GAC) — это хранилище сборок, одновременно используемых несколькими приложениями. Такие сборки называются публичными. GAC может содержать в себе несколько сборок, отличающихся друг от друга только версией. На вашем компьютере GAC находится в каталоге C:\WINDOWS\assembly (рис. 9.15).
увеличить изображение
Рис. 9.15. Глобальный кэш сборок, GAC
Все сборки, находящиеся в GAC, подписаны строгим именем — при установке сборки среда Common Language Runtime проверяет сборку на уникальность и сравнивает ее с другими, уже имеющимися сборками.
Управлять глобальным хранилищем сборок можно несколькими способами. Первый способ — с помощью утилиты gacutil.exe, файл которой располагается в папке C\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\ gacutil.exe. Для работы с ней, как и большинством других утилит в командной строке Visual Studio.NET, следует ввести
gacutil.exe
При этом появляется описание команд утилиты (рис. 9.16), среди которых нас интересуют всего три:
/i или –i: установка сборки в GAC;
/l или –l: вывод списка установленных сборок; /u или –u: удаление сборки.
увеличить изображение
Рис. 9.16. Запуск утилиты в командной строке Visual Studio .NET
Управление сборками при помощи утилиты gacutil.exe — не самый удобный способ. Более широкие возможности управления сборками предоставляет консоль MMC (Microsoft Management Console), для запуска которой в окне Выполнить (Run) набираем mmc (рис. 9.17).
Рис. 9.17. Запуск консоли MMC
В появившемся окне выбираем в меню "Консоль\Добавить или удалить оснастку …" (рис. 9.18).
Рис. 9.18. Добавление оснастки
Оснасткой называется основной тип инструментов, которые можно добавить на консоль. В данном случае оснасткой будет глобальный кэш сборок. В окне "Добавить\Удалить оснастку" нажимаем кнопку "Добавить" и в появившемся списке выбираем .NET Framework 1.1 Configuration (рис. 9.19).
Рис. 9.19. Добавление оснастки .NET Framework 1.1 Configuration
В открывшемся окне можно управлять сборками — добавлять их или удалять (рис. 9.20).
увеличить изображение
Рис. 9.20. Удаление сборки
Не удаляйте сборки, которые вам неизвестны, — вы можете нарушить работоспособность некоторых программ!
Настройка политики выполнения сборок и контроля версий
Консоль MMC предоставляет возможность настройки политики выполнения сборок и контроля версий. Рассмотрим практическое использование контроля версий сборок. Создайте новое консольное приложение и назовите его AssVersion. Полный листинг этого приложения:
using System; namespace LibVersion
{
///<summary>
///Класс для тестирования контроля версий сборок.
///</summary>
public class MyClass
{
///<summary>
///Метод, возвращающий текущую версию сборки.
///<summary>
///<returns></returns>
public static string GetString()
{
return "Version 1";
}
}
}
В файле AssemblyInfo.cs изменяем значения атрибутов [assembly:]:
//Жестко прописываем версию сборки
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyDelaySign(false)]
//Указываем закрытый ключ, созданный утилитой sn.exe [assembly: AssemblyKeyFile("C:\\StrongKey.snk")] [assembly: AssemblyKeyName("")]
При попытке скомпилировать приложение появляется ошибка — наше приложение не содержит точки входа:
Program 'D:\Code\Glava9\AssVersion\obj\Debug\
AssVersion.exe' does not have an entry point defined
Мы удалили метод Main, поэтому возникает это исключение при попытке создания консольного приложения. Нам нужно скомпилировать проект как класс библиотеки, для этого в окне Solution Explorer щелкаем правой кнопкой на названии проекта AssVersion и в появившемся контекстном меню выбираем пункт Properties. Изменяем свойство Output Type на значение Class
Library, закрываем окно свойств проекта и снова скомпилируем его.
Добавим теперь созданную сборку в GAC. В консоли MMC щелкаем правой кнопкой мыши на названии Assembly Cache и выбираем пункт Add… (рис. 9.21).
Рис. 9.21. Добавление сборки в GAC из консоли MMC
Переходим в папку bin/Debug и выбираем файл AssVersion.dll. В результате в списке сборок появляется добавленная сборка
AssVersion.dll (рис. 9.22).
увеличить изображение
Рис. 9.22. Добавленная сборка AssVersion.dll в списке GAC
Создадим теперь новое консольное приложение UsingMyClassFromGAC, которое будет ссылаться на эту сборку и использовать ее
метод. В окне Solution Explorer щелкаем правой кнопкой мыши на папке References и в появившемся контекстном меню выбираем пункт Add Reference (рис. 9.23).
Рис. 9.23. Добавление ссылки к проекту
В появившемся окне Add Reference нажимаем кнопку Browse и выбираем сборку AssVersion.dll из каталога AssVersion\bin\Debug\ AssVersion.dll. Подключаем пространство имен для использования этой сборки и вызываем ее метод:
using System;
//Подключаем пространство имен: using AssVersion;
namespace UsingMyClassFromGAC
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
//Получаем строку с помощью метода GetString string stringFromMethod = MyClass.GetString();
//Выводим строку на экран
Console.WriteLine(stringFromMethod);
}
}
}
Компилируем приложение и затем запускаем его из командной строки2) Visual Studio .NET (рис. 9.24).
увеличить изображение
Рис. 9.24. Результат запуска приложения UsingMyClassFromGAC из командной строки
Изменим теперь сборку AssVersion — возвращаемое методом значение — на Version 2:
public static string GetString()
{
return "Version 2";
}
Изменим файл AssemblyInfo.cs:
// Жестко прописываем новую версию сборки
[assembly: AssemblyVersion("2.0.0.0")]
Скомпилируем сборку и добавим ее в GAC. В результате в списке сборок появится две версии (рис. 9.25).
Рис. 9.25. Список сборок содержит две версии AssVersion — 1.0.0.0 и 2.0.0.0
Снова запустим приложение UsingMyClassFromGAC из командной строки. Результат не изменился, по-прежнему выводится текст
Version 1.
Перейдем теперь к настройке управления версиями сборок. В консоли управления .NET Framework 1.1 открываем вкладку
Configured Assemblies и выбираем задачу Configure an Assembly (рис. 9.26).
Рис. 9.26. Список задач на вкладке Configured Assemblies консоли управления .NET Framework 1.1
В открывшемся окне конфигурирования сборки (рис. 9.27) переключатель стоит по умолчанию на значении Choose an Assembly from the assembly cache, нажимаем кнопку Choose Assembly для перехода к списку сборок.
