14

I want to get my hands on an assembly by saving it to disc or reflect it at runtime. The assembly is generated dynamically in memory by third party.

Does anyone know how to do this?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Daniel
  • 8,133
  • 5
  • 36
  • 51

3 Answers3

3

Try this (found here):

byte[] dllAsArray;

using (MemoryStream stream = new MemoryStream())
{
    BinaryFormatter formatter = new BinaryFormatter();

    formatter.Serialize(stream, results.CompiledAssembly);

    dllAsArray = stream.ToArray();
}
Christopher Currens
  • 29,917
  • 5
  • 57
  • 77
Roboblob
  • 1,795
  • 1
  • 22
  • 27
  • This is true. You can also send them over the internet (through WCF for instance), cast it back to an Assembly on the other end and load it. Blew my mind. – gjvdkamp May 15 '13 at 12:59
  • Instead you could use File.ReadAllBytes on file that is stored on temp folder at time of compilation. – Akash Kava Mar 31 '14 at 06:58
  • 1
    Careful with accepting remotely sent assemblies. That can quickly become a big security issue. – Joseph Lennox Nov 13 '15 at 00:18
  • I know it's been quite some time since the last post, but I don't want to create yet another question about this. Where does the "results" come from - I'm having a hard time figuring out a class that supports a field/property named "CompiledAssembly"? – Scott Feb 06 '16 at 03:42
  • 2
    (You probably found it by now, but...) CSharpCodeProvider.CompileAssemblyFromSource produces a CompilerResults object that has the CompiledAssembly. The CSharpCodeProvider also has a CompilerParameters property that has GenerateInMemory/OutputAssembly properties to compile to memory or disk. I noticed that using the BinaryFormatter option above (in my particular sample case) only produces a file that is 175 bytes in size, yet compiling to disk creates a 9K file. The 9k one loads and the 175 byte one does not, so I can't recommend using the BinaryFormatter for created assemblies. – DanW Aug 30 '16 at 18:00
1

It's been a while since I did this, I'm guessing that the program that hands you the DLL uses CompilerParameters.GenerateInMemory=True.

Thing is however that the dll does actually get saved on disk in some temp folder for a brief while (while it runs or something... ) because that is how the C# compiler works (worked?).

I can remember this being an issue for me back then but I'm having trouble getting back the details now, gimme a sec. You can probablby find this out with ProcessExplorer or similar tools to see which files were saved/ touched.

gjvdkamp
  • 9,929
  • 3
  • 38
  • 46
0

You can do this using SOS in WinDbg.

The problem is finding the modules.

If you do get your hands on it, there is a 'SaveModule' command to dump the module/assembly to file.

Good luck :)

leppie
  • 115,091
  • 17
  • 196
  • 297
  • 1
    Well, talking about trying again, you can't SaveModule a «Run» only module :) – Jb Evain Dec 09 '09 at 09:54
  • @JB: this is from within WinDbg, I am not aware of such limitations. – leppie Dec 09 '09 at 10:40
  • That's what am saying. You can see the module with !DumpDomain, but you can't !SaveModule it. – Jb Evain Dec 09 '09 at 10:45
  • That's because you need the base address which is very difficult to find! http://blogs.msdn.com/debuggingtoolbox/archive/2007/07/02/windbg-script-extracting-base-address-and-image-name-from-a-method-call.aspx – leppie Dec 09 '09 at 12:38
  • 2
    The fact that you're not aware of the limitation doesn't make the limitation any less real. A dynamically created assembly doesn't have a module that you can interact with like any loaded PE module in windbg. They don't have a base address that you can use, and you can't dump them. – Jb Evain Dec 09 '09 at 13:34
  • @JB: thanks. I always thought it was possible. So how does MS debug dynamic assemblies? ;) – leppie Dec 09 '09 at 13:38
  • 3
    You can still debug dynamic assemblies (albeit you lose a bit of details and possibilities iirc). It's just that dynamic module are not in a PE shape that msdbg can dump until they're really saved to disk. They have their custom representation in the CLR. – Jb Evain Dec 09 '09 at 14:10