我需要重写.NET文件中#US堆中的字符串。我决定使用dnlib,它看起来像一个强大的库来操作.NET文件。不幸的是,它的记录不足。
我以通常的方式加载文件。ModuleDefMD
Load()
方法似乎是加载文件的唯一方法:
ModuleDefMD module = ModuleDefMD.Load("test.dll");
现在,dnlib具有Writer
命名空间,这表明它应该用于写入.NET结构。它包含看起来很有前途的USHeap
类。
似乎Writer需要创建可以处理的元数据:
dnlib.DotNet.Writer.MetaData metadata = dnlib.DotNet.Writer.MetaData.Create(module, null, null, null);
在USHeap类中有一个SetRawData()
方法,其描述为"覆盖应该写入堆的值"。剩下的还不清楚,让我们无论如何都用它来写3个原始的任意字节。根据CLI标准,第一个有效偏移量为1:
byte[] raw_data = { 0x61, 0x62, 0x63 }; // "abc"
uint offset = 1; // the least valid offset in #US heap
metadata.USHeap.SetRawData(offset, raw_data);
dnlib示例显示如何编写文件:
module.Write("test-out.dll");
此代码编译并运行时没有出现错误。不幸的是,新文件与原始文件具有相同的#US流内容。
我似乎不知道这位作家是怎么工作的。研究源代码并不容易,因为dnlib由相当多的源文件和行组成。
dnlib文档引用了使用dnlib操作文件的ConfuserEx-模糊处理程序。然而,从其来源来看,它似乎根本没有操纵#US堆。
调用模块之前。Write(),初始化写入程序选项类。将侦听器设置为编写器侦听器,然后将选项传递给Write()。在某些编写器事件之后,您可以在将元数据写入文件之前开始操作元数据。然后,您可以将任意字符串添加到#US堆或任何其他堆中。
您可以查看以下示例:https://github.com/0xd4d/dnlib/blob/master/Examples/Example6.cs