65.9K
CodeProject 正在变化。 阅读更多。
Home

程序集操作和 C# / VB.NET 代码注入

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (192投票s)

2007 年 9 月 19 日

MIT

5分钟阅读

viewsIcon

958775

downloadIcon

25145

Reflexil 是一个程序集编辑器,可以作为 Reflector 或 JustDecompile 的插件运行。Reflexil 能够操作 IL 代码并将修改后的程序集保存到磁盘。Reflexil 还支持“即时” C#/VB.NET 代码注入。

最新版本

您始终可以在此处获取最新的 Reflexil 版本。

引言

ReflectorJustDecompile 是用于深入检查各种程序集以及将 IL 代码反编译为支持的 .NET 语言的优秀工具。但是,它们无法修改程序集的结构或 IL 代码。Reflexil 通过使用由 Jb EVAIN 编写的强大的 Mono.Cecil 库来实现这些修改。Reflexil 作为插件运行,特别针对 IL 代码处理。它通过提供完整的指令编辑器并允许 C#/VB.NET 代码注入来实现这一点,我们将在接下来的两个示例中进行演示。

演示应用程序

让我们使用一个非常简单的应用程序,它可以将两个数字相加

using System;
using System.Windows.Forms;

namespace ReflexilDemo
{
    public partial class DemoForm : Form
    {
        public DemoForm()
        {
            InitializeComponent();
        }

        private void ComputeAndDisplay(decimal x, decimal y)
        {
            MessageBox.Show(String.Format("{0}+{1}={2}", x, y, x + y));
        }

        private void DisplayResultButton_Click(object sender, EventArgs e)
        {
            ComputeAndDisplay(LeftOperand.Value, RightOperand.Value);
        }
    }
}

Reflexil Demo

Result

使用指令编辑器

使用指令编辑器,让我们通过调用重载的 MessageBox.Show 方法来更新 ComputeAndDisplay 方法体,该方法接受一个标题作为第二个参数来显示结果的模态窗口。为此,我们必须首先使用 ldstr 操作码将一个 string 参数推送到堆栈上。

Method editor

Create new instruction

然后,我们需要更新“call”指令,以使用先前创建的参数的重载方法 MessageBox.Show

Method editor

Edit existing instruction

Select a method

现在是保存我们的工作并测试修补后的程序集的时候了。

Screenshot - reflexil08new.png

我们的程序集现在正在使用重载方法和适当的参数。

Result

指令编辑器功能

指令编辑器支持 Mono.Cecil 中定义的所有操作码。以下操作数受支持:

  • 原始类型:byte、sbyte、int32、int64、single、double
  • 字符串
  • 指令引用
  • 多个指令引用(switch)
  • 参数或变量引用
  • 内部泛型类型引用
  • 使用浏览器选择合适元素的类型、字段或方法引用。此浏览器类似于 Reflector 的(延迟加载、图标等)。

可以理解的是,ReflectorReflexil 的对象模型不同步:对 IL 代码进行的更新不会影响 Reflector 的反编译窗口。ReflexilMono.Cecil 不执行对发出的代码的任何检查。唯一的约束是操作数类型与给定操作码的使用方式之间的协调性。对于那些觉得 IL 操作困难的人来说,以下示例展示了如何使用 C# 或 VB.NET 更新方法体。

使用 C#/VB.NET 代码注入

您可以使用配置窗体选择您喜欢的注入语言和输入/显示基数(二进制、八进制、十进制和十六进制)。

Configuration

让我们使用“全部替换为代码”功能来处理 ComputeAndDisplay 方法体。

Replace all with code

编译窗口使我们能够查看生成的 IL 代码。提供了对 Intellisense/Insight 的基本支持。

Injecting C#

我们可以用 VB.NET 语言再次执行此操作。请注意,在这种简单的情况下,我们获得了相同的 IL 代码(情况并非总是如此)。

Injecting VB.NET

让我们保存并测试修补后的程序集。

Result

C#/VB.NET 代码注入功能

代码使用 System.CodeDom 在单独的 AppDomain 中编译,以正确释放资源。编译后,指令会被提取,然后重新插入到原始方法体中。参数、变量、方法、字段和类型引用会被调整以匹配原始程序集。代码注入是有限的:无法引用原始方法所属类型的祖先类型中定义的字段或方法。您可以选择编译过程使用的目标框架。

方法属性编辑器

您可以轻松更新方法签名或更改其可见范围。您还可以更改返回类型。

Method attributes editor

方法参数(和变量)也是可编辑的。Reflexil 可以加载符号(支持 MDB 和 PDB 文件)以显示原始变量名。

Parameter attributes editor

异常处理程序

Reflexil 允许添加/更新/删除与方法体关联的异常处理程序。支持以下类型:

  • Catch
  • Filter(VB.NET 在 Try/Catch 块中的 Where 子句)
  • 最后
  • Fault

Edit exception handler

类型属性编辑器

与方法一样,您可以更改任何类型的可见范围。因此,您可以将先前 private 的类型公开给外界。

Type attributes editor

成员操作

Reflexil 能够重命名、删除或注入类、接口、结构、枚举、事件、字段、方法、构造函数、属性或程序集引用。

Injection

智能注入:注入一个新属性将生成一个字段、getter/setter 方法和 IL 代码。

Smart injection

资源编辑器

您可以注入和修改嵌入式资源、链接资源和程序集链接资源。提供了一个完整的十六进制编辑器来更新、导出或导入文件。

Resources editor

自定义属性编辑器

完全支持自定义属性。

Resources editor

程序集和程序集引用编辑器

使用程序集编辑器,您可以选择不同的入口点。

Assembly editor

您还可以更新有关标识的所有信息:版本、公钥、名称和区域性。请注意,您还可以修改任何引用的程序集,以便可以使用不同的版本。

Assembly editor

模块编辑器

使用模块编辑器,您可以简单地更改应用程序的类型(例如,将可执行程序集转换为 DLL 库)。

Module editor

已签名程序集支持

保存已签名程序集时,生成的程序集处于“延迟签名”状态。Reflexil 可以使用 SDK 工具来修复它。

Signed assembly

Reflexil 能够删除程序集强名称并更新引用程序集。您也可以通过程序集编辑器自行完成:删除公钥并将 HasPublicKey 标志设置为 false

Signed assembly

反混淆支持

Reflexil 能够通过 de4dot 删除混淆的代码。

Obfuscator search

支持 Babel NET、CliSecure、CodeFort、CodeVeil、CodeWall、CryptoObfuscator、DeepSea、Dotfuscator、dotNET Reactor、Eazfuscator NET、Goliath NET、ILProtector、MaxtoCode、MPRESS、Rummage、Skater NET、SmartAssembly、Spices Net 和 Xenocode。

Obfuscator found
Obfuscator cleaning

程序集验证器

使用程序集验证器(使用 .NET SDK 的 peverify.exe),您可以确定 IL 代码和关联的元数据是否满足类型安全要求。

Assembly verifier
Assembly verified

结论

Reflexil 完全基于 Mono.Cecil。有趣的是,Mono.Cecil 可以在没有运行时帮助的情况下加载程序集,因此没有资源释放约束和 AppDomain 隔离等问题。System.TypeMono.Cecil.TypeDefinition 之间没有关系,尽管它们都体现了 .NET 类型概念。如果我们想以编程方式重现我们的第一个示例(Show 重载),我们可以非常轻松地编写它,这要归功于 Mono.Cecil

更改日志

////////////////////////////////////////////////////////////////////////////////
// v1.6 - 17/01/2013 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - Optional ILMerged version to prevent unexpected Mono.Cecil assemblies.
	  
  upgrades:
    - de4dot 1.9.0 update. New deobfuscation support for CodeFort, CodeWall,
      ILProtector, MPRESS, Rummage.
    - Mono.Cecil 0.9.5.4 update.
    - ARM, WindowsRuntime and Module characteristics support.
        
  bugfixes:
    - Check customized Mono.Cecil assembly

////////////////////////////////////////////////////////////////////////////////
// v1.5 - 16/04/2012 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - deobfuscation support for Babel NET, CliSecure, CodeVeil, CryptoObfuscator
      DeepSea, Dotfuscator, dotNET Reactor, Eazfuscator NET, Goliath NET,
      MaxtoCode, Skater NET, SmartAssembly, Spices Net and Xenocode.
      Thanks to de4dot by 0xd4d!
	  
  upgrades:
    - Mono.Cecil update.
        
  bugfixes:
    - bugfix for "register for verification skipping" and delay signed assembly.
    - bugfix for "resign" and delay signed assembly.
      
////////////////////////////////////////////////////////////////////////////////
// v1.4 - 27/01/2012 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - custom attributes support.
    - assembly/module renaming.
    
  upgrades:
    - search the type tree with a regex like ^SerializableAttribute$.
    
  bugfixes:
    - fixed drag&drop issues with column headers.
    - fixed broken ExceptionHandler editor after Mono.Cecil 0.9.x migration.
    - fixed broken Variable editor after Mono.Cecil 0.9.x migration.
    - fixed assembly resolution issues, thanks to Douglas Drinka.
  
////////////////////////////////////////////////////////////////////////////////
// v1.3 - 24/08/2011 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - resource support (injection and alteration): Embedded resources, linked
      resources and assembly linked resources. Complete hex editor to update,
      export or import files.
    
  upgrades:
    - works both on Reflector 6.x and Reflector 7.x.
    
  bugfixes:
    - fixed assembly loading errors when using symbols and pdb file is not 
      available.

////////////////////////////////////////////////////////////////////////////////
// v1.2 - 07/03/2011 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - Reflexil is now MIT/X11 licensed
    - technical update: using customized Mono.Cecil/Light 0.9.x
    - technical update: using customized ICSharpCode.SharpDevelop.Dom.dll
    - technical update: using customized ICSharpCode.TextEditor.dll
    - technical update: using customized ICSharpCode.NRefactory.dll
    
  upgrades:
    - moved "Kind" and "Target Runtime" from Assembly to Module handler
    - better support for pdb and mdb files and strong name assemblies
    - complete support for PE32+ assemblies
    - less memory consumption
    - lazy loading of every metadata element
    - speed and optimizations
    - you can enable/disable cache settings for intellisense 
    - injection/compilation with version control: v2.0, v3.5, v4.0
    - new injection import process
    - added architecture support (I386, AMD64, IA64) in module definition
    - new attributes grouping
    
  bugfixes:
    - fixed PointerType/ArrayType/ReferenceType Cecil/Reflector code matching 
      (No data shown for methods with "ref" array parameters)
    - fixed crashes when attempting to replace all with code
      (Could not find a part of the path)
    - fixed type import when updating field, method, property or event
    - fixed extra random assembly reference when injecting/compiling

////////////////////////////////////////////////////////////////////////////////
// v1.1 - 28/04/2010 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - rename, delete or inject class/interface/struct/enum/event/field/method/
      constructor/property/assembly reference
    - smart injection : injecting a new property will generate a field, 
      getter/setter methods and IL code.
    - open architecture: Reflexil is now able to be used with Reflector,
      Cecil.Studio or anything able to convert an object model to Mono.Cecil
    - property editor (attributes, type, constant)
    - field editor (attributes, type, constant)
    - event editor (attributes, type)
    - assembly verifier (using peverify.exe from .NET SDK)
    
  upgrades:
    - interfaces and base type selection for type editor
    - Reflector/Mono.Cecil method matching

  bugfixes:
    - fixed framework version detection for Mono, initial patch by Robin Herbots
    - fixed constant handling with parameters
    - fixed InitLocals initialization for method bodies
    - fixed branch to self causes stack overflow, patch by Brien Sourceforge
    - fixed crash with unsupported assemblies
    - fixed grid refresh for method overrides 
    - fixed offset compute after code injection
    - fixed code injection/type matching with nested types
    - fixed const handling with parameters, fields and properties

////////////////////////////////////////////////////////////////////////////////
// v1.0 - 23/10/2009 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - proper configuration for code injection with .NET 3.5 compiled files
    - using up to date Mono.Cecil.Pdb (now fully managed)

  bugfixes:
    - fixed ArgumentOutOfRange with some compile errors (replace all with code)
    - fixed error CS0006: Metadata file '...' could not be found    
    
////////////////////////////////////////////////////////////////////////////////
// v0.9.1 - 30/04/2009 /////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - check if .NET Framework v3.5 is installed

  bugfixes:
    - some debug code was left, causing errors to users without "c:" drive.
    
  misc:
    - source code cleanup
  
////////////////////////////////////////////////////////////////////////////////
// v0.9 - 28/01/2009 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - instruction offset column
    - code editor intellisense 
    - region folding
    - insight window
    
  bugfixes:
    - assembly browser was only listening to mouse events
    - fix combobox rendering errors without visual themes
    
  misc:
    - source code cleanup
  
////////////////////////////////////////////////////////////////////////////////
// v0.8 - 25/05/2008 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - assembly reference editor (name, version, public key, token, hash) 
    - assembly name editor (entry point, assembly kind, framework version, name,
      version, public key, token) 
    
  upgrades:
    - 'unsafe' code generation support
    - reflector item handler
    
  bugfixes:
    - field reference fix after code injection
    - forms tabindexes
  
////////////////////////////////////////////////////////////////////////////////
// v0.7 - 17/01/2008 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - type attributes editor (sealed, semantic, layout, string format,
      visibility, ...) 
    - strong name remover

  upgrades:
    - sn.exe registry keys with framework 3.5
    - C# / VB.NET code generator
    
  bugfixes:
    - static field code generation
    - VB.NET 'Single' type alias code generation
    - C# / VB.NET keywords used as field/method/parameter names
    - main window flicker fix

////////////////////////////////////////////////////////////////////////////////
// v0.6 - 30/10/2007 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - symbol loading support (pdb and mdb)
    - method attributes editor (member access, vtable layout, code type,
      managment, calling convention, return type) -> so you can change a method
      visibility
    - parameter editor -> so you can change a method signature
    - variable editor

  upgrades:
    - multiple selection support in grids
    - method RVA tooltip in grids
    - assembly / method definition cache system

  bugfixes:
    - namespaces with type browser
    - pointer type matching
    - method matching
    - generic type matching
    - remoting timeout with compilation window
    - Mono.Cecil import context update
    - VB.NET arrays
    - unsafe C# compilation setting
    - prevent "insert after/insert before" when a list is empty
    
////////////////////////////////////////////////////////////////////////////////
// v0.5 - 14/09/2007 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - VB.NET code injection
    - binary, octal, hexadecimal, decimal base support.
    - configuration form

  upgrades:
    - code injection is no more 'context-free': type, fields and methods can
      be referenced, and are automaticaly mapped to original items.
    - scroll positions are now saved when creating/updating/deleting
      instructions or exception handlers

  bugfixes:
    - injection code works even if the library is not in the same folder than 
      Reflector.
    - sn.exe (strong name utility) is correctly located even if PATH variable
      contains quotes.

////////////////////////////////////////////////////////////////////////////////
// v0.4 - 29/08/2007 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - exception handlers support.
    - exception handler drag&drop.
    - signed assembly support.

  upgrades:
    - Reflector bug report is sent to reflexil mailbox.

  bugfixes:
    - using non CLI images with Reflector.

////////////////////////////////////////////////////////////////////////////////
// v0.3 - 20/07/2007 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - instruction drag&drop.
    - delete all instructions.
    - C# code injection (preliminary support).

  upgrades:
    - opcodes autocomplete.

////////////////////////////////////////////////////////////////////////////////
// v0.2 - 08/07/2007 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

  news:
    - editors: type, method or field references.

  upgrades:
    - instruction edit form with opcodes descriptions (and grid tooltips).

////////////////////////////////////////////////////////////////////////////////
// v0.1 - 02/07/2007 ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

历史

  • 2007 年 9 月 19 日 - 文章发布
  • 2007 年 10 月 22 日 - 完整源代码下载已添加到文章
  • 2008 年 6 月 13 日 - v0.6、v0.7、v0.8 升级
  • 2009 年 1 月 29 日 - v0.9 升级
  • 2009 年 10 月 23 日 - v1.0 升级
  • 2013 年 4 月 26 日 - v1.1 至 v1.6 升级
© . All rights reserved.