public void IsCorrectSize() { var stream = new MemoryStream(); var rw = new StreamStructReaderWriter(stream); rw.Write(_testStruct2); Assert.AreEqual(9, stream.Length); }
private void CanWriteAndRead <T>(T testValue) where T : struct { var stream = new MemoryStream(); var rw = new StreamStructReaderWriter(stream); rw.Write(testValue); var readStruct = rw.Read <T>(0); Assert.AreEqual(testValue, readStruct, $"Can not read struct of type {typeof(T).Name} after writing it"); }
public void IncreasesRVA() { var stream = new MemoryStream(); var rw = new StreamStructReaderWriter(stream); rw.Write(123); rw.Write('c'); rw.Write(true); Assert.AreEqual(7, stream.Length); }
public void KeepsInitialRVA() { var stream = new MemoryStream(); stream.WriteByte(2); stream.WriteByte(1); stream.WriteByte(0); var rw = new StreamStructReaderWriter(stream); var read = rw.Read <TestStruct1>(rw.Write(_testStruct1)); var read2 = rw.Read <TestStruct2>(rw.Write(_testStruct2)); Assert.AreEqual(_testStruct1, read, $"Can not read struct of type {nameof(TestStruct1)} correctly after writing it"); Assert.AreEqual(_testStruct2, read2, $"Can not read struct of type {nameof(TestStruct2)} correctly after writing it"); }
public unsafe ISectionsResult Package(ISectionsInfo param) { var sectionDataStart = param.FileOffsetAtSectionsHeader + sizeof(SectionHeader) * (param.OtherSections.Count() + SpecialSectionCount); var peFile = new MemoryStream { Position = sectionDataStart }; var rva = 0x1000u; var idataInfo = new IdataInfo(param.Imports, rva, param.FileAlignment); var idataPackage = _idataPackager.Package(idataInfo); var idataSection = WriteAndCreateHeader(peFile, idataPackage, param.FileAlignment, param.SectionAlignment, ref rva); var textSection = WriteAndCreateHeader(peFile, param.TextSection, param.FileAlignment, param.SectionAlignment, ref rva); var sectionHeaders = new List <SectionHeader> { idataSection, textSection }; foreach (var otherSection in param.OtherSections) { sectionHeaders.Add(WriteAndCreateHeader(peFile, otherSection, param.FileAlignment, param.SectionAlignment, ref rva)); } var relocInfo = CreateRelocInfo(param, sectionHeaders); var relocPackage = _relocPackager.Package(relocInfo); var relocSection = WriteAndCreateHeader(peFile, relocPackage, param.FileAlignment, param.SectionAlignment, ref rva); sectionHeaders.Add(relocSection); var relocDataDirectory = new ImageDataDirectory { VirtualAddress = relocSection.VirtualAddress, Size = relocPackage.RelocationDirectorySize }; peFile.Position = param.FileOffsetAtSectionsHeader; var structWriter = new StreamStructReaderWriter(peFile); structWriter.WriteArray(sectionHeaders.ToArray()); Debug.Assert(peFile.Position <= sectionDataStart, "Section headers are writing into section data"); return(new SectionsResult( peFile.ToArray().Skip((int)param.FileOffsetAtSectionsHeader).ToArray(), sectionHeaders, param.TextSection.EntryPointOffset + textSection.VirtualAddress, idataPackage.IATResolver, idataPackage.ImportDirectory, idataPackage.IAT,
public unsafe IOptionalHeaderResult Package(IOptionalHeaderInfo param) { var codeSection = param.Sections.SectionHeaders.First(sec => sec.NameString.StartsWith(".text")); var initializedDataSection = param.Sections.SectionHeaders.FirstOrDefault(sec => sec.NameString.StartsWith(".data")); var uninitializedDataSection = param.Sections.SectionHeaders.FirstOrDefault(sec => sec.NameString.StartsWith(".bss")); var optHeaderStandard = new PE32PlusOptionalHeaderStandard { ExecutableKind = ExecutableKind.PE32Plus, BaseOfCodeRVA = codeSection.VirtualAddress, EntryPointRVA = param.Sections.EntryPointRVA, MajorLinkerVersion = param.MajorLinkerVersion, MinorLinkerVersion = param.MinorLinkerVersion, SizeOfCode = codeSection.VirtualSize, SizeOfInitializedData = initializedDataSection != default ? initializedDataSection.VirtualSize : 0, SizeOfUninitializedData = uninitializedDataSection != default ? uninitializedDataSection.VirtualSize : 0 }; var optHeaderWinNT = new PE32PlusOptionalHeaderWinNT { FileAlignment = param.FileAlignment, SectionAlignment = param.SectionAlignment, Subsystem = param.Subsystem, DllCharacteristics = param.DllCharacteristics, HeapSizeReserve = param.HeapSizeReserve, HeapSizeCommit = param.HeapSizeCommit, StackSizeReserve = param.StackSizeReserve, StackSizeCommit = param.StackSizeCommit, SizeOfImage = param.Sections.SectionHeaders.Max(sec => Round.Up(sec.VirtualAddress + sec.VirtualSize, param.SectionAlignment)), ImageBaseOffset = param.ImageBase, NumberOfDataDirectoryEntries = 0x10, SizeOfHeaders = Round.Up( (uint)(param.MZHeader.RawData.Length + sizeof(PEHeader) + sizeof(PE32PlusOptionalHeader) + sizeof(SectionHeader) * param.Sections.SectionHeaders.Count), param.FileAlignment ), MajorOSVersion = param.MajorOperatingSystemVersion, MinorOSVersion = param.MinorOperatingSystemVersion, MajorSubsystemVersion = param.MajorSubSystemVersion, MinorSubsystemVersion = param.MinorSubSystemVersion, MajorImageVersion = param.MajorImageVersion, MinorImageVersion = param.MinorImageVersion }; var optHeaderDataDictionary = new PE32PlusOptionalHeaderDataDirectories { IAT = param.Sections.IAT, ImportTable = param.Sections.ImportTable, Debug = param.Sections.Debug, BaseRelocationTable = param.Sections.BaseRelocationTable //todo }; var rawData = new MemoryStream(); var structWriter = new StreamStructReaderWriter(rawData); structWriter.Write(optHeaderStandard); structWriter.Write(optHeaderWinNT); structWriter.Write(optHeaderDataDictionary); return(new OptionalHeadersResult( rawData.ToArray(), param.Sections.Debug.VirtualAddress != 0, param.Sections.BaseRelocationTable.VirtualAddress != 0 )); } }