/AsmResolver

PE reader and editor. Native headers and resources, .NET metadata and disassemblers (x86 and msil).

Primary LanguageC#GNU Lesser General Public License v3.0LGPL-3.0

#AsmResolver Build status

AsmResolver is a PE inspection library allowing .NET programmers to read, modify and write executable files. This includes .NET as well as native native images. The library exposes high-level representations of the PE, while still allowing the user to access low-level structures.

AsmResolver is released under the LGPL license.

#Quick starters guide ##Reading an assembly Opening an assembly can be done by specifying a file path:

var assembly = WindowsAssembly.FromFile(@"C:\yourfile.exe");

... or passing a byte array:

var assembly = WindowsAssembly.FromBytes(File.ReadAllBytes(@"C:\yourfile.exe"));

... or using an instance of a IBinaryStreamReader:

var reader = new MemoryStreamReader(File.ReadAllBytes(@"C:\yourfile.exe"));
var assembly = WindowsAssembly.FromReader(reader);

##Writing an assembly Building an assembly can be done by using one of the WindowsAssembly.Write overloads:

assembly.Write(@"C:\yourfile.exe");
using (var stream = File.Create(@"C:\yourfile.exe"))
{
    assembly.Write(new BinaryStreamWriter(stream));
}
using (var stream = File.Create(@"C:\yourfile.exe"))
{
    var parameters = new BuildingParameters(new BinaryStreamWriter(stream));
    // ...
    assembly.Write(parameters);
}

Currently, AsmResolver only has an inbuilt .NET assembly writer, and therefore only .NET applications can be built at the moment. Support for native images will be added in the future.

##Disassembling x86 code Reading x86 code can be done using the X86Disassembler class.

var disassembler = new X86Disassembler(assembly.ReadingContext.Reader.CreateSubReader(start));

while (reader.Position < reader.Length)
{
    var instruction = disassembler.ReadNextInstruction();
    // ...
}

Disassembled instructions can be formatted into a readable text using an instance of an IX86Formatter.

var formatter = new FasmX86Formatter();
...
Console.WriteLine(formatter.FormatInstruction(instruction));

##Accessing .NET streams / heaps The WindowsAssembly class holds a property called NetDirectory, which exposes members representing .NET-specific structures and metadata.

Accessing the metadata streams can be done by using the MetadataHeader class:

var header = assembly.NetDirectory.MetadataHeader;
var streams = header.GetStreams();

Getting a specific metadata stream can be done using the GetStream(string) method.

var tableStream = (TableStream)header.GetStream("#~");
var blobStream = (BlobStream)header.GetStream("#Blob");

AsmResolver also provides an overload of the method GetStream<TStream>, which takes away the need of specifying the name and a type-cast.

var tableStream = header.GetStream<TableStream>();
var blobStream = header.GetStream<BlobStream>();

Adding a stream can be done by using the StreamHeaders property:

var header = assembly.NetDirectory.MetadataHeader;
var stream = new UserStringStream();
header.StreamHeaders.Add(new MetadataStreamHeader("#US", stream));

##Accessing metadata tables The metadata tables can be aquired using the TableStream.GetTable(MetadataTokenType) method.

var typesTable = (MetadataTable<TypeDefinition>)tableStream.GetTable(MetadataTokenType.Type);
var myType = typesTable[0];

AsmResolver also provides the generic overload GetTable<TMember>() to reduce the amount of code.

var typesTable = tableStream.GetTable<TypeDefinition>();
var myType = typesTable[0];

The MetadataTable class implements the ICollection interface, which makes adding and removing members possible

var typesTable = tableStream.GetTable<TypeDefinition>();
var myType = new TypeDefinition(...);
typesTable.Add(myType);

Please note that even though some metadata classes expose collections of metadata members, such as the TypeDefinition class exposing the Methods property, it is still required to manually add/remove the members to/from the corresponding tables. AsmResolver does not have an inbuilt metadata builder yet, but it is expected this feature will be added in the future.

##Editing method bodies AsmResolver fully supports reading and editing managed method bodies using the MethodBody class. This class exposes various members that will aid in editing the contents of the method. Method bodies can be accessed through the MethodDefinition.MethodBody property.

var typesTable = tableStream.GetTable<TypeDefinition>();
var myType = typesTable[0];
var myMethod = myType.Methods[0];
var myMethodBody = myMethod.MethodBody;