title: Rewriting string in .NET CLR heaps using dnlib
body: <p>I need to rewrite strings in #US heap in .NET file. I decided to use <a href="https://github.com/0xd4d/dnlib" rel="nofollow">dnlib</a> that looks like a powerful library to manipulate .NET files. It is underdocumented unfortunately.</p>
  
  <p>I load the file the usual way. The <code>ModuleDefMD</code> <code>Load()</code> methods seem to be the only way to load the file:</p>
  
  <pre><code>ModuleDefMD module = ModuleDefMD.Load("test.dll");
  </code></pre>
  
  <p>Now, the dnlib has <code>Writer</code> namespace that suggests it should be used to write to the .NET structures. It contains <a href="https://github.com/0xd4d/dnlib/blob/59281085c10dc6f0ef497893821c8a8629c81349/src/DotNet/Writer/USHeap.cs#L13" rel="nofollow"><code>USHeap</code> class</a> that looks promising.</p>
  
  <p>It seems the Writer needs to create metadata that it can work on:</p>
  
  <pre><code>dnlib.DotNet.Writer.MetaData metadata = dnlib.DotNet.Writer.MetaData.Create(module, null, null, null);
  </code></pre>
  
  <p>In the USHeap class there is <a href="https://github.com/0xd4d/dnlib/blob/59281085c10dc6f0ef497893821c8a8629c81349/src/DotNet/Writer/USHeap.cs#L154" rel="nofollow"><code>SetRawData()</code> method</a> with <a href="https://github.com/0xd4d/dnlib/blob/59281085c10dc6f0ef497893821c8a8629c81349/src/DotNet/Writer/IOffsetHeap.cs#L25" rel="nofollow">description</a> "Overrides what value should be written to the heap". The rest is unclear, let's use it anyway to write 3 raw arbitrary bytes. According to the CLI standard, the first valid offset is 1:</p>
  
  <pre><code>byte[] raw_data = { 0x61, 0x62, 0x63 };   // "abc"
  uint offset = 1;   // the least valid offset in #US heap
  metadata.USHeap.SetRawData(offset, raw_data);
  </code></pre>
  
  <p><a href="https://github.com/0xd4d/dnlib/tree/59281085c10dc6f0ef497893821c8a8629c81349/Examples" rel="nofollow">dnlib Examples</a> show how to write the file:</p>
  
  <pre><code>module.Write("test-out.dll");
  </code></pre>
  
  <p>This code compiles and runs without errors. Unfortunately the new file has the same #US stream contents as the original.</p>
  
  <p>It seems I didn't get the idea how the Writer works. Studying the sources is not easy as dnlib consists of quite a lot source files and lines.</p>
  
  <p>The <a href="https://github.com/0xd4d/dnlib" rel="nofollow">dnlib documentation</a> refers to <a href="https://github.com/yck1509/ConfuserEx" rel="nofollow">ConfuserEx</a> - obfuscator that uses dnlib to manipulate files. However, looking at its sources, it seems that it doesn't manipulate the #US heap at all.</p>