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






4.95/5 (192投票s)
Reflexil 是一个程序集编辑器,可以作为 Reflector 或 JustDecompile 的插件运行。Reflexil 能够操作 IL 代码并将修改后的程序集保存到磁盘。Reflexil 还支持“即时” C#/VB.NET 代码注入。
最新版本
您始终可以在此处获取最新的 Reflexil
版本。
引言
Reflector 和 JustDecompile 是用于深入检查各种程序集以及将 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);
}
}
}
使用指令编辑器
使用指令编辑器,让我们通过调用重载的 MessageBox.Show
方法来更新 ComputeAndDisplay
方法体,该方法接受一个标题作为第二个参数来显示结果的模态窗口。为此,我们必须首先使用 ldstr
操作码将一个 string
参数推送到堆栈上。

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

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

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

指令编辑器功能
指令编辑器支持 Mono.Cecil
中定义的所有操作码。以下操作数受支持:
- 原始类型:byte、sbyte、int32、int64、single、double
- 字符串
- 指令引用
- 多个指令引用(switch)
- 参数或变量引用
- 内部泛型类型引用
- 使用浏览器选择合适元素的类型、字段或方法引用。此浏览器类似于 Reflector 的(延迟加载、图标等)。
可以理解的是,Reflector
和 Reflexil
的对象模型不同步:对 IL 代码进行的更新不会影响 Reflector
的反编译窗口。Reflexil
和 Mono.Cecil
不执行对发出的代码的任何检查。唯一的约束是操作数类型与给定操作码的使用方式之间的协调性。对于那些觉得 IL 操作困难的人来说,以下示例展示了如何使用 C# 或 VB.NET 更新方法体。
使用 C#/VB.NET 代码注入
您可以使用配置窗体选择您喜欢的注入语言和输入/显示基数(二进制、八进制、十进制和十六进制)。

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

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

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

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

C#/VB.NET 代码注入功能
代码使用 System.CodeDom
在单独的 AppDomain
中编译,以正确释放资源。编译后,指令会被提取,然后重新插入到原始方法体中。参数、变量、方法、字段和类型引用会被调整以匹配原始程序集。代码注入是有限的:无法引用原始方法所属类型的祖先类型中定义的字段或方法。您可以选择编译过程使用的目标框架。
方法属性编辑器
您可以轻松更新方法签名或更改其可见范围。您还可以更改返回类型。

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

异常处理程序
Reflexil
允许添加/更新/删除与方法体关联的异常处理程序。支持以下类型:
Catch
Filter
(VB.NET 在Try
/Catch
块中的Where
子句)最后
Fault
类型属性编辑器
与方法一样,您可以更改任何类型的可见范围。因此,您可以将先前 private
的类型公开给外界。

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

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

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

自定义属性编辑器
完全支持自定义属性。

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

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

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

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

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

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

支持 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。


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


结论
Reflexil
完全基于 Mono.Cecil
。有趣的是,Mono.Cecil
可以在没有运行时帮助的情况下加载程序集,因此没有资源释放约束和 AppDomain
隔离等问题。System.Type
和 Mono.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 升级