Basic I/O¶
Note
The documentation has a new home: Check it out!
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");
IPEFile 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¶
Building an image back to a PE file can be done manually by constructing a PEFile
, or by using one of the classes that implement the IPEFileBuilder
interface.
Note
Currently AsmResolver only provides a full fletched builder for .NET images.
Building a .NET image can be done through the AsmResolver.PE.DotNet.Builder.ManagedPEFileBuilder
class:
var builder = new ManagedPEFileBuilder();
var newPEFile = builder.CreateFile(image);
Once a PEFile
instance has been generated from the image, you can use it to write the executable to an output stream (such as a file on the disk or a memory stream).
using (var stream = File.Create(@"C:\mynewfile.exe"))
{
var writer = new BinaryStreamWriter(stream);
newPEFile.Write(writer);
}
For more information on how to construct arbitrary PEFile
instances for native images, look at PE File Building.
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);