如何将受管.NET程序集从内存中保存为EXE/DLL文件

Fit*_*Dev 5 .net reflection .net-assembly

我想知道它是否尽可能,如果是这样 - 如何保存动态加载的.net程序集(它是从字节数组而不是文件加载)到磁盘上的文件(exe/dll取决于组件)和能够直接使用它(即,如果它是EXE,它包含所有exe头和可运或者至少是"可反射").

加载的程序集实际上也完全按照它们出现在文件中的方式存储在内存中,即所有PE EXE头文件,资源等,即内存中的exe/dll文件,或者它们以不同方式存储在内存中,因此它不会可以将一些内存区域保存为dll/exe .net程序集吗?也就是说,如果我可以使用图像中的类比:您可以将jpeg文件作为位图加载到内存中,其中表示内存中图像的实际字节将与表示jpeg文件的实际字节完全不同.加载组件也一样吗?

最后,我如何获得程序集实际位于进程内存中的内存地址(指针)?

只是为了澄清:我无法访问通过Assembly.Load()加载程序集的初始字节数组.

这是一个相关的问题,但是从答案中不清楚是否可能有一种方法将通过字节数组加载的程序集从内存转储到磁盘上的文件.

谢谢.

Kii*_*Kii 1

首先,在 .NET 中,程序集可以由物理上位于不同位置的多个模块组成。所以只能在程序集中保存一个模块。大多数时候你只需要主模块,这样你就可以使用Assembly.ManifestModule它来获取它。

Marshal.GetHINSTANCE将返回模块的 HINSTANCE,根据本文,这是模块的基地址。尽管 MSDN 中的注释指出内存模块没有 HINSTANCE,但该方法似乎确实返回内存模块的基地址。

现在我们有了模块的基地址。接下来要做的就是确定模块的大小。最简单的方法是解析PE 文件的节头。例如:

Name   | Raw Size | Raw Address
.text  | 0x2000   | 0x400
.rsrc  | 0x400    | 0x2400
.reloc | 0x200    | 0x2800
Run Code Online (Sandbox Code Playgroud)

在这种情况下,模块的大小是最大Raw Address加上相应的Raw Size,即0x2A00。