Write the Results to Storage

CCI Metadata

After loading the input files, rewriting applications typically create a mutable copy of the corresponding objects, modify them in various ways, and write the results to storage. PeToPe skips the modification step and simply writes the input assembly and PDB files to storage, so there is no need to create a mutable object. For more discussion, see Mutable and Immutable Representations.

The following example shows how PeToPe writes the input assembly and PDB file to storage.
Stream peStream = File.Create(module.Location + ".pe");
if (pdbReader == null)
  PeWriter.WritePeToStream(module, host, peStream);

  using (pdbReader)
    using (var pdbWriter = new PdbWriter(module.Location + ".pdb", pdbReader))

The static PeWriter.WritePeToStream method takes the CCI Metadata objects that represent the assembly, and optionally the PDB file. It converts those objects to the appropriate format, and writes the outputs to a specified stream.

PeToPe uses File.Create to create a Stream object to contain the output assembly. PeToPe appends “.pe” to the input file path to create a name for the output file, so that the output file is in the same folder as the input file.

Write an Assembly to Storage

If there is no PDB file, PeToPe calls the shorter of the two WritePeToStream overloads, which writes the output assembly to the specified stream. This overload has three parameters:
  1. The output assembly’s CCI Metadata object.
  2. The host.
  3. A Stream object, to receive the output assembly. For PeToPe, the Stream object represents a new file.

Write an Assembly and a PDB File to Storage

To write the contents of a PdbReader object to a stream:
  1. Create a PdbWriter object and initialize it with the PDB file’s PdbReader object and the output file path. PeToPe creates an output file path by appending .pdb to the input PE file path.
  2. Use the longer of the two WritePeToStream overloads to write the output PE and PDB files with a single WritePeToStream call.
This WritePeToStream overload has six parameters.
  1. The output assembly’s CCI Metadata object.
  2. The host.
  3. A Stream object, to receive the output PDB file. For PeToPe, the Stream object represents a new file.
  4. A source location provider for the PDB file, represented by ISourceLocationProvider. This object connects IL instructions with the corresponding line of source code.
  5. A local scope provider for the PDB file, represented by ILocalScopeProvider. This object provides local variable names, scopes, and so on.
  6. The PdbWriter object.
Note: PeToPe uses PdbReader for parameters 4 and 5. The PdbReader object supports both ISourceLocationProvider and ILocalScopeProvider interfaces and is sufficient for many applications. You can also implement custom objects for this purpose.

PdbReader and PdbWriter both interact with the file system, which requires locking files. Both classes expose IDisposable, which allows you to ensure that files aren’t locked longer than necessary by disposing the objects.

You should dispose PdbReader and PdbWriter as soon as you are finished with the objects. PeToPe manages this task by wrapping the WritePeToStream call in a using block.

Return to Beginning

Last edited Jan 12, 2010 at 3:58 PM by Guy_Smith, version 2


No comments yet.