public DotNetResourceProviderImpl(HexBufferFile file, PeHeaders peHeaders, DotNetMetadataHeaders metadataHeaders, HexSpan?resourcesSpan) : base(file) { if (peHeaders == null) { throw new ArgumentNullException(nameof(peHeaders)); } this.peHeaders = peHeaders; if (metadataHeaders?.TablesStream != null && resourcesSpan != null) { Debug.Assert(file.Span.Contains(resourcesSpan.Value)); // Verified by caller ResourcesSpan = resourcesSpan.Value; resourceInfos = CreateResourceInfos(file, metadataHeaders.TablesStream.MDTables[(int)Table.ManifestResource], metadataHeaders.StringsStream); } else { resourceInfos = Array.Empty <ResourceInfo>(); } if (resourceInfos.Length > 0) { var lastEnd = resourceInfos[0].Span.Start; var filesToCreate = new List <BufferFileOptions>(); foreach (var info in resourceInfos) { if (info.Span.Start < lastEnd) { continue; } filesToCreate.Add(new BufferFileOptions(HexSpan.FromBounds(info.Span.Start + 4, info.Span.End), info.FilteredName, string.Empty, defaultTags)); lastEnd = info.Span.End; } if (filesToCreate.Count > 0) { file.CreateFiles(filesToCreate.ToArray()); } } }
DotNetMultiFileResourcesImpl(HexBufferFile file, Bit7String?resourceTypeSpan, Bit7String?resourceSetTypeSpan, HexPosition versionPosition, HexSpan paddingSpan, Bit7String[] typeNames, int numResources, HexPosition dataSectionPosition, HexPosition nameSectionPosition) : base(file) { DataSectionPosition = dataSectionPosition; var headerSpan = new HexBufferSpan(file.Buffer, HexSpan.FromBounds(file.Span.Start, nameSectionPosition)); Header = new DotNetMultiFileResourceHeaderDataImpl(headerSpan, resourceTypeSpan, resourceSetTypeSpan, versionPosition, paddingSpan, typeNames, numResources); ResourceInfo[] resourceInfos; dataArray = CreateDataArray(typeNames, numResources, paddingSpan.End, dataSectionPosition, nameSectionPosition, out resourceInfos); var files = new List <BufferFileOptions>(resourceInfos.Length); foreach (var info in resourceInfos) { var data = info.ResData; if (data == null) { continue; } if (data.NestedFileData.IsEmpty) { continue; } if (!IsNestedFile(data.TypeCode)) { continue; } var name = Encoding.Unicode.GetString(File.Buffer.ReadBytes(info.UnicodeName.StringSpan)); var filteredName = NameUtils.FilterName(name); var tags = data.TypeCode >= ResourceTypeCode.UserTypes ? tagsSerialized : tagsNonSerialized; files.Add(new BufferFileOptions(data.NestedFileData, filteredName, string.Empty, tags)); } if (files.Count > 0) { File.CreateFiles(files.ToArray()); } }
public override StructureProvider?Create(HexBufferFile file) => new MultiResourceStructureProvider(file);
/// <summary> /// Gets the PE file layout /// </summary> /// <param name="file">File. This can be a nested file.</param> /// <returns></returns> public abstract PeFileLayout GetLayout(HexBufferFile file);
public abstract PENode FindPENode(HexBufferFile file);
public override HexIndexes[] GetSubStructureIndexes(HexBufferFile file, ComplexData structure, HexPosition position) { var body = structure as DotNetMethodBody; if (body != null) { if (body.Kind == DotNetMethodBodyKind.Tiny) { return(Array.Empty <HexIndexes>()); } var fatBody = body as FatMethodBody; if (fatBody != null) { if (fatBody.EHTable == null) { return(subStructFatWithoutEH); } return(subStructFatWithEH); } } if (structure is DotNetEmbeddedResource) { return(Array.Empty <HexIndexes>()); } var multiResource = structure as MultiResourceDataHeaderData; if (multiResource != null) { if (multiResource is MultiResourceSimplDataHeaderData || multiResource is MultiResourceStringDataHeaderData) { return(multiResourceFields2); } if (multiResource is MultiResourceArrayDataHeaderData) { return(multiResourceFields3); } Debug.Fail($"Unknown multi res type: {multiResource.GetType()}"); } var stringsRec = structure as StringsHeapRecordData; if (stringsRec?.Terminator != null) { return(stringsRecordIndexes); } var usRec = structure as USHeapRecordData; if (usRec != null) { if (usRec.TerminalByte != null) { return(usRecordIndexes3); } return(usRecordIndexes2); } if (structure is BlobHeapRecordData) { return(blobRecordIndexes2); } return(null); }
static DotNetMultiFileResourcesImpl?TryReadCore(HexBufferFile file) { if (file is null) { throw new ArgumentNullException(nameof(file)); } if (file.Span.Length < 0x1C) { return(null); } var buffer = file.Buffer; var pos = file.Span.Start; if (buffer.ReadUInt32(pos) != 0xBEEFCACE) { return(null); } int resMgrHeaderVersion = buffer.ReadInt32(pos + 4); int headerSize = buffer.ReadInt32(pos + 8); if (resMgrHeaderVersion < 0 || headerSize < 0) { return(null); } pos += 0xC; Bit7String?resourceTypeSpan = null; Bit7String?resourceSetTypeSpan = null; if (resMgrHeaderVersion > 1) { pos += headerSize; } else { resourceTypeSpan = ReadBit7String(buffer, ref pos, file.Span.End); resourceSetTypeSpan = ReadBit7String(buffer, ref pos, file.Span.End); if (resourceTypeSpan is null || resourceSetTypeSpan is null) { return(null); } var resourceType = Encoding.UTF8.GetString(buffer.ReadBytes(resourceTypeSpan.Value.StringSpan)); if (!Regex.IsMatch(resourceType, @"^System\.Resources\.ResourceReader,\s*mscorlib,")) { return(null); } } var versionPosition = pos; if (pos + 0x0C > file.Span.End) { return(null); } uint version = buffer.ReadUInt32(pos); if (version != 2) { return(null); //TODO: Support version 1 } int numResources = buffer.ReadInt32(pos + 4); int numTypes = buffer.ReadInt32(pos + 8); if (numResources < 0 || numTypes < 0) { return(null); } pos += 0x0C; var typeNames = new Bit7String[numTypes]; for (int i = 0; i < typeNames.Length; i++) { var info = ReadBit7String(buffer, ref pos, file.Span.End); if (info is null) { return(null); } typeNames[i] = info.Value; } var paddingStart = pos; pos = file.AlignUp(pos, 8); var paddingSpan = HexSpan.FromBounds(paddingStart, pos); if (pos + (ulong)numResources * 8 + 4 > file.Span.End) { return(null); } pos += (ulong)numResources * 8; int dataSectionOffset = buffer.ReadInt32(pos); pos += 4; if (dataSectionOffset < 0 || dataSectionOffset < (pos - file.Span.Start)) { return(null); } // Use > and not >= in case it's an empty resource if (dataSectionOffset > file.Span.Length) { return(null); } var dataSectionPosition = file.Span.Start + dataSectionOffset; var nameSectionPosition = pos; return(new DotNetMultiFileResourcesImpl(file, resourceTypeSpan, resourceSetTypeSpan, versionPosition, paddingSpan, typeNames, numResources, dataSectionPosition, nameSectionPosition)); }
/// <summary> /// Constructor /// </summary> /// <param name="file">File</param> protected DotNetResourceProvider(HexBufferFile file) => File = file ?? throw new ArgumentNullException(nameof(file));
public DotNetStructureProvider(HexBufferFile file) => this.file = file ?? throw new ArgumentNullException(nameof(file));
DotNetMetadataHeaderReader(HexBufferFile file, HexSpan mdSpan) { this.file = file ?? throw new ArgumentNullException(nameof(file)); MetadataSpan = mdSpan; }
public DotNetHeapsReader(HexBufferFile file, DotNetMetadataHeaderData mdHeader, StorageStreamHeader[] storageStreamHeaders) { this.file = file ?? throw new ArgumentNullException(nameof(file)); this.mdHeader = mdHeader ?? throw new ArgumentNullException(nameof(mdHeader)); this.storageStreamHeaders = storageStreamHeaders ?? throw new ArgumentNullException(nameof(storageStreamHeaders)); }
/// <summary> /// Constructor /// </summary> /// <param name="file">File</param> protected DotNetMultiFileResources(HexBufferFile file) => File = file ?? throw new ArgumentNullException(nameof(file));
DotNetMultiFileResourcesImpl(HexBufferFile file, in Bit7String?resourceTypeSpan, in Bit7String?resourceSetTypeSpan, HexPosition versionPosition, HexSpan paddingSpan, Bit7String[] typeNames, int numResources, HexPosition dataSectionPosition, HexPosition nameSectionPosition)
public HexFieldReference(HexBufferFile file, HexVM structure, HexField field) { File = file ?? throw new ArgumentNullException(nameof(file)); Structure = structure ?? throw new ArgumentNullException(nameof(structure)); Field = field ?? throw new ArgumentNullException(nameof(field)); }
public override StructureProvider Create(HexBufferFile file) => new PeStructureProvider(file, peFileLayoutProviders);
public override StructureProvider?Create(HexBufferFile file) => new DotNetStructureProvider(file);
/// <summary> /// Creates a <see cref="BufferFileHeadersProvider"/> or returns null /// </summary> /// <param name="file">File</param> /// <returns></returns> public abstract BufferFileHeadersProvider Create(HexBufferFile file);
public abstract DsDocumentNode Find(HexBufferFile file);
public PEStructureProviderImpl(HexBufferFile file, PeHeaders peHeaders) { if (file == null) { throw new ArgumentNullException(nameof(file)); } if (peHeaders == null) { throw new ArgumentNullException(nameof(peHeaders)); } if (peHeaders != file.GetHeaders <PeHeaders>()) { throw new ArgumentException(); } this.file = file; this.peHeaders = peHeaders; var buffer = file.Buffer; imageDosHeader = new ImageDosHeaderVM(buffer, peHeaders.DosHeader); imageFileHeader = new ImageFileHeaderVM(buffer, peHeaders.FileHeader); if (peHeaders.OptionalHeader.Is32Bit) { imageOptionalHeader = new ImageOptionalHeader32VM(buffer, (PeOptionalHeader32Data)peHeaders.OptionalHeader); } else { imageOptionalHeader = new ImageOptionalHeader64VM(buffer, (PeOptionalHeader64Data)peHeaders.OptionalHeader); } sections = new ImageSectionHeaderVM[peHeaders.Sections.FieldCount]; for (int i = 0; i < sections.Length; i++) { sections[i] = new ImageSectionHeaderVM(buffer, peHeaders.Sections[i].Data); } var dnHeaders = file.GetHeaders <DotNetHeaders>(); storageStreams = Array.Empty <StorageStreamVM>(); if (dnHeaders != null) { imageCor20Header = new ImageCor20HeaderVM(buffer, dnHeaders.Cor20); var mdHeaders = dnHeaders.MetadataHeaders; if (mdHeaders != null) { storageSignature = new StorageSignatureVM(buffer, mdHeaders.MetadataHeader); storageHeader = new StorageHeaderVM(buffer, mdHeaders.MetadataHeader); storageStreams = new StorageStreamVM[mdHeaders.Streams.Count]; for (int i = 0; i < storageStreams.Length; i++) { var ssh = mdHeaders.MetadataHeader.StreamHeaders.Data[i].Data; var heap = mdHeaders.Streams[i]; storageStreams[i] = new StorageStreamVM(buffer, heap, ssh, i); } var metaDataTables = new MetaDataTableVM[0x40]; if (mdHeaders.TablesStream != null) { tablesStream = new TablesStreamVM(buffer, mdHeaders.TablesStream, metaDataTables); var stringsHeapSpan = GetSpan(mdHeaders.StringsStream); var guidHeapSpan = GetSpan(mdHeaders.GUIDStream); foreach (var mdTable in mdHeaders.TablesStream.MDTables) { if (mdTable.Rows != 0) { metaDataTables[(int)mdTable.Table] = MetaDataTableVM.Create(buffer, tablesStream, mdTable, stringsHeapSpan, guidHeapSpan); } } } } } }
HexSpan?GetFieldReferenceSpan(HexBufferFile file, FatMethodBody fatBody, HexPosition position) { var ehTable = fatBody.EHTable; if (ehTable != null) { if (!ehTable.Data.Span.Span.Contains(position)) { return(null); } if (ehTable.Data.IsSmall) { var smallTable = (SmallExceptionHandlerTable)ehTable.Data; if (!smallTable.Clauses.Data.Span.Span.Contains(position)) { return(null); } var clause = (SmallExceptionClause)smallTable.Clauses.Data.GetFieldByPosition(position)?.Data; if (clause == null) { return(null); } HexSpan?span; if ((span = TryGetSpan(fatBody, position, clause.TryOffset.Data, clause.TryLength.Data)) != null) { return(span); } if ((span = TryGetSpan(fatBody, position, clause.HandlerOffset.Data, clause.HandlerLength.Data)) != null) { return(span); } if (clause.ClassTokenOrFilterOffset.Data.Span.Span.Contains(position)) { if (clause.Flags.Data.ReadValue() == 0) { return(TryGetTokenSpan(file, clause.ClassTokenOrFilterOffset.Data.ReadValue())); } else { return(TryGetSpan(fatBody, clause.ClassTokenOrFilterOffset.Data.ReadValue(), 1)); } } } else { var fatTable = (FatExceptionHandlerTable)ehTable.Data; if (!fatTable.Clauses.Data.Span.Span.Contains(position)) { return(null); } var clause = (FatExceptionClause)fatTable.Clauses.Data.GetFieldByPosition(position)?.Data; if (clause == null) { return(null); } HexSpan?span; if ((span = TryGetSpan(fatBody, position, clause.TryOffset.Data, clause.TryLength.Data)) != null) { return(span); } if ((span = TryGetSpan(fatBody, position, clause.HandlerOffset.Data, clause.HandlerLength.Data)) != null) { return(span); } if (clause.ClassTokenOrFilterOffset.Data.Span.Span.Contains(position)) { if (clause.Flags.Data.ReadValue() == 0) { return(TryGetTokenSpan(file, clause.ClassTokenOrFilterOffset.Data.ReadValue())); } else { return(TryGetSpan(fatBody, clause.ClassTokenOrFilterOffset.Data.ReadValue(), 1)); } } } return(null); } return(null); }
public abstract PEStructureProvider TryGetProvider(HexBufferFile file);
public static PEStructure TryCreate(PEStructureProviderFactory peStructureProviderFactory, HexBufferFile file) { if (file.Properties.TryGetProperty(typeof(PEStructure), out PEStructure peStructure)) { return(peStructure); } var provider = peStructureProviderFactory.TryGetProvider(file); if (provider != null) { peStructure = new PEStructure(provider); } file.Properties.AddProperty(typeof(PEStructure), peStructure); return(peStructure); }
public PeStructureProvider(HexBufferFile file, Lazy <PeFileLayoutProvider, VSUTIL.IOrderable>[] peFileLayoutProviders) { this.file = file ?? throw new ArgumentNullException(nameof(file)); this.peFileLayoutProviders = peFileLayoutProviders ?? throw new ArgumentNullException(nameof(peFileLayoutProviders)); }