5

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

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

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

澄清一下:我无法访问通过 Assembly.Load() 加载程序集的初始字节数组。

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

谢谢你。

4

1 回答 1

1

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

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

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

Name   | Raw Size | Raw Address
.text  | 0x2000   | 0x400
.rsrc  | 0x400    | 0x2400
.reloc | 0x200    | 0x2800

在这种情况下,模块的大小是最大的原始地址加上相应的原始大小,即 0x2A00。

于 2012-07-13T06:36:55.290 回答