我需要在.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 流内容。
看来我不明白 Writer 是如何工作的。研究源代码并不容易,因为 dnlib 包含相当多的源文件和行。
dnlib文档引用了ConfuserEx - 使用 dnlib 来操作文件的混淆器。然而,看看它的来源,它似乎根本没有操纵 #US 堆。