Table of Contents

Basic I/O

Every PE image interaction is done through classes defined by the AsmResolver.PE namespace:

using AsmResolver.PE;

Creating a new PE image

Creating a new image can be done by instantiating a PEImage class:

var peImage = new PEImage();

Opening a PE image

Opening an image can be done through one of the FromXXX methods from the PEImage class:

byte[] raw = ...
var peImage = PEImage.FromBytes(raw);
var peImage = PEImage.FromFile(@"C:\myfile.exe");
PEFile peFile = ...
var peImage = PEImage.FromFile(peFile);
BinaryStreamReader reader = ...
var peImage = PEImage.FromReader(reader);

If you want to read large files (+100MB), consider using memory mapped I/O instead:

using var service = new MemoryMappedFileService();
var peImage = PEImage.FromFile(service.OpenFile(@"C:\myfile.exe"));

On Windows, if a module is loaded and mapped in memory (e.g. as a native dependency or by the means of LoadLibrary), it is possible to load the PE image from memory by providing the HINSTANCE (a.k.a. module base address):

IntPtr hInstance = ...
var peImage = PEImage.FromModuleBaseAddress(hInstance);

Writing a PE image

To write a PE image, you first need to serialize it back into a PEFile using a IPEFileBuilder instance:

var newPEFile = peImage.ToPEFile(new ManagedPEFileBuilder());
var newPEFile = peImage.ToPEFile(new UnmanagedPEFileBuilder());

Depending on the type of PE image you will need a different type of PE builder. See PE File Building for more details.

Once a PEFile instance has been constructed from the image, it can be written to an output stream (as described in Writing PE files):

using var stream = File.Create(@"C:\mynewfile.exe");
newPEFile.Write(new BinaryStreamWriter(stream));

Strong name signing

If the PE image is a .NET image, it can be signed with a strong-name. Open a strong name private key from a file:

var snk = StrongNamePrivateKey.FromFile(@"C:\Path\To\keyfile.snk");

Make sure that the strong name directory is present and has the correct size.

image.DotNetDirectory.StrongName = new DataSegment(new byte[snk.Modulus.Length]);

After writing the PE image to an output stream, use the StrongNameSigner class to sign the image.

using Stream outputStream = ...

var signer = new StrongNameSigner(snk);
signer.SignImage(outputStream, module.Assembly.HashAlgorithm);