2015-10-26 4 views
0

Я хотел бы спросить, возможно ли каким-либо образом ввести код C# в существующий * .exe файл, который также написан на C# без декомпиляции.Ввод и изменение исполняемого файла C#

Другими словами, я пытаюсь сделать «расширение» для уже существующей программы на C#, но я хотел бы изменить ее без каких-либо манипуляций с «базовым» кодом (файл. * Exe).

Есть ли способ сделать это? Или процесс декомпиляции, необходимый для изменения методов, классов базового кода и/или добавления расширений к нему и т. Д.?

+1

* Вы можете * редактировать код IL непосредственно без decompliling его в C#, редактирование C#, а затем перекомпилировать его, но шансы, что это будет сложнее * * для вас, а не проще. – Servy

+0

Вы просмотрели [Методы расширения] (https://msdn.microsoft.com/en-us/library/bb383977.aspx)? – Tim

+0

@Servy, редактирование IL все еще декомпилирует исполняемый файл. – Jetti

ответ

0

вы можете достичь этого, используя фреймы, такие как Mono.Cecil или Microsoft CCI project. Эти рамки позволяют вам читать & изменить/ввести IL. Но изучить эти рамки и использование IL-кодов нелегко.

Мысль о наличии библиотеки FluentIL, которая построена поверх Mono.Cecil, предоставляет C# -обертку для IL-кода. Он не декомпилирует сборку, а загружает ее, вводя сборку, может записывать/генерировать новую с помощью вложенного кода.

Вот пример, который я использовал для ввода «Код проверки нулей» в методах, где аргументы помечены в компиляции сборки проекта.

var assembly = AssemblyDefinition.ReadAssembly(SourceAssemblyPath); 
var module = assembly.MainModule; 

var q = from type in module.Types 
     from method in type.Methods 
     from parameter in method.Parameters 
     where parameter.HasCustomAttributes 
     from attribute in parameter.CustomAttributes 
     where attribute.AttributeType.FullName == NotNullAttribute.FullName 
     select new { Method = method, Parameter = parameter }; 

foreach (var item in q) 
{ 
    item.Method.InsertBefore() 
     .Ldarg(item.Parameter.Name) 
     .IfNull() 
      .Throw<ArgumentNullException>() 
     .EndIf(); 
} 

SourceAssemblyPath = SourceAssemblyPath.Replace("\\debug\\", "\\release\\"); 
assembly.Write(SourceAssemblyPath, new WriterParameters { WriteSymbols = false }); 
Смежные вопросы