Всем привет!
В этой теме Вы увидите как можно работать с библиотекой Mono.Cecil. - Данная библиотека работает только с исполняемыми файлами (.exe, .dll)
Установить данную библиотеку можно через Nuget
Описание классов и методов и.т.п:
Он содержит информацию о сборке, такую как имя, версия и токен открытого ключа, а также список модулей и ссылки на другие сборки.
Он также содержит корень древовидной структуры, содержащей все типы и элементы, определенные в сборке, а также методы, поля и свойства этих типов.
Этот класс также позволяет изменять содержимое сборки, предоставляя методы для добавления, удаления и замены типов, элементов и ссылок.
В этом режиме библиотека
В классе
Он принимает два параметра: имя и путь, по которому необходимо сохранить созданную сборку, а также принимает параметр для настройки атрибутов сборки и других параметров.
После создания сборки вы можете добавлять модули и типы в эту сборку, используя различные методы библиотеки.
или можно по аналогичной схеме сделать так:
Через Linq
Описание атрибутов и.т.д:
*
Она представляет собой набор пар имен и значений, которые передаются в качестве параметров для инициализации объекта.
*
Для значений могут быть использованы любые поддерживаемые цецильными типы, включая строки, массивы и перечисления. Для этого типа используется тип
*
*
*
*
Они предоставляют дополнительные сведения о классах, методах, структурах, перечислениях, интерфейсах и полях.
Они могут содержать информацию о происхождении кода, версиях, авторстве, и т.д.
*
Этот тип обычно используется для представления текстовых данных в других типах данных, таких как массивы и кортежи.
Список атрибутов можете найти в классе:
Вот общий список стандартных атрибутов сборки .NET:
Ну и по стандарту, нужно же сохранить как-то модифицированную сборку
В этой теме Вы увидите как можно работать с библиотекой Mono.Cecil. - Данная библиотека работает только с исполняемыми файлами (.exe, .dll)
Установить данную библиотеку можно через Nuget
Mono.Cecil — это библиотека, написанная на C#, которая предоставляет полную и точную, полнофункциональную библиотеку общего назначения для создания и проверки программ и библиотек в форме ECMA CIL.
Его можно использовать для различных задач, в том числе:
- Генерация сборок и модулей с нуля
- Генерация кода или данных, которые можно вставить в существующие сборки
- Проверка, анализ и модификация существующих сборок
- Декомпиляция существующих сборок и.т.д
Его можно использовать для различных задач, в том числе:
- Генерация сборок и модулей с нуля
- Генерация кода или данных, которые можно вставить в существующие сборки
- Проверка, анализ и модификация существующих сборок
- Декомпиляция существующих сборок и.т.д
DNlib и Mono.Cecil — это библиотеки, используемые для модификации сборок .NET.
Однако DNlib более легкий и предоставляет больше возможностей для модификации сборок .NET, чем Mono.Cecil.
В частности, DNlib имеет функции для добавления, удаления и редактирования метаданных, а также для сжатия, шифрования и подписи.
Он также поддерживает .NET Core, .NET Standard и .NET Framework, тогда как Mono.Cecil имеет ограниченную поддержку только .NET Framework.
Однако DNlib более легкий и предоставляет больше возможностей для модификации сборок .NET, чем Mono.Cecil.
В частности, DNlib имеет функции для добавления, удаления и редактирования метаданных, а также для сжатия, шифрования и подписи.
Он также поддерживает .NET Core, .NET Standard и .NET Framework, тогда как Mono.Cecil имеет ограниченную поддержку только .NET Framework.
Демонстрирую два варианта загрузки, 1- через ресурсы, 2-ой локально.
1)
2)
1)
C#:
// Сначала загружаем в память файл из ресурсов StubDnlib - это .exe файл
using System.IO.MemoryStream memoryStream = new(Properties.Resources.StubDnlib);
// Читаем сборку из памяти
using AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(memoryStream, new ReaderParameters(ReadingMode.Immediate));
C#:
// Путь до файла
string path = @"D:\Projects\MonoProject\bin\Debug\myFile.exe";
// Читаем сборку
using AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(path, new ReaderParameters(ReadingMode.Immediate));
Описание классов и методов и.т.п:
AssemblyDefinition— это класс в библиотеке Mono.Cecil, который используется для представления сборки .NET.Он содержит информацию о сборке, такую как имя, версия и токен открытого ключа, а также список модулей и ссылки на другие сборки.
Он также содержит корень древовидной структуры, содержащей все типы и элементы, определенные в сборке, а также методы, поля и свойства этих типов.
Этот класс также позволяет изменять содержимое сборки, предоставляя методы для добавления, удаления и замены типов, элементов и ссылок.
AssemblyDefinition.ReadAssembly() - используется для загрузки сборки из файла.ReaderParameters- Этот класс используется для предоставления внешней сборке набора параметров, используемых библиотекой Mono.Cecil для чтения сборки.ReadingMode.Immediate - этот параметр используется, когда требуется немедленный доступ к содержимому сборки.В этом режиме библиотека
Mono.Cecil будет читать сборку, как только ей будут переданы параметры, что обеспечивает быстрый доступ к содержимому.В классе
AssemblyDefinitionтак же существует ещё один метод CreateAssembly.AssemblyDefinition.CreateAssembly- это метод, который используется для создания новой сборки.Он принимает два параметра: имя и путь, по которому необходимо сохранить созданную сборку, а также принимает параметр для настройки атрибутов сборки и других параметров.
После создания сборки вы можете добавлять модули и типы в эту сборку, используя различные методы библиотеки.
C#:
// Читаем сборку
using AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(memoryStream, new ReaderParameters(ReadingMode.Immediate));
// Проверяем что в сборке есть атрибуты
if (assembly.CustomAttributes.Count > 0)
{
// Проходимся по циклу и ищим нужный нам атрибут, в данном случае TargetFrameworkAttribute
foreach (CustomAttribute attribute in assembly.CustomAttributes.Where(attribute => attribute.AttributeType.Name == "TargetFrameworkAttribute"))
{
// Заменяем значение атрибута на новую версию .NetFramework
attribute.ConstructorArguments[0] = new CustomAttributeArgument(assembly.MainModule.TypeSystem.String, ".NETFramework,Version=v4.6.2"); // обязательно: .NETFramework,Version=vВашаВерсия
assembly.EntryPoint.Module.RuntimeVersion = "v4.0.30319"; // "v4.0.30319"; // "v4.8.3928.0"
assembly.EntryPoint.Module.Runtime = TargetRuntime.Net_4_0; // Максимальная Net_4_0
}
}
C#:
// Перебираем все атрибуты
foreach (CustomAttribute list in assembly.CustomAttributes)
{
/* Вывести список атрибутов: $"{list.AttributeType.Name}\r\n" */
// Находим имя атрибута
if (list.AttributeType.Name.Contains("TargetFrameworkAttribute"))
{
// Заменяем на нашу переменную типа String
// через ветку реестра: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP - смотрим доступные версии .NetFramework, в случае не правильной версии, будет ошибка с уведомлением об установке новой версии пакета .NetFramework'a
list.ConstructorArguments[0] = new CustomAttributeArgument(assembly.MainModule.TypeSystem.String, ".NETFramework,Version=v4.6.2");
assembly.EntryPoint.Module.RuntimeVersion = "v4.0.30319"; // "v4.0.30319"; // "v4.8.3928.0"
assembly.EntryPoint.Module.Runtime = TargetRuntime.Net_4_0; // Максимальная Net_4_0
}
// и.т.д с остальными атрибутами.
}
C#:
// Находим атрибут "TargetFrameworkAttribute"
CustomAttribute attr = assembly.CustomAttributes.Where(c => c.AttributeType.Name == "TargetFrameworkAttribute").FirstOrDefault();
// Заменяем на новое значение
attr.ConstructorArguments[0] = new CustomAttributeArgument(attr.ConstructorArguments[0].Type, ".NETFramework,Version=v4.6.2");
// Так же применяем остальное
assembly.EntryPoint.Module.RuntimeVersion = "v4.0.30319"; // "v4.8.3928.0", "v2.0.50727.4927" и.т.д
assembly.EntryPoint.Module.Runtime = TargetRuntime.Net_4_0; // Максимальная Net_4_0
Описание атрибутов и.т.д:
*
ConstructorArguments- это коллекция аргументов, используемая для инициализации конструктора определенного объекта.Она представляет собой набор пар имен и значений, которые передаются в качестве параметров для инициализации объекта.
*
CustomAttributeArgumentпредставляет собой аргумент для атрибута класса. Возможны два типа аргументов: значения и типы.Для значений могут быть использованы любые поддерживаемые цецильными типы, включая строки, массивы и перечисления. Для этого типа используется тип
TypeReference.*
EntryPoint- это точка входа приложения*
RuntimeVersion- это версия общеязыковой среды выполнения (CLR), необходимая для запуска сборки. (Значение Runtime Version будет иметь вид «vX.X.XXXXX», где первые две цифры обозначают основной номер версии CLR, а вторые две цифры — дополнительный номер версии.)*
Runtime- это возвращает экземпляр среды выполнения, используемый для запуска программы.*
CustomAttributes- это атрибуты, которые можно применять к типам и конструкциям управляемого кода.Они предоставляют дополнительные сведения о классах, методах, структурах, перечислениях, интерфейсах и полях.
Они могут содержать информацию о происхождении кода, версиях, авторстве, и т.д.
*
MainModule.TypeSystem.String - это стандартный тип данных System.String в Mono.Cecil. Он используется для представления строковых констант в скомпилированном коде.Этот тип обычно используется для представления текстовых данных в других типах данных, таких как массивы и кортежи.
Список атрибутов можете найти в классе:
AssemblyInfo.cs или загрузив сборку в любой дизассемблер по типу: ILSpy, DnSpy и там смотреть список атрибутов.Вот общий список стандартных атрибутов сборки .NET:
CompilationRelaxationsAttribute - int
RuntimeCompatibilityAttribute - bool
DebuggableAttribute - enum
AssemblyTitleAttribute - string
AssemblyDescriptionAttribute - string
AssemblyConfigurationAttribute - string
AssemblyCompanyAttribute - string
AssemblyProductAttribute - string
AssemblyCopyrightAttribute - string
AssemblyTrademarkAttribute - string
ComVisibleAttribute - bool
GuidAttribute - Guid
AssemblyVersion - string
AssemblyFileVersionAttribute - string
TargetFrameworkAttribute - string
Значение архитектуры зависит от процессорной платформы, на которой был собран модуль.
Это может быть одна из следующих архитектур:
*
*
*
*
*
Флаг
Другими атрибутами, составляющими перечисление
*
*
*
*
*
*
*
Это может быть одна из следующих архитектур:
*
MSIL- это абстрактный процессор, предназначенный для интерпретации или трансляции в другую архитектуру;*
I386 (X86) - архитектура 32-разрядного процессора Intel;*
ARM- архитектура 32-разрядного процессора для мобильных устройств;*
IA64- архитектура 64-разрядного процессора Intel;*
AMD64- архитектура 64-разрядного процессора AMD.
C#:
// Читаем сборку
using AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(memoryStream, new ReaderParameters(ReadingMode.Immediate));
// Заменяем архитектуру процессора
assembly.MainModule.Architecture = TargetArchitecture.I386; // AnyCPU (предпочтительно 32-бит)
assembly.MainModule.Attributes |= ModuleAttributes.Required32Bit; // Устанавливаем нужный атрибут
ModuleAttributes.Required32Bit указывает, что для модуля требуется загрузка 32-разрядного образа, даже если процессор способен запускать 64-разрядный образ.Другими атрибутами, составляющими перечисление
ModuleAttributes, являются:*
ModuleAttributes.ILOnly — указывает, что модуль содержит только инструкции промежуточного языка (IL) и не содержит собственного кода.*
ModuleAttributes.Required — указывает, что модуль требует загрузки изображения.*
ModuleAttributes.StrongNameSigned — указывает, что модуль подписан подписью строгого имени.*
ModuleAttributes.Preferred32Bit — указывает, что модуль должен загружаться как 32-битный образ, даже если процессор способен запускать 64-битный образ.*
ModuleAttributes.PE32Plus — указывает, что модуль представляет собой 64-битный образ.*
ModuleAttributes.APTCA — указывает, что модуль является сборкой, подписанной Authenticode.*
ModuleAttributes.UnmanagedExport — указывает, что модуль содержит неуправляемые экспорты.Ну и по стандарту, нужно же сохранить как-то модифицированную сборку
C#:
assembly.Write("application.exe"); // Метод Write - сохраняет изменения перезаписывая файл.
Последнее редактирование: