public void RebuildNetPEAddSection() { const string fileName = "HelloWorld"; const string sectionName = ".test"; var sectionData = new byte[] { 1, 3, 3, 7 }; var peFile = PEFile.FromBytes(Properties.Resources.HelloWorld); // Add a new section. peFile.Sections.Add(new PESection(sectionName, SectionFlags.MemoryRead | SectionFlags.ContentInitializedData) { Contents = new DataSegment(sectionData) }); // Rebuild and check if file is still runnable. _fixture .GetRunner <FrameworkPERunner>() .RebuildAndRun(peFile, fileName, "Hello World!" + Environment.NewLine); // Read the new file. var newPEFile = PEFile.FromFile(_fixture .GetRunner <FrameworkPERunner>() .GetTestExecutablePath(nameof(PEFileTest), nameof(RebuildNetPEAddSection), fileName)); // Verify the section and its data is present: var newSection = newPEFile.Sections.First(s => s.Name == sectionName); var newData = new byte[sectionData.Length]; Assert.Equal(sectionData.Length, newSection .CreateReader() .ReadBytes(newData, 0, newData.Length)); Assert.Equal(sectionData, newData); }
public void PreserveMetadataNoChange() { var peFile = PEFile.FromBytes(Properties.Resources.HelloWorld); var peImage = PEImage.FromFile(peFile); var metadata = peImage.DotNetDirectory.Metadata; using var tempStream = new MemoryStream(); metadata.Write(new BinaryStreamWriter(tempStream)); var newMetadata = new SerializedMetadata(new PEReaderContext(peFile), new ByteArrayReader(tempStream.ToArray())); Assert.Equal(metadata.MajorVersion, newMetadata.MajorVersion); Assert.Equal(metadata.MinorVersion, newMetadata.MinorVersion); Assert.Equal(metadata.Reserved, newMetadata.Reserved); Assert.Equal(metadata.VersionString, newMetadata.VersionString); Assert.Equal(metadata.Flags, newMetadata.Flags); Assert.Equal(metadata.Streams.Count, newMetadata.Streams.Count); for (int i = 0; i < metadata.Streams.Count; i++) { var oldStream = metadata.Streams[i]; var newStream = newMetadata.Streams[i]; Assert.Equal(oldStream.Name, newStream.Name); var oldData = oldStream.CreateReader().ReadToEnd(); var newData = newStream.CreateReader().ReadToEnd(); Assert.Equal(oldData, newData); } }
public void PreserveTableStreamNoChange() { var peFile = PEFile.FromBytes(Properties.Resources.HelloWorld); var peImage = PEImage.FromFile(peFile); var tablesStream = peImage.DotNetDirectory.Metadata.GetStream <TablesStream>(); using var tempStream = new MemoryStream(); tablesStream.Write(new BinaryStreamWriter(tempStream)); var newTablesStream = new SerializedTableStream(tablesStream.Name, tempStream.ToArray(), peFile); Assert.Equal(tablesStream.Reserved, newTablesStream.Reserved); Assert.Equal(tablesStream.MajorVersion, newTablesStream.MajorVersion); Assert.Equal(tablesStream.MinorVersion, newTablesStream.MinorVersion); Assert.Equal(tablesStream.Flags, newTablesStream.Flags); Assert.Equal(tablesStream.Log2LargestRid, newTablesStream.Log2LargestRid); Assert.Equal(tablesStream.ExtraData, newTablesStream.ExtraData); for (TableIndex i = 0; i <= TableIndex.GenericParamConstraint; i++) { var oldTable = tablesStream.GetTable(i); var newTable = newTablesStream.GetTable(i); Assert.Equal(oldTable.Count, newTable.Count); for (int j = 0; j < oldTable.Count; j++) { Assert.Equal(oldTable[j], newTable[j]); } } }
public void RebuildNetPENoChange() { var peFile = PEFile.FromBytes(Properties.Resources.HelloWorld); _fixture .GetRunner <FrameworkPERunner>() .RebuildAndRun(peFile, "HelloWorld", "Hello World!" + Environment.NewLine); }
public void RemoveSectionShouldPersistOtherSectionContents() { var peFile = PEFile.FromBytes(Properties.Resources.HelloWorld); var section = peFile.Sections[1]; byte[] contents = ((IReadableSegment)section.Contents).ToArray(); peFile.Sections.RemoveAt(0); peFile.UpdateHeaders(); byte[] contents2 = ((IReadableSegment)section.Contents).ToArray(); Assert.Equal(contents, contents2); }
public void InsertSectionShouldPersistOtherSectionContents() { var peFile = PEFile.FromBytes(Properties.Resources.HelloWorld); var section = peFile.Sections[0]; byte[] contents = ((IReadableSegment)section.Contents).ToArray(); peFile.Sections.Insert(0, new PESection(".test", SectionFlags.MemoryRead | SectionFlags.MemoryWrite | SectionFlags.ContentInitializedData, new DataSegment(new byte[] { 1, 2, 3, 4 }))); peFile.UpdateHeaders(); byte[] contents2 = ((IReadableSegment)section.Contents).ToArray(); Assert.Equal(contents, contents2); }
public void RoundTripPE() { // This test validates that a PE can be loaded, copied, and written, without altering the data var originalBytes = Properties.Resources.NativeMemoryDemos; var peFile = PEFile.FromBytes(originalBytes); var msOutput = new MemoryStream(); var output = new PEFile(peFile.DosHeader, peFile.FileHeader, peFile.OptionalHeader); foreach (var section in peFile.Sections) { var newSection = new PESection(section); output.Sections.Add(newSection); } output.Write(new BinaryStreamWriter(msOutput)); Assert.Equal(originalBytes, msOutput.ToArray()); }
/// <summary> /// Finalizes a delay-signed PE image. /// </summary> /// <param name="imageStream">The stream containing the image to sign.</param> /// <param name="hashAlgorithm">The hashing algorithm to use.</param> /// <exception cref="BadImageFormatException">Occurs when the image does not contain a valid .NET image.</exception> /// <exception cref="ArgumentException">Occurs when the image does not contain a strong name directory of the right size.</exception> public void SignImage(Stream imageStream, AssemblyHashAlgorithm hashAlgorithm) { imageStream.Position = 0; using var streamCopy = new MemoryStream(); imageStream.CopyTo(streamCopy); streamCopy.Position = 0; var file = PEFile.FromBytes(streamCopy.ToArray()); var image = PEImage.FromFile(file); // Check existence of .NET metadata. if (image.DotNetDirectory is null) { throw new BadImageFormatException("Input image is not a .NET assembly."); } // Check existence of a valid sn directory. var strongNameDirectory = image.DotNetDirectory.StrongName; if (strongNameDirectory is null) { throw new ArgumentException("Cannot sign an image without a strong name directory."); } if (PrivateKey.Modulus.Length != strongNameDirectory.GetPhysicalSize()) { throw new ArgumentException( "The strong name signature directory size does not match the size of the strong signature."); } // Compute hash of pseudo PE file. var hash = GetHashToSign(streamCopy, file, image, hashAlgorithm); // Compute strong name signature. var signature = ComputeSignature(hashAlgorithm, hash); // Copy strong name signature into target PE. imageStream.Position = (long)strongNameDirectory.Offset; imageStream.Write(signature, 0, signature.Length); }
public void SectionsInMappedBinaryShouldUseVirtualAddressesAsOffset() { var physicalFile = PEFile.FromBytes(Properties.Resources.HelloWorld); var memoryFile = PEFile.FromDataSource( new ByteArrayDataSource(Properties.Resources.HelloWorldDump), PEMappingMode.Mapped); Assert.Equal(physicalFile.Sections.Count, memoryFile.Sections.Count); for (int i = 0; i < physicalFile.Sections.Count; i++) { var physicalSection = physicalFile.Sections[i]; var memorySection = memoryFile.Sections[i]; Assert.NotEqual(physicalSection.Offset, memorySection.Offset); Assert.Equal(physicalSection.Rva, memorySection.Rva); byte[] expected = new byte[20]; physicalSection.CreateReader().ReadBytes(expected, 0, expected.Length); byte[] actual = new byte[20]; memorySection.CreateReader().ReadBytes(actual, 0, actual.Length); Assert.Equal(expected, actual); } }
/// <summary> /// Opens a PE image from a buffer. /// </summary> /// <param name="bytes">The bytes to interpret.</param> /// <param name="readParameters">The parameters to use while reading the PE image.</param> /// <returns>The PE image that was opened.</returns> /// <exception cref="BadImageFormatException">Occurs when the file does not follow the PE file format.</exception> public static IPEImage FromBytes(byte[] bytes, PEReadParameters readParameters) => FromFile(PEFile.FromBytes(bytes), readParameters);
/// <summary> /// Opens a PE image from a buffer. /// </summary> /// <param name="bytes">The bytes to interpret.</param> /// <returns>The PE image that was opened.</returns> /// <exception cref="BadImageFormatException">Occurs when the file does not follow the PE file format.</exception> public static IPEImage FromBytes(byte[] bytes) => FromFile(PEFile.FromBytes(bytes));
public void InvalidFileOffsetToRva() { var peFile = PEFile.FromBytes(Properties.Resources.HelloWorld); Assert.Throws <ArgumentOutOfRangeException>(() => peFile.FileOffsetToRva(0x2000)); }
public void ValidFileOffsetToRva() { var peFile = PEFile.FromBytes(Properties.Resources.HelloWorld); Assert.Equal(0x0000268Eu, peFile.FileOffsetToRva(0x0000088Eu)); }