SectionLocation findSectionLocation(ImportEntry _importEntry, out bool _usePlexLocation) { _usePlexLocation = true; if (_importEntry != null) { // 1. find section locations with corresponding PlexLocation var locations = from location in m_sectionLocations.OrderByDescending(loc => loc.PlexLocation.Length) where !String.IsNullOrEmpty(location.PlexLocation) && _importEntry.FullFileName.StartsWith(location.PlexLocation, StringComparison.OrdinalIgnoreCase) select location; SectionLocation sectionLocation = locations.FirstOrDefault(); if (sectionLocation == null) { _usePlexLocation = false; // 2. find section locations with corresponding MappedLocation locations = from location in m_sectionLocations.OrderByDescending(loc => loc.MappedLocation.Length) where !String.IsNullOrEmpty(location.MappedLocation) && _importEntry.FullFileName.StartsWith(location.MappedLocation, StringComparison.OrdinalIgnoreCase) select location; sectionLocation = locations.FirstOrDefault(); } return(sectionLocation); } return(null); }
public void updateSectionLocations() { if (m_importFile != null) { foreach (ImportEntry entry in m_importFile.Entries) { bool usePlexLocation; SectionLocation sectionLocation = findSectionLocation(entry, out usePlexLocation); if (sectionLocation != null && sectionLocation.Owner() != null) { entry.setSectionLocation(sectionLocation, usePlexLocation, progressMessage); if (entry.FolderSection != null) { Debug.WriteLine(String.Format("==> FOLDER FOUND[{0}]: {1} - {2}", entry.FullFileName, entry.FolderSection.Key, entry.FolderSection.Title)); } else { Debug.WriteLine(String.Format("==> folderSection NOT FOUND[{0}]", entry.FullFileName)); } } else { entry.FolderSection = null; Debug.WriteLine(String.Format("==> Mapped SectionLocation NOT FOUND[{0}]", entry.FullFileName)); } } } progressMessage("", true); }
protected void copyMappedLocations(List <SectionLocation> _fromLocations, List <SectionLocation> _toLocations, bool _addIfMissing) { if (_fromLocations != null && _toLocations != null) { foreach (SectionLocation sectionLocation in _toLocations) { SectionLocation mappedLocation = _fromLocations.FirstOrDefault(location => location.PlexLocation.Equals(sectionLocation.PlexLocation, StringComparison.OrdinalIgnoreCase)); if (mappedLocation != null) { if (PMSServer.DirectorySeparator == PMSBase.FORWARD_SLASH && !String.IsNullOrEmpty(mappedLocation.MappedLocation)) { mappedLocation.MappedLocation = ImportEntry.normalizePath(mappedLocation.MappedLocation, PMSBase.BACKWARD_SLASH, PMSServer.DirectorySeparator); } sectionLocation.MappedLocation = mappedLocation.MappedLocation ?? ""; } } if (_addIfMissing) { foreach (SectionLocation sectionLocation in _fromLocations) { if (_toLocations.FirstOrDefault(location => location.PlexLocation.Equals(sectionLocation.PlexLocation, StringComparison.OrdinalIgnoreCase)) == null) { _toLocations.Add(new SectionLocation(null) { PlexLocation = sectionLocation.PlexLocation }); } } } } }
protected override void Serialize(BlobBuilder builder, SectionLocation location) { NativeResourceWriter.SerializeWin32Resources( builder, _resources, location.RelativeVirtualAddress ); }
private MainSection getSelectedMainSection() { if (gvSectionLocation.SelectedRows.Count == 1) { SectionLocation sectionLocation = gvSectionLocation.SelectedRows[0].DataBoundItem as SectionLocation; return(sectionLocation != null?sectionLocation.Owner() : null); } return(null); }
protected override void Serialize(BlobBuilder builder, SectionLocation location) { int value; while ((value = _resources.ReadByte()) >= 0) { builder.WriteByte((byte)value); } }
public bool Equals(SectionInfo other) { return(other == null ? false : Section.Equals(other.Section) && FullSection.SequenceEqual(other.FullSection) && Body.SequenceEqual(other.Body) && SectionLocation.Equals(other.SectionLocation) && SectionBodyLocation.Equals(other.SectionBodyLocation)); }
protected override BlobBuilder SerializeSection(string name, SectionLocation location) { if (name.Equals(MvidSectionName, StringComparison.Ordinal)) { Debug.Assert(_withMvidSection); return(SerializeMvidSection(location)); } return(base.SerializeSection(name, location)); }
public void PutLocation(int id, SectionLocation model) { DataProvider.ExecuteNonQuery(GetConnection, "dbo.Sections_UpdateLocationTab" , inputParamMapper : delegate(SqlParameterCollection param) { param.AddWithValue("@Id", id); param.AddWithValue("@CampusLocation", model.CampusLocation); param.AddWithValue("@RoomNumber", model.RoomNumber); }); }
/// <summary> /// Emit the .reloc section based on file relocation information in the individual blocks. /// We rely on the fact that the .reloc section is emitted last so that, by the time /// it's getting serialized, all other sections that may contain relocations have already /// been laid out. /// </summary> private BlobBuilder SerializeRelocationSection(SectionLocation sectionLocation) { // There are 12 bits for the relative offset const int RelocationTypeShift = 12; const int MaxRelativeOffsetInBlock = (1 << RelocationTypeShift) - 1; // Even though the format doesn't dictate it, it seems customary // to align the base RVA's on 4K boundaries. const int BaseRVAAlignment = 1 << RelocationTypeShift; BlobBuilder builder = new BlobBuilder(); int baseRVA = 0; List <ushort> offsetsAndTypes = null; // Traverse relocations in all sections in their RVA order // By now, all "normal" sections with relocations should already have been laid out foreach (Section section in _sections.OrderBy((sec) => sec.RVAWhenPlaced)) { foreach (PlacedObjectData placedObjectData in section.PlacedObjectDataToRelocate) { for (int relocIndex = 0; relocIndex < placedObjectData.Relocs.Length; relocIndex++) { RelocType relocType = placedObjectData.Relocs[relocIndex].RelocType; RelocType fileRelocType = GetFileRelocationType(relocType); if (fileRelocType != RelocType.IMAGE_REL_BASED_ABSOLUTE) { int relocationRVA = section.RVAWhenPlaced + placedObjectData.Offset + placedObjectData.Relocs[relocIndex].Offset; if (offsetsAndTypes != null && relocationRVA - baseRVA > MaxRelativeOffsetInBlock) { // Need to flush relocation block as the current RVA is too far from base RVA FlushRelocationBlock(builder, baseRVA, offsetsAndTypes); offsetsAndTypes = null; } if (offsetsAndTypes == null) { // Create new relocation block baseRVA = relocationRVA & -BaseRVAAlignment; offsetsAndTypes = new List <ushort>(); } ushort offsetAndType = (ushort)(((ushort)fileRelocType << RelocationTypeShift) | (relocationRVA - baseRVA)); offsetsAndTypes.Add(offsetAndType); } } } } if (offsetsAndTypes != null) { FlushRelocationBlock(builder, baseRVA, offsetsAndTypes); } _relocationDirectoryEntry = new DirectoryEntry(sectionLocation.RelativeVirtualAddress, builder.Count); return(builder); }
/// <summary> /// Traverse blocks within a single section and use them to calculate final layout /// of the given section. /// </summary> /// <param name="name">Section to serialize</param> /// <param name="sectionLocation">Logical section address within the output PE file</param> /// <returns></returns> public BlobBuilder SerializeSection(string name, SectionLocation sectionLocation) { if (name == R2RPEBuilder.RelocSectionName) { return(SerializeRelocationSection(sectionLocation)); } if (name == R2RPEBuilder.ExportDataSectionName) { return(SerializeExportSection(sectionLocation)); } BlobBuilder serializedSection = null; // Locate logical section index by name foreach (Section section in _sections.Where((sec) => sec.Name == name)) { // Calculate alignment padding int alignedRVA = (sectionLocation.RelativeVirtualAddress + section.Alignment - 1) & -section.Alignment; int padding = alignedRVA - sectionLocation.RelativeVirtualAddress; if (padding > 0) { if (serializedSection == null) { serializedSection = new BlobBuilder(); } serializedSection.WriteBytes(0, padding); sectionLocation = new SectionLocation( sectionLocation.RelativeVirtualAddress + padding, sectionLocation.PointerToRawData + padding); } // Place the section section.RVAWhenPlaced = sectionLocation.RelativeVirtualAddress; section.FilePosWhenPlaced = sectionLocation.PointerToRawData; if (section.Content.Count != 0) { sectionLocation = new SectionLocation( sectionLocation.RelativeVirtualAddress + section.Content.Count, sectionLocation.PointerToRawData + section.Content.Count); if (serializedSection == null) { serializedSection = section.Content; } else { serializedSection.LinkSuffix(section.Content); } } } return(serializedSection); }
public HttpResponseMessage updateLocation(int id, SectionLocation model) { if (!ModelState.IsValid) { return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState)); } SucessResponse response = new SucessResponse(); _sectionService.PutLocation(id, model); return(Request.CreateResponse(response)); }
protected override BlobBuilder SerializeSection(string name, SectionLocation location) { if (name == ".s2") { _dirBuilder.CopyrightTable = new DirectoryEntry(location.RelativeVirtualAddress + 5, 10); } var builder = new BlobBuilder(); builder.WriteBytes((byte)name[name.Length - 1], 10); return(builder); }
public AttributeDatum <double> GetNumericAttributeDatum(ConfigFileModel item) { var sqlConnection = new SqlConnection(item.Connection.UserName, item.Connection.Password, item.Connection.Server, item.Connection.DataSource); var numericAttribute = new NumericAttribute(item.AttributeName, sqlConnection, Convert.ToDouble(item.DefaultValue), item.Maximum, item.Minimum); var sectionLocation = new SectionLocation("I dont know yet"); var numericAttributeDatum = new AttributeDatum <double>(numericAttribute, 5, sectionLocation, DateTime.Now); return(numericAttributeDatum); }
private BlobBuilder SerializeMvidSection(SectionLocation location) { var sectionBuilder = new BlobBuilder(); // The guid will be filled in later: _mvidSectionFixup = sectionBuilder.ReserveBytes(SizeOfGuid); var mvidWriter = new BlobWriter(_mvidSectionFixup); mvidWriter.WriteBytes(0, _mvidSectionFixup.Length); Debug.Assert(mvidWriter.RemainingBytes == 0); return(sectionBuilder); }
/// <summary> /// 由坐标点获取区段代码 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public string getSectionCode(int x, int y) { string secCode = "null"; float offsetX = PathMatrix.offsetX; float offsetY = PathMatrix.offsetY; offsetX = offsetX - (float)DefaultSizeStr.leftSpaceWidth * (PathMatrix.widthScale - 1f); offsetY = offsetY - (float)DefaultSizeStr.upHourWordHeight * (PathMatrix.heightScale - 1f); x = x - (int)offsetX; y = y - (int)offsetY; if (secLocation == null || secLocation.Count <= 0) { return(secCode); } int y1, y2, x1, x2; for (int i = 0; i < secLocation.Count; i++) { SectionLocation oneIDLocation = (SectionLocation)secLocation[i]; x1 = oneIDLocation.pStart.X; x2 = oneIDLocation.pEnd.X; y1 = oneIDLocation.pStart.Y; y2 = oneIDLocation.pEnd.Y; if (y2 - y1 == 0) { continue; } if (y >= y1 && y <= y2 && x >= x1 - 5 && x <= x1 + 5) { secCode = oneIDLocation.sectionCode; return(secCode); } } return(secCode); }
public void setSectionLocation(SectionLocation _sectionLocation, bool _usePlexLocation, ImportManager.ProgressEventHandler _progressMessage) { string relativePath = RelativePath(_usePlexLocation ? _sectionLocation.PlexLocation : _sectionLocation.MappedLocation); MainSection = _sectionLocation.Owner(); MainSection.loadFromCache(false, true, _progressMessage); var folders = from folder in MainSection.folders where folder.Title.Equals(relativePath, StringComparison.OrdinalIgnoreCase) select folder; FolderSection = folders.FirstOrDefault(); char directorySeparatorFrom = PMSServer.DirectorySeparator == PMSBase.BACKWARD_SLASH ? PMSBase.FORWARD_SLASH : PMSBase.BACKWARD_SLASH; m_fullPlexFileName = FullFileName; if (!_usePlexLocation && !String.IsNullOrEmpty(_sectionLocation.MappedLocation)) { if (m_fullPlexFileName.StartsWith(_sectionLocation.MappedLocation, StringComparison.OrdinalIgnoreCase)) { m_fullPlexFileName = _sectionLocation.PlexLocation + m_fullPlexFileName.Remove(0, _sectionLocation.MappedLocation.Length); } m_fullPlexFileName = normalizePath(m_fullPlexFileName, directorySeparatorFrom, PMSServer.DirectorySeparator); } }
/// <summary> /// Serialize the export symbol table into the export section. /// </summary> /// <param name="location">RVA and file location of the .edata section</param> private BlobBuilder SerializeExportSection(SectionLocation sectionLocation) { _exportSymbols.MergeSort((es1, es2) => StringComparer.Ordinal.Compare(es1.Name, es2.Name)); BlobBuilder builder = new BlobBuilder(); int minOrdinal = int.MaxValue; int maxOrdinal = int.MinValue; // First, emit the name table and store the name RVA's for the individual export symbols // Also, record the ordinal range. foreach (ExportSymbol symbol in _exportSymbols) { symbol.NameRVAWhenPlaced = sectionLocation.RelativeVirtualAddress + builder.Count; builder.WriteUTF8(symbol.Name); builder.WriteByte(0); if (symbol.Ordinal < minOrdinal) { minOrdinal = symbol.Ordinal; } if (symbol.Ordinal > maxOrdinal) { maxOrdinal = symbol.Ordinal; } } // Emit the DLL name int dllNameRVA = sectionLocation.RelativeVirtualAddress + builder.Count; builder.WriteUTF8(_dllNameForExportDirectoryTable); builder.WriteByte(0); int[] addressTable = new int[maxOrdinal - minOrdinal + 1]; // Emit the name pointer table; it should be alphabetically sorted. // Also, we can now fill in the export address table as we've detected its size // in the previous pass. int namePointerTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count; foreach (ExportSymbol symbol in _exportSymbols) { builder.WriteInt32(symbol.NameRVAWhenPlaced); SymbolTarget symbolTarget = _symbolMap[symbol.Symbol]; Section symbolSection = _sections[symbolTarget.SectionIndex]; Debug.Assert(symbolSection.RVAWhenPlaced != 0); addressTable[symbol.Ordinal - minOrdinal] = symbolSection.RVAWhenPlaced + symbolTarget.Offset; } // Emit the ordinal table int ordinalTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count; foreach (ExportSymbol symbol in _exportSymbols) { builder.WriteUInt16((ushort)(symbol.Ordinal - minOrdinal)); } // Emit the address table int addressTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count; foreach (int addressTableEntry in addressTable) { builder.WriteInt32(addressTableEntry); } // Emit the export directory table int exportDirectoryTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count; // +0x00: reserved builder.WriteInt32(0); // +0x04: TODO: time/date stamp builder.WriteInt32(0); // +0x08: major version builder.WriteInt16(0); // +0x0A: minor version builder.WriteInt16(0); // +0x0C: DLL name RVA builder.WriteInt32(dllNameRVA); // +0x10: ordinal base builder.WriteInt32(minOrdinal); // +0x14: number of entries in the address table builder.WriteInt32(addressTable.Length); // +0x18: number of name pointers builder.WriteInt32(_exportSymbols.Count); // +0x1C: export address table RVA builder.WriteInt32(addressTableRVA); // +0x20: name pointer RVV builder.WriteInt32(namePointerTableRVA); // +0x24: ordinal table RVA builder.WriteInt32(ordinalTableRVA); int exportDirectorySize = sectionLocation.RelativeVirtualAddress + builder.Count - exportDirectoryTableRVA; _exportDirectoryEntry = new DirectoryEntry(relativeVirtualAddress: exportDirectoryTableRVA, size: exportDirectorySize); return(builder); }
/// <summary> /// Output the section with a given name. For sections existent in the source MSIL PE file /// (.text, optionally .rsrc and .reloc), we first copy the content of the input MSIL PE file /// and then call the section serialization callback to emit the extra content after the input /// section content. /// </summary> /// <param name="name">Section name</param> /// <param name="location">RVA and file location where the section will be put</param> /// <returns>Blob builder representing the section data</returns> protected override BlobBuilder SerializeSection(string name, SectionLocation location) { BlobBuilder sectionDataBuilder = null; int sectionStartRva = location.RelativeVirtualAddress; int outputSectionIndex = _sections.Length - 1; while (outputSectionIndex >= 0 && _sections[outputSectionIndex].Name != name) { outputSectionIndex--; } int injectedPadding = 0; if (_customPESectionAlignment != 0) { if (outputSectionIndex > 0) { sectionStartRva = Math.Max(sectionStartRva, _sectionRVAs[outputSectionIndex - 1] + _sectionRawSizes[outputSectionIndex - 1]); } int newSectionStartRva = AlignmentHelper.AlignUp(sectionStartRva, _customPESectionAlignment); int newSectionPointerToRawData = AlignmentHelper.AlignUp(location.PointerToRawData, _customPESectionAlignment); if (newSectionPointerToRawData > location.PointerToRawData) { sectionDataBuilder = new BlobBuilder(); injectedPadding = newSectionPointerToRawData - location.PointerToRawData; sectionDataBuilder.WriteBytes(1, injectedPadding); } sectionStartRva = newSectionStartRva; location = new SectionLocation(sectionStartRva, newSectionPointerToRawData); } if (!_target.IsWindows) { const int RVAAlign = 1 << RVABitsToMatchFilePos; if (outputSectionIndex > 0) { sectionStartRva = Math.Max(sectionStartRva, _sectionRVAs[outputSectionIndex - 1] + _sectionRawSizes[outputSectionIndex - 1]); // when assembly is stored in a singlefile bundle, an additional skew is introduced // as the streams inside the bundle are not necessarily page aligned as we do not // know the actual page size on the target system. // We may need one page gap of unused VA space before the next section starts. // We will assume the page size is <= RVAAlign sectionStartRva += RVAAlign; } sectionStartRva = AlignmentHelper.AlignUp(sectionStartRva, RVAAlign); int rvaAdjust = (location.PointerToRawData - sectionStartRva) & (RVAAlign - 1); sectionStartRva += rvaAdjust; location = new SectionLocation(sectionStartRva, location.PointerToRawData); } if (outputSectionIndex >= 0) { _sectionRVAs[outputSectionIndex] = sectionStartRva; _sectionPointerToRawData[outputSectionIndex] = location.PointerToRawData; } BlobBuilder extraData = _sectionBuilder.SerializeSection(name, location); if (extraData != null) { if (sectionDataBuilder == null) { // See above - there's a bug due to which LinkSuffix to an empty BlobBuilder screws up the blob content. sectionDataBuilder = extraData; } else { sectionDataBuilder.LinkSuffix(extraData); } } // Make sure the section has at least 1 byte, otherwise the PE emitter goes mad, // messes up the section map and corrups the output executable. if (sectionDataBuilder == null) { sectionDataBuilder = new BlobBuilder(); } if (sectionDataBuilder.Count == 0) { sectionDataBuilder.WriteByte(0); } int sectionRawSize = sectionDataBuilder.Count - injectedPadding; if (_customPESectionAlignment != 0) { // Align the end of the section to the padding offset int count = AlignmentHelper.AlignUp(sectionRawSize, _customPESectionAlignment); sectionDataBuilder.WriteBytes(0, count - sectionRawSize); sectionRawSize = count; } if (outputSectionIndex >= 0) { _sectionRawSizes[outputSectionIndex] = sectionRawSize; } return(sectionDataBuilder); }
protected internal override void Serialize(BlobBuilder builder, SectionLocation location) { throw new NotImplementedException(); }
protected internal override void Serialize(BlobBuilder builder, SectionLocation location) { builder.WriteInt32(0x12345678); builder.WriteInt32(location.PointerToRawData); builder.WriteInt32(location.RelativeVirtualAddress); }
internal protected override void Serialize(BlobBuilder builder, SectionLocation location) { builder.WriteInt32(0x12345678); builder.WriteInt32(location.PointerToRawData); builder.WriteInt32(location.RelativeVirtualAddress); }
/// <summary> /// Traverse blocks within a single section and use them to calculate final layout /// of the given section. /// </summary> /// <param name="name">Section to serialize</param> /// <param name="sectionLocation">Logical section address within the output PE file</param> /// <param name="sectionStartRva">Section start RVA</param> /// <returns></returns> public BlobBuilder SerializeSection(string name, SectionLocation sectionLocation, int sectionStartRva) { if (name == ".reloc") { return(SerializeRelocationSection(sectionLocation)); } if (name == ".edata") { return(SerializeExportSection(sectionLocation)); } BlobBuilder serializedSection = null; // Locate logical section index by name foreach (Section section in _sections.Where((sec) => sec.Name == name)) { // Calculate alignment padding int alignedRVA = (sectionLocation.RelativeVirtualAddress + section.Alignment - 1) & -section.Alignment; int padding = alignedRVA - sectionLocation.RelativeVirtualAddress; if (padding > 0) { if (serializedSection == null) { serializedSection = new BlobBuilder(); } serializedSection.WriteBytes(0, padding); sectionLocation = new SectionLocation( sectionLocation.RelativeVirtualAddress + padding, sectionLocation.PointerToRawData + padding); } // Place the section section.RVAWhenPlaced = sectionLocation.RelativeVirtualAddress; section.FilePosWhenPlaced = sectionLocation.PointerToRawData; // Place section start symbol node if available if (_sectionStartNodeLookup != null) { ISymbolNode sectionStartNode = _sectionStartNodeLookup(name); if (sectionStartNode != null) { // We back-compensate the start section symbol to point at the beginning of the original // section data. This is needed to access RVA field data in the embedded MSIL. _symbolMap.Add(sectionStartNode, new SymbolTarget(section.Index, sectionStartRva - section.RVAWhenPlaced)); } } if (section.Content.Count != 0) { sectionLocation = new SectionLocation( sectionLocation.RelativeVirtualAddress + section.Content.Count, sectionLocation.PointerToRawData + section.Content.Count); if (serializedSection == null) { serializedSection = section.Content; } else { serializedSection.LinkSuffix(section.Content); } } } return(serializedSection); }
/// <summary> /// Output the section with a given name. For sections existent in the source MSIL PE file /// (.text, optionally .rsrc and .reloc), we first copy the content of the input MSIL PE file /// and then call the section serialization callback to emit the extra content after the input /// section content. /// </summary> /// <param name="name">Section name</param> /// <param name="location">RVA and file location where the section will be put</param> /// <returns>Blob builder representing the section data</returns> protected override BlobBuilder SerializeSection(string name, SectionLocation location) { BlobBuilder sectionDataBuilder = null; int sectionStartRva = location.RelativeVirtualAddress; int outputSectionIndex = _sections.Length - 1; while (outputSectionIndex >= 0 && _sections[outputSectionIndex].Name != name) { outputSectionIndex--; } if (!_target.IsWindows) { if (outputSectionIndex > 0) { sectionStartRva = Math.Max(sectionStartRva, _sectionRVAs[outputSectionIndex - 1] + _sectionRawSizes[outputSectionIndex - 1]); } const int RVAAlign = 1 << RVABitsToMatchFilePos; sectionStartRva = AlignmentHelper.AlignUp(sectionStartRva, RVAAlign); int rvaAdjust = (location.PointerToRawData - sectionStartRva) & (RVAAlign - 1); sectionStartRva += rvaAdjust; location = new SectionLocation(sectionStartRva, location.PointerToRawData); } if (outputSectionIndex >= 0) { _sectionRVAs[outputSectionIndex] = sectionStartRva; } int inputSectionIndex = _peReader.PEHeaders.SectionHeaders.Count() - 1; while (inputSectionIndex >= 0 && _peReader.PEHeaders.SectionHeaders[inputSectionIndex].Name != name) { inputSectionIndex--; } if (inputSectionIndex >= 0) { SectionHeader sectionHeader = _peReader.PEHeaders.SectionHeaders[inputSectionIndex]; int sectionOffset = (_peReader.IsLoadedImage ? sectionHeader.VirtualAddress : sectionHeader.PointerToRawData); int rvaDelta = location.RelativeVirtualAddress - sectionHeader.VirtualAddress; _sectionRvaDeltas.Add(new SectionRVADelta( startRVA: sectionHeader.VirtualAddress, endRVA: sectionHeader.VirtualAddress + Math.Max(sectionHeader.VirtualSize, sectionHeader.SizeOfRawData), deltaRVA: rvaDelta)); int bytesToRead = Math.Min(sectionHeader.SizeOfRawData, sectionHeader.VirtualSize); BlobReader inputSectionReader = _peReader.GetEntireImage().GetReader(sectionOffset, bytesToRead); if (name == RsrcSectionName) { // There seems to be a bug in BlobBuilder - when we LinkSuffix to an empty blob builder, // the blob data goes out of sync and WriteContentTo outputs garbage. sectionDataBuilder = PEResourceHelper.Relocate(inputSectionReader, rvaDelta); } int alignedSize = sectionHeader.VirtualSize; // When custom section data is present, align the section size to 4K to prevent // pre-generated MSIL relocations from tampering with native relocations. if (_customSections.Contains(name)) { alignedSize = (alignedSize + 0xFFF) & ~0xFFF; } if (sectionDataBuilder != null) { if (alignedSize > bytesToRead) { // If the number of bytes read from the source PE file is less than the virtual size, // zero pad to the end of virtual size before emitting extra section data sectionDataBuilder.WriteBytes(0, alignedSize - bytesToRead); } location = new SectionLocation( location.RelativeVirtualAddress + sectionDataBuilder.Count, location.PointerToRawData + sectionDataBuilder.Count); } } BlobBuilder extraData = _sectionBuilder.SerializeSection(name, location); if (extraData != null) { if (sectionDataBuilder == null) { // See above - there's a bug due to which LinkSuffix to an empty BlobBuilder screws up the blob content. sectionDataBuilder = extraData; } else { sectionDataBuilder.LinkSuffix(extraData); } } // Make sure the section has at least 1 byte, otherwise the PE emitter goes mad, // messes up the section map and corrups the output executable. if (sectionDataBuilder == null) { sectionDataBuilder = new BlobBuilder(); } if (sectionDataBuilder.Count == 0) { sectionDataBuilder.WriteByte(0); } if (outputSectionIndex >= 0) { _sectionRawSizes[outputSectionIndex] = sectionDataBuilder.Count; } return(sectionDataBuilder); }
/// <summary> /// Output the section with a given name. For sections existent in the source MSIL PE file /// (.text, optionally .rsrc and .reloc), we first copy the content of the input MSIL PE file /// and then call the section serialization callback to emit the extra content after the input /// section content. /// </summary> /// <param name="name">Section name</param> /// <param name="location">RVA and file location where the section will be put</param> /// <returns>Blob builder representing the section data</returns> protected override BlobBuilder SerializeSection(string name, SectionLocation location) { BlobBuilder sectionDataBuilder = null; bool haveCustomSection = _customSections.Contains(name); int sectionIndex = _peReader.PEHeaders.SectionHeaders.Count() - 1; int sectionStartRva = location.RelativeVirtualAddress; while (sectionIndex >= 0 && _peReader.PEHeaders.SectionHeaders[sectionIndex].Name != name) { sectionIndex--; } if (sectionIndex >= 0) { SectionHeader sectionHeader = _peReader.PEHeaders.SectionHeaders[sectionIndex]; int sectionOffset = (_peReader.IsLoadedImage ? sectionHeader.VirtualAddress : sectionHeader.PointerToRawData); int rvaDelta = location.RelativeVirtualAddress - sectionHeader.VirtualAddress; _sectionRvaDeltas.Add(new SectionRVADelta( startRVA: sectionHeader.VirtualAddress, endRVA: sectionHeader.VirtualAddress + Math.Max(sectionHeader.VirtualSize, sectionHeader.SizeOfRawData), deltaRVA: rvaDelta)); unsafe { int bytesToRead = Math.Min(sectionHeader.SizeOfRawData, sectionHeader.VirtualSize); BlobReader inputSectionReader = _peReader.GetEntireImage().GetReader(sectionOffset, bytesToRead); if (name == ".rsrc") { // There seems to be a bug in BlobBuilder - when we LinkSuffix to an empty blob builder, // the blob data goes out of sync and WriteContentTo outputs garbage. sectionDataBuilder = PEResourceHelper.Relocate(inputSectionReader, rvaDelta); } else { sectionDataBuilder = new BlobBuilder(); sectionDataBuilder.WriteBytes(inputSectionReader.CurrentPointer, inputSectionReader.RemainingBytes); int corHeaderRvaDelta = _peReader.PEHeaders.PEHeader.CorHeaderTableDirectory.RelativeVirtualAddress - sectionHeader.VirtualAddress; if (corHeaderRvaDelta >= 0 && corHeaderRvaDelta < bytesToRead) { // Assume COR header resides in this section, deserialize it and store its location _corHeaderFileOffset = location.PointerToRawData + corHeaderRvaDelta; inputSectionReader.Offset = corHeaderRvaDelta; _corHeaderBuilder = new CorHeaderBuilder(ref inputSectionReader); } } int alignedSize = sectionHeader.VirtualSize; // When custom section data is present, align the section size to 4K to prevent // pre-generated MSIL relocations from tampering with native relocations. if (_customSections.Contains(name)) { alignedSize = (alignedSize + 0xFFF) & ~0xFFF; } if (alignedSize > bytesToRead) { // If the number of bytes read from the source PE file is less than the virtual size, // zero pad to the end of virtual size before emitting extra section data sectionDataBuilder.WriteBytes(0, alignedSize - bytesToRead); } location = new SectionLocation( location.RelativeVirtualAddress + sectionDataBuilder.Count, location.PointerToRawData + sectionDataBuilder.Count); } } if (_sectionSerializer != null) { BlobBuilder extraData = _sectionSerializer(name, location, sectionStartRva); if (extraData != null) { if (sectionDataBuilder == null) { // See above - there's a bug due to which LinkSuffix to an empty BlobBuilder screws up the blob content. sectionDataBuilder = extraData; } else { sectionDataBuilder.LinkSuffix(extraData); } } } // Make sure the section has at least 1 byte, otherwise the PE emitter goes mad, // messes up the section map and corrups the output executable. if (sectionDataBuilder == null) { sectionDataBuilder = new BlobBuilder(); } if (sectionDataBuilder.Count == 0) { sectionDataBuilder.WriteByte(0); } return(sectionDataBuilder); }
/// <summary> /// Output the section with a given name. For sections existent in the source MSIL PE file /// (.text, optionally .rsrc and .reloc), we first copy the content of the input MSIL PE file /// and then call the section serialization callback to emit the extra content after the input /// section content. /// </summary> /// <param name="name">Section name</param> /// <param name="location">RVA and file location where the section will be put</param> /// <returns>Blob builder representing the section data</returns> protected override BlobBuilder SerializeSection(string name, SectionLocation location) { BlobBuilder sectionDataBuilder = null; int sectionStartRva = location.RelativeVirtualAddress; int outputSectionIndex = _sections.Length - 1; while (outputSectionIndex >= 0 && _sections[outputSectionIndex].Name != name) { outputSectionIndex--; } int injectedPadding = 0; if (_customPESectionAlignment != 0) { if (outputSectionIndex > 0) { sectionStartRva = Math.Max(sectionStartRva, _sectionRVAs[outputSectionIndex - 1] + _sectionRawSizes[outputSectionIndex - 1]); } int newSectionStartRva = AlignmentHelper.AlignUp(sectionStartRva, _customPESectionAlignment); int newSectionPointerToRawData = AlignmentHelper.AlignUp(location.PointerToRawData, _customPESectionAlignment); if (newSectionPointerToRawData > location.PointerToRawData) { sectionDataBuilder = new BlobBuilder(); injectedPadding = newSectionPointerToRawData - location.PointerToRawData; sectionDataBuilder.WriteBytes(1, injectedPadding); } sectionStartRva = newSectionStartRva; location = new SectionLocation(sectionStartRva, newSectionPointerToRawData); } if (!_target.IsWindows) { if (outputSectionIndex > 0) { sectionStartRva = Math.Max(sectionStartRva, _sectionRVAs[outputSectionIndex - 1] + _sectionRawSizes[outputSectionIndex - 1]); } const int RVAAlign = 1 << RVABitsToMatchFilePos; sectionStartRva = AlignmentHelper.AlignUp(sectionStartRva, RVAAlign); int rvaAdjust = (location.PointerToRawData - sectionStartRva) & (RVAAlign - 1); sectionStartRva += rvaAdjust; location = new SectionLocation(sectionStartRva, location.PointerToRawData); } if (outputSectionIndex >= 0) { _sectionRVAs[outputSectionIndex] = sectionStartRva; _sectionPointerToRawData[outputSectionIndex] = location.PointerToRawData; } BlobBuilder extraData = _sectionBuilder.SerializeSection(name, location); if (extraData != null) { if (sectionDataBuilder == null) { // See above - there's a bug due to which LinkSuffix to an empty BlobBuilder screws up the blob content. sectionDataBuilder = extraData; } else { sectionDataBuilder.LinkSuffix(extraData); } } // Make sure the section has at least 1 byte, otherwise the PE emitter goes mad, // messes up the section map and corrups the output executable. if (sectionDataBuilder == null) { sectionDataBuilder = new BlobBuilder(); } if (sectionDataBuilder.Count == 0) { sectionDataBuilder.WriteByte(0); } int sectionRawSize = sectionDataBuilder.Count - injectedPadding; if (_customPESectionAlignment != 0) { // Align the end of the section to the padding offset int count = AlignmentHelper.AlignUp(sectionRawSize, _customPESectionAlignment); sectionDataBuilder.WriteBytes(0, count - sectionRawSize); sectionRawSize = count; } if (outputSectionIndex >= 0) { _sectionRawSizes[outputSectionIndex] = sectionRawSize; } return(sectionDataBuilder); }
internal protected override void Serialize(BlobBuilder builder, SectionLocation location) { throw new NotImplementedException(); }