public void Save(Stream bnkStream, Stream mbnkStream) { Header.NumFiles = (uint)Files.Count; Header.HeaderSize = (uint)(Marshal.SizeOf(typeof(SoundbankHeader)) + (Marshal.SizeOf(typeof(SoundbankEntryInfo)) * Header.NumFiles)); bnkStream.WriteStruct(Header); mbnkStream.WriteStruct(Header); uint nextOffset = Header.HeaderSize; nextOffset = nextOffset.Align(0x800); foreach (var entry in Files) { entry.Info.Offset = nextOffset; nextOffset += entry.Info.MetadataLength + entry.Info.AudioLength; nextOffset = nextOffset.Align(0x800); bnkStream.WriteStruct(entry.Info); mbnkStream.WriteStruct(entry.Info); } int count = 0; foreach (var entry in Files) { bnkStream.Seek(entry.Info.Offset, SeekOrigin.Begin); Stream metadataStream = m_MetadataStreams[count]; if (metadataStream != null) { metadataStream.Seek(0, SeekOrigin.Begin); metadataStream.CopyTo(bnkStream); } Stream audioStream = m_AudioStreams[count]; audioStream.CopyTo(bnkStream); count++; } }
/// <inheritdoc /> public void UpdateOffsets(uint newFileOffset, uint newRva) { FileOffset = newFileOffset; Rva = newRva; _physicalSize = 0; _virtualSize = 0; foreach (var item in _items) { uint physicalPadding = newFileOffset.Align(item.Alignment) - newFileOffset; uint virtualPadding = newRva.Align(item.Alignment) - newRva; newFileOffset += physicalPadding; newRva += virtualPadding; item.Segment.UpdateOffsets(newFileOffset, newRva); uint physicalSize = item.Segment.GetPhysicalSize(); uint virtualSize = item.Segment.GetVirtualSize(); newFileOffset += physicalSize; newRva += virtualSize; _physicalSize += physicalPadding + physicalSize; _virtualSize += virtualPadding + virtualSize; } }
public bool Validate(string path, out ArchiveValidateError error) { byte[] buffer = new byte[256 - 4]; using (var input = File.Open( path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { while (input.Position < input.Length) { if (input.Position + 256 > input.Length) { error = new ArchiveValidateError( "end of file for next entry", input); return(false); } input.Read(buffer, 0, buffer.Length); int length = CheckFileName(buffer); if (length < 0) { error = new ArchiveValidateError( "invalid file name", input); return(false); } uint size = input.ReadValueU32(); uint realSize = size.Align(64); if (size == 0 && length == 0) { // this is the last entry if (input.Position == input.Length) { break; } error = new ArchiveValidateError( "null entry not at end of file", input); return(false); } if (input.Position + realSize > input.Length) { error = new ArchiveValidateError( "end of file for data", input); return(false); } input.Seek(realSize, SeekOrigin.Current); } error = null; return(true); } }
/// <inheritdoc /> public override uint GetPhysicalSize() { uint size = VersionTableEntryHeader.GetHeaderSize(Key); size = size.Align(4); size += (uint)Values.Count * sizeof(uint); return(size); }
public List <ArchiveEntry> GetEntries(string path) { byte[] buffer = new byte[256 - 4]; var entries = new List <ArchiveEntry>(); using (var input = File.Open( path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { while (input.Position < input.Length) { if (input.Position + 256 > input.Length) { return(null); } input.Read(buffer, 0, buffer.Length); int length = CheckFileName(buffer); if (length < 0) { return(null); } uint size = input.ReadValueU32(); uint realSize = size.Align(64); if (size == 0 && length == 0) { // this is the last entry if (input.Position == input.Length) { break; } return(null); } if (input.Position + realSize > input.Length) { return(null); } entries.Add(new ArchiveEntry() { Name = GetUniqueName(Encoding.ASCII.GetString(buffer, 0, length), entries), Offset = input.Position, Size = size, }); input.Seek(realSize, SeekOrigin.Current); } return(entries); } }
/// <inheritdoc /> public override uint GetPhysicalSize() { uint size = VersionTableEntryHeader.GetHeaderSize(Key); for (int i = 0; i < Tables.Count; i++) { size = size.Align(4); size += Tables[i].GetPhysicalSize(); } return(size); }
private MemoryStream ReadAlignedBlock(Stream input) { uint tableLength = input.ReadValueU32(); uint alignedLength = tableLength.Align(16); var memory = input.ReadToMemoryStream(tableLength); if (alignedLength != tableLength) { input.Seek(alignedLength - tableLength, SeekOrigin.Current); } return(memory); }
/// <summary> /// Aligns all sections according to the file and section alignment properties in the optional header. /// </summary> public void AlignSections() { for (int i = 0; i < Sections.Count; i++) { var section = Sections[i]; uint fileOffset = i > 0 ? Sections[i - 1].FileOffset + Sections[i - 1].GetPhysicalSize() : OptionalHeader.SizeOfHeaders; uint rva = i > 0 ? Sections[i - 1].Rva + Sections[i - 1].GetVirtualSize() : OptionalHeader.SizeOfHeaders.Align(OptionalHeader.SectionAlignment); section.UpdateOffsets( fileOffset.Align(OptionalHeader.FileAlignment), rva.Align(OptionalHeader.SectionAlignment)); } }
public void CreateFromDirectory(string Dir, string Outfile) { string[] Filepaths = System.IO.Directory.GetFiles(Dir); ushort Filecount = (ushort)Filepaths.Length; uint RequiredBytesForHeader = Util.Align(Filecount * 4u + 4u, 0x50u); // pretty sure this is not right but should work var Filestream = new System.IO.FileStream(Outfile, System.IO.FileMode.Create); // header Filestream.WriteByte((byte)'S'); Filestream.WriteByte((byte)'C'); Filestream.WriteByte((byte)'M'); Filestream.WriteByte((byte)'P'); uint TotalFilesize = RequiredBytesForHeader; foreach (string Path in Filepaths) { Filestream.Write(BitConverter.GetBytes(TotalFilesize), 0, 4); TotalFilesize += (uint)(new System.IO.FileInfo(Path).Length); TotalFilesize = TotalFilesize.Align(0x10u); } while (Filestream.Length < RequiredBytesForHeader) { Filestream.WriteByte(0x00); } // files foreach (string Path in Filepaths) { var File = new System.IO.FileStream(Path, System.IO.FileMode.Open); Util.CopyStream(File, Filestream, (int)File.Length); File.Close(); while (Filestream.Length % 0x10 != 0) { Filestream.WriteByte(0x00); } } Filestream.Close(); }
public void CreateFromDirectory(string Dir, string Outfile) { string[] Filepaths = System.IO.Directory.GetFiles(Dir); ushort Filecount = (ushort)Filepaths.Length; uint RequiredBytesForHeader = NumberUtils.Align(Filecount * 3u + 5u, 0x10u); // 3 bytes per filesize + 3 bytes for an extra pointer to first file + 2 bytes for filecount var Filestream = new System.IO.FileStream(Outfile, System.IO.FileMode.Create); // header Filestream.Write(BitConverter.GetBytes(Filecount), 0, 2); Filestream.Write(NumberUtils.GetBytesForUInt24(RequiredBytesForHeader), 0, 3); uint TotalFilesize = RequiredBytesForHeader; foreach (string Path in Filepaths) { TotalFilesize += (uint)(new System.IO.FileInfo(Path).Length); Filestream.Write(NumberUtils.GetBytesForUInt24(TotalFilesize), 0, 3); TotalFilesize = TotalFilesize.Align(0x10u); } while (Filestream.Length < RequiredBytesForHeader) { Filestream.WriteByte(0x00); } // files foreach (string Path in Filepaths) { var File = new System.IO.FileStream(Path, System.IO.FileMode.Open); StreamUtils.CopyStream(File, Filestream, (int)File.Length); File.Close(); while (Filestream.Length % 0x10 != 0) { Filestream.WriteByte(0x00); } } Filestream.Close(); }
/// <inheritdoc /> public override void UpdateOffsets(uint newFileOffset, uint newRva) { base.UpdateOffsets(newFileOffset, newRva); uint offset = newFileOffset; foreach (var module in _modules) { foreach (var entry in module.Symbols) { if (entry.IsImportByName) { _hintNameOffsets[entry] = offset - newFileOffset; offset += (uint)(sizeof(ushort) + Encoding.ASCII.GetByteCount(entry.Name) + 1); offset = offset.Align(2); } } _moduleNameOffsets[module] = offset - newFileOffset; offset += (uint)Encoding.ASCII.GetByteCount(module.Name) + 1; } _length = offset - newFileOffset; }
/// <summary> /// Aligns the writer to a specified boundary. /// </summary> /// <param name="writer">The writer to align.</param> /// <param name="align">The boundary to use.</param> public static void Align(this IBinaryStreamWriter writer, uint align) { uint currentPosition = writer.FileOffset; writer.WriteZeroes((int)(currentPosition.Align(align) - writer.FileOffset)); }
protected void Build( TPackage package, IEnumerable <KeyValuePair <string, string> > paths, string outputPath, bool ps3) { var isCompressed = (package.Flags & Package.HeaderFlags.Compressed) != 0; var isCondensed = (package.Flags & Package.HeaderFlags.Condensed) != 0; package.Entries.Clear(); foreach (var kv in paths) { package.Entries.Add(new TEntry() { Name = kv.Key, }); } var baseOffset = package.EstimateHeaderSize(); package.Entries.Clear(); using (var output = File.Create(outputPath)) { if (isCondensed == true && isCompressed == true) { output.Seek(baseOffset, SeekOrigin.Begin); using (var compressed = new MemoryStream()) { var z = new ZLIB.ZOutputStream(compressed, ZLIB.zlibConst.Z_BEST_COMPRESSION); z.FlushMode = ZLIB.zlibConst.Z_SYNC_FLUSH; long offset = 0; foreach (var kv in paths) { using (var input = File.OpenRead(kv.Value)) { var entry = new TEntry(); entry.Name = kv.Key; entry.Offset = (uint)offset; entry.UncompressedSize = (uint)input.Length; long size = z.TotalOut; z.WriteFromStream(input, input.Length); size = z.TotalOut - size; entry.CompressedSize = (uint)size; offset += entry.UncompressedSize; package.Entries.Add(entry); } } package.CompressedSize = (uint)compressed.Length; package.UncompressedSize = (uint)offset; compressed.Position = 0; output.WriteFromStream(compressed, compressed.Length); } output.Seek(0, SeekOrigin.Begin); package.Serialize(output); } else if ( ps3 == true && isCompressed == true) { output.Seek(baseOffset, SeekOrigin.Begin); long offset = 0; uint uncompressedSize = 0; foreach (var kv in paths) { using (var input = File.OpenRead(kv.Value)) { if (isCondensed == false) { var offsetPadding = offset.Align(2048) - offset; if (offsetPadding > 0) { offset += offsetPadding; output.Seek(offsetPadding, SeekOrigin.Current); } var sizePadding = uncompressedSize.Align(2048) - uncompressedSize; if (sizePadding > 0) { uncompressedSize += sizePadding; } } var entry = new TEntry(); entry.Name = kv.Key; entry.Offset = (uint)offset; entry.UncompressedSize = (uint)input.Length; entry.CompressedSize = 0; var left = input.Length; while (left > 0) { using (var compressed = new MemoryStream()) { var chunkUncompressedSize = (uint)Math.Min(0x10000, left); var zlib = new DeflaterOutputStream(compressed, new Deflater(9, true)); zlib.WriteFromStream(input, chunkUncompressedSize); zlib.Finish(); var chunkCompressedSize = (uint)compressed.Length; if (chunkCompressedSize > 0xFFFF) { throw new InvalidOperationException(); } output.WriteValueU16((ushort)chunkCompressedSize, package.Endian); output.WriteValueU16(0, package.Endian); output.WriteValueU32(chunkUncompressedSize, package.Endian); entry.CompressedSize += 2 + 2 + 4; entry.CompressedSize += chunkCompressedSize; compressed.Position = 0; output.WriteFromStream(compressed, compressed.Length); left -= chunkUncompressedSize; } } offset += entry.CompressedSize; uncompressedSize += entry.UncompressedSize; package.Entries.Add(entry); } } package.CompressedSize = (uint)offset; package.UncompressedSize = uncompressedSize; } else if (isCompressed == true) { output.Seek(baseOffset, SeekOrigin.Begin); long offset = 0; uint uncompressedSize = 0; foreach (var kv in paths) { using (var input = File.OpenRead(kv.Value)) { if (isCondensed == false) { var offsetPadding = offset.Align(2048) - offset; if (offsetPadding > 0) { offset += offsetPadding; output.Seek(offsetPadding, SeekOrigin.Current); } var sizePadding = uncompressedSize.Align(2048) - uncompressedSize; if (sizePadding > 0) { uncompressedSize += sizePadding; } } var entry = new TEntry(); entry.Name = kv.Key; entry.Offset = (uint)offset; entry.UncompressedSize = (uint)input.Length; using (var compressed = new MemoryStream()) { var zlib = new DeflaterOutputStream(compressed); zlib.WriteFromStream(input, input.Length); zlib.Finish(); entry.CompressedSize = (uint)compressed.Length; compressed.Position = 0; output.WriteFromStream(compressed, compressed.Length); } offset += entry.CompressedSize; uncompressedSize += entry.UncompressedSize; package.Entries.Add(entry); } } package.CompressedSize = (uint)offset; package.UncompressedSize = uncompressedSize; } else { output.Seek(baseOffset, SeekOrigin.Begin); long offset = 0; foreach (var kv in paths) { using (var input = File.OpenRead(kv.Value)) { if (isCondensed == false) { var padding = offset.Align(2048) - offset; if (padding > 0) { offset += padding; output.Seek(padding, SeekOrigin.Current); } } else if ( isCondensed == true && isCompressed == false) { var padding = offset.Align(16) - offset; if (padding > 0) { offset += padding; output.Seek(padding, SeekOrigin.Current); } } var entry = new TEntry(); entry.Name = kv.Key; entry.Offset = (uint)offset; entry.UncompressedSize = (uint)input.Length; output.WriteFromStream(input, input.Length); entry.CompressedSize = 0xFFFFFFFF; offset += entry.UncompressedSize; package.Entries.Add(entry); } } package.CompressedSize = 0xFFFFFFFF; package.UncompressedSize = (uint)offset; } package.TotalSize = (uint)output.Length; output.Seek(0, SeekOrigin.Begin); package.Serialize(output); } }
public void Pack(string[] files, string outFilename, string metadata = null) { FileCount = (uint)files.Length + 1; HeaderSize = 0x1C; EntrySize = 0; if (ContainsStartPointers) { EntrySize += 4; } if (ContainsEndPointers) { EntrySize += 4; } if (ContainsFileSizes) { EntrySize += 4; } if (ContainsFilenames) { EntrySize += 0x20; } if (ContainsFiletypes) { EntrySize += 4; } if (ContainsFileMetadata) { EntrySize += 4; } uint HeaderEnd = HeaderSize + EntrySize * FileCount; if (!String.IsNullOrEmpty(ArchiveName)) { ArchiveNameLocation = HeaderEnd; } if (infile == null) // <- this is hacky and may create broken files when using -o with changed filenames/filecount/metadata/etc { FirstFileStart = HeaderEnd.Align(Alignment); // <- this is inaccurate and will break with metadata } using (FileStream f = new FileStream(outFilename, FileMode.Create)) { // header f.Write(Encoding.ASCII.GetBytes("FPS4"), 0, 4); f.WriteUInt32(FileCount.SwapEndian()); f.WriteUInt32(HeaderSize.SwapEndian()); f.WriteUInt32(FirstFileStart.SwapEndian()); f.WriteUInt16(EntrySize.SwapEndian()); f.WriteUInt16(ContentBitmask.SwapEndian()); f.WriteUInt32(Unknown2.SwapEndian()); f.WriteUInt32(ArchiveNameLocation.SwapEndian()); // file list uint ptr = FirstFileStart; for (int i = 0; i < files.Length; ++i) { var fi = new System.IO.FileInfo(files[i]); if (ContainsStartPointers) { f.WriteUInt32(ptr.SwapEndian()); } if (ContainsEndPointers) { f.WriteUInt32(((uint)(fi.Length.Align((int)Alignment))).SwapEndian()); } if (ContainsFileSizes) { f.WriteUInt32(((uint)(fi.Length)).SwapEndian()); } if (ContainsFilenames) { string filename = fi.Name.Truncate(0x1F); byte[] fnbytes = Util.ShiftJISEncoding.GetBytes(filename); f.Write(fnbytes, 0, fnbytes.Length); for (int j = fnbytes.Length; j < 0x20; ++j) { f.WriteByte(0); } } if (ContainsFiletypes) { string extension = fi.Extension.TrimStart('.').Truncate(4); byte[] extbytes = Util.ShiftJISEncoding.GetBytes(extension); f.Write(extbytes, 0, extbytes.Length); for (int j = extbytes.Length; j < 4; ++j) { f.WriteByte(0); } } if (ContainsFileMetadata) { if (infile != null) { // copy this from original file, very hacky when filenames/filecount/metadata changes infile.Position = f.Position; f.WriteUInt32(infile.ReadUInt32()); } else { // place a null for now and go back to fix later f.WriteUInt32(0); } } ptr += (uint)fi.Length.Align((int)Alignment); } // at the end of the file list, a final entry pointing to the end of the container f.WriteUInt32(ptr.SwapEndian()); for (int j = 4; j < EntrySize; ++j) { f.WriteByte(0); } // the idea is to write a pointer here // and at the target of the pointer you have a nullterminated string // with all the metadata in a param=data format separated by spaces // maybe including a filepath at the start without a param= // strings should be after the filelist block but before the actual files if (ContainsFileMetadata && metadata != null) { for (int i = 0; i < files.Length; ++i) { var fi = new System.IO.FileInfo(files[i]); long ptrPos = 0x1C + ((i + 1) * EntrySize) - 4; // remember pos uint oldPos = (uint)f.Position; // jump to metaptr f.Position = ptrPos; // write remembered pos f.WriteUInt32(oldPos.SwapEndian()); // jump to remembered pos f.Position = oldPos; // write meta + nullterm if (metadata.Contains('p')) { string relativePath = GetRelativePath(f.Name, fi.FullName); f.Write(Util.ShiftJISEncoding.GetBytes(relativePath)); } if (metadata.Contains('n')) { f.Write(Util.ShiftJISEncoding.GetBytes("name=" + Path.GetFileNameWithoutExtension(fi.FullName))); } f.WriteByte(0); } } // write original archive filepath if (!String.IsNullOrEmpty(ArchiveName)) { byte[] archiveNameBytes = Util.ShiftJISEncoding.GetBytes(ArchiveName); f.Write(archiveNameBytes, 0, archiveNameBytes.Length); f.WriteByte(0); } // fix up header if we inserted metadata if (ContainsFileMetadata && metadata != null) { long pos = f.Position; FirstFileStart = ((uint)(f.Position)).Align(Alignment); f.Position = 0xC; f.WriteUInt32(FirstFileStart.SwapEndian()); ptr = FirstFileStart; for (int i = 0; i < files.Length; ++i) { f.Position = 0x1C + (i * EntrySize); var fi = new System.IO.FileInfo(files[i]); if (ContainsStartPointers) { f.WriteUInt32(ptr.SwapEndian()); } if (ContainsEndPointers) { f.WriteUInt32(((uint)(fi.Length.Align((int)Alignment))).SwapEndian()); } ptr += (uint)fi.Length.Align((int)Alignment); } f.Position = 0x1C + (files.Length * EntrySize); f.WriteUInt32(ptr.SwapEndian()); f.Position = pos; } // pad until files if (infile != null) { infile.Position = f.Position; for (long i = f.Length; i < FirstFileStart; ++i) { f.WriteByte((byte)infile.ReadByte()); } } else { for (long i = f.Length; i < FirstFileStart; ++i) { f.WriteByte(0); } } // actually write files for (int i = 0; i < files.Length; ++i) { using (var fs = new System.IO.FileStream(files[i], FileMode.Open)) { Console.WriteLine("Packing #" + i.ToString("D4") + ": " + files[i]); Util.CopyStream(fs, f, (int)fs.Length); while (f.Length % Alignment != 0) { f.WriteByte(0); } } } } }
public void Save(Stream stream) { // Calculate IndexSize FileData.IndexCount = (uint)Files.Count; FileData.IndexSize = (FileData.IndexCount * 0x1C); // Write Names & calculate NamesSize Dictionary <string, uint> filenames = new Dictionary <string, uint>(StringComparer.InvariantCultureIgnoreCase); stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin); uint filenameOffset = 0; foreach (PackfileEntry entry in Files) { string filename = Path.GetFileNameWithoutExtension(entry.Name); if (filenames.ContainsKey(filename)) { entry.Data.FilenameOffset = filenames[filename]; } else { entry.Data.FilenameOffset = filenameOffset; int length = stream.WriteAsciiNullTerminatedString(filename); filenames.Add(filename, filenameOffset); filenameOffset += (uint)length; } } FileData.NamesSize = filenameOffset; // Write Extensions & calculate ExtensionsSize Dictionary <string, uint> extensions = new Dictionary <string, uint>(StringComparer.InvariantCultureIgnoreCase); uint extensionOffset = 0; stream.Seek(CalculateExtensionsOffset(), SeekOrigin.Begin); foreach (PackfileEntry entry in Files) { string extension = Path.GetExtension(entry.Name); if (extension.StartsWith(".")) { extension = extension.Remove(0, 1); } if (extensions.ContainsKey(extension)) { entry.Data.ExtensionOffset = extensions[extension]; } else { entry.Data.ExtensionOffset = extensionOffset; int length = stream.WriteAsciiNullTerminatedString(extension); extensions.Add(extension, extensionOffset); extensionOffset += (uint)length; } } FileData.ExtensionsSize = extensionOffset; // Write data uint dataOffset = 0; stream.Seek(CalculateDataStartOffset(), SeekOrigin.Begin); foreach (PackfileEntry entry in Files) { Stream inStream = m_Streams[entry.Name]; entry.Data.Size = (uint)inStream.Length; entry.Data.Start = dataOffset; entry.Data.CompressedSize = (uint)0xFFFFFFFF; inStream.CopyTo(stream); dataOffset += entry.Data.Size; stream.Align(16); dataOffset = dataOffset.Align(16); } // Write Header stream.Seek(0, SeekOrigin.Begin); FileData.Descriptor = 0x51890ACE; FileData.Version = 0x04; FileData.CompressedDataSize = 0xFFFFFFFF; FileData.UncompressedDataSize = dataOffset; FileData.PackageSize = (uint)stream.Length; stream.WriteStruct(FileData); // Write file index stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin); foreach (PackfileEntry entry in Files) { stream.WriteStruct(entry.Data); } }
public void Build() { // Build tasks foreach (var task in _tasks) { task.Build(); } // Remove empty sections for (int i = _sections.Count - 1; i >= 0; i--) { if (_sections[i].Blobs.Count == 0) { _sections.RemoveAt(i); } } // Init if (_is32Bits) { _sizeOfHeaders = (uint) ( PEConstants.DosHeaderSize + PEConstants.DosX86Stub.Length + 4 + // NTSignature PEConstants.COFFHeaderSize + PEConstants.PEHeaderSize + PEConstants.NumberOfRvaAndSizes * 8 + PEConstants.SectionHeaderSize * _sections.Count ); } else { _sizeOfHeaders = (uint) ( PEConstants.DosHeaderSize + PEConstants.DosX86Stub.Length + 4 + // NTSignature PEConstants.COFFHeaderSize + PEConstants.PEHeader64Size + PEConstants.NumberOfRvaAndSizes * 8 + PEConstants.SectionHeaderSize * _sections.Count ); } _sizeOfHeaders = _sizeOfHeaders.Align(_fileAlignment); _sizeOfImage = _sizeOfHeaders; _baseOfCode = 0; _baseOfData = 0; _sizeOfCode = 0; _sizeOfInitializedData = 0; _sizeOfUninitializedData = 0; if (_is32Bits) { _characteristics |= ImageCharacteristics.MACHINE_32BIT; } else { _characteristics &= ~ImageCharacteristics.MACHINE_32BIT; } // Build sections uint virtualAddress = _sectionAlignment; uint pointerToRawData = _sizeOfHeaders; foreach (BuildSection section in _sections) { section._rva = virtualAddress; section._pointerToRawData = pointerToRawData; uint blobLength = 0; foreach (var blob in section.Blobs) { if (blob.OffsetAlignment > 0) { blobLength = blobLength.Align(blob.OffsetAlignment); } blob._rva = virtualAddress + blobLength; blob._pointerToRawData = pointerToRawData + blobLength; blobLength += (uint)blob.Length; } section._virtualSize = blobLength; section._sizeOfRawData = blobLength.Align(_fileAlignment); virtualAddress += section.VirtualSize.Align(_sectionAlignment); pointerToRawData += section.SizeOfRawData; if ((section.Characteristics & SectionCharacteristics.ContainsCode) != 0) { _sizeOfCode += section.SizeOfRawData; if (_baseOfCode == 0) { _baseOfCode = section.RVA; } } if ((section.Characteristics & SectionCharacteristics.ContainsInitializedData) != 0) { _sizeOfInitializedData += section.SizeOfRawData; if (_baseOfData == 0) { _baseOfData = section.RVA; } } if ((section.Characteristics & SectionCharacteristics.ContainsUninitializedData) != 0) { _sizeOfUninitializedData += section.SizeOfRawData; } } _sizeOfImage = virtualAddress; // Apply fixups foreach (var fixup in _fixups) { fixup.ApplyFixup(); } }