public DotNetResourceProviderImpl(HexBufferFile file, PeHeaders peHeaders, DotNetMetadataHeaders metadataHeaders, HexSpan?resourcesSpan) : base(file) { this.peHeaders = peHeaders ?? throw new ArgumentNullException(nameof(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()); } } }
public DotNetHeadersImpl(PeHeaders peHeaders, DotNetCor20Data cor20, DotNetMetadataHeaders metadataHeaders, VirtualArrayData <ByteData> strongNameSignature, DotNetMethodProvider methodProvider, DotNetResourceProvider resourceProvider) { if (peHeaders == null) { throw new ArgumentNullException(nameof(peHeaders)); } if (cor20 == null) { throw new ArgumentNullException(nameof(cor20)); } if (methodProvider == null) { throw new ArgumentNullException(nameof(methodProvider)); } if (resourceProvider == null) { throw new ArgumentNullException(nameof(resourceProvider)); } PeHeaders = peHeaders; Cor20 = cor20; MetadataHeaders = metadataHeaders; StrongNameSignature = strongNameSignature; MethodProvider = methodProvider; ResourceProvider = resourceProvider; }
private int ReadSecurityCookieOffset() { // Calculate the offset of the load config table if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.LoadConfigTableDirectory, out var loadConfigTableOffset)) { return(0); } if (PeHeaders.PEHeader.Magic == PEMagic.PE32) { // Read the load config table var loadConfigTable = MemoryMarshal.Read <ImageLoadConfigDirectory32>(PeBytes.Slice(loadConfigTableOffset).Span); // Calculate the offset of the security cookie return(loadConfigTable.SecurityCookie == 0 ? 0 : loadConfigTable.SecurityCookie - (int)PeHeaders.PEHeader.ImageBase); } else { // Read the load config table var loadConfigTable = MemoryMarshal.Read <ImageLoadConfigDirectory64>(PeBytes.Slice(loadConfigTableOffset).Span); // Calculate the offset of the security cookie return(loadConfigTable.SecurityCookie == 0 ? 0 : (int)(loadConfigTable.SecurityCookie - (long)PeHeaders.PEHeader.ImageBase)); } }
public GoToMetadataVM(HexBuffer buffer, DotNetMetadataHeaders mdHeaders, PeHeaders peHeaders, uint value) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (mdHeaders == null) { throw new ArgumentNullException(nameof(mdHeaders)); } this.peHeaders = peHeaders; offsetTokenVM = new OffsetTokenVM(buffer, mdHeaders, peHeaders, value, a => HasErrorUpdated()); GoToMetadataCollection = new ObservableCollection <GoToMetadataKindVM>(); GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.Table, dnSpy_Resources.GoToMetadataToken, dnSpy_Resources.ShortCutKeyCtrl1)); if (peHeaders != null) { GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.MemberRva, dnSpy_Resources.GoToMetadataMethodBody, dnSpy_Resources.ShortCutKeyCtrl2)); } GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.Blob, "#Blob", dnSpy_Resources.ShortCutKeyCtrl3)); GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.Strings, "#Strings", dnSpy_Resources.ShortCutKeyCtrl4)); GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.US, "#US", dnSpy_Resources.ShortCutKeyCtrl5)); GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.GUID, "#GUID", dnSpy_Resources.ShortCutKeyCtrl6)); selectedItem = GoToMetadataCollection[0]; offsetTokenVM.GoToMetadataKind = GoToMetadataKind; }
void ReadStrongNameSignature(PeHeaders peHeaders, HexSpan?span) { if (span == null) { return; } strongNameSignature = ArrayData.CreateVirtualByteArray(new HexBufferSpan(file.Buffer, span.Value), name: "STRONGNAMESIGNATURE"); }
void ReadDotNetMetadataHeader(PeHeaders peHeaders, HexSpan?dir) { if (dir == null) { return; } ReadDotNetMetadataHeader(dir.Value); }
internal PeParser(string dllPath) { _dllBuffer = LocalMemoryTools.StoreBytesInBuffer(File.ReadAllBytes(dllPath)); _peHeaders = new PeHeaders(); ReadPeHeaders(); }
internal PeParser(byte[] dllBytes) { _dllBuffer = LocalMemoryTools.StoreBytesInBuffer(dllBytes); _peHeaders = new PeHeaders(); ReadPeHeaders(); }
internal PortableExecutableParser(string dllPath) { _dllBuffer = MemoryTools.StoreBytesInBuffer(File.ReadAllBytes(dllPath)); _peHeaders = new PeHeaders(); ReadHeaders(); }
public OffsetTokenVM(HexBuffer buffer, DotNetMetadataHeaders mdHeaders, PeHeaders peHeaders, uint value, Action <DataFieldVM> onUpdated) : base(onUpdated, uint.MinValue, uint.MaxValue, null) { SetValueFromConstructor(value); this.buffer = buffer; this.mdHeaders = mdHeaders; this.peHeaders = peHeaders; }
internal PortableExecutableParser(byte[] dllBytes) { _dllBuffer = MemoryTools.StoreBytesInBuffer(dllBytes); _peHeaders = new PeHeaders(); ReadHeaders(); }
internal PeParser(string dllPath) { _dllBufferHandle = GCHandle.Alloc(File.ReadAllBytes(dllPath), GCHandleType.Pinned); _dllBuffer = _dllBufferHandle.AddrOfPinnedObject(); _peHeaders = new PeHeaders(); ReadPeHeaders(); }
internal PeParser(byte[] dllBytes) { _dllBufferHandle = GCHandle.Alloc(dllBytes.Clone(), GCHandleType.Pinned); _dllBuffer = _dllBufferHandle.AddrOfPinnedObject(); _peHeaders = new PeHeaders(); ReadPeHeaders(); }
public DotNetResourceProviderImpl(HexBufferFile file, PeHeaders peHeaders, DotNetMetadataHeaders?metadataHeaders, HexSpan?resourcesSpan) : base(file) { this.peHeaders = peHeaders ?? throw new ArgumentNullException(nameof(peHeaders)); if (metadataHeaders?.TablesStream is not null && resourcesSpan is not 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); }
public DotNetMethodProviderImpl(HexBufferFile file, PeHeaders peHeaders, TablesHeap tablesHeap) : base(file) { if (file == null) { throw new ArgumentNullException(nameof(file)); } this.peHeaders = peHeaders ?? throw new ArgumentNullException(nameof(peHeaders)); methodBodyRvas = CreateMethodBodyRvas(tablesHeap?.MDTables[(int)Table.Method]); methodBodiesSpan = GetMethodBodiesSpan(methodBodyRvas); }
private IEnumerable <BaseRelocation> ReadBaseRelocations() { // Calculate the offset of the first base relocation block if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.BaseRelocationTableDirectory, out var currentRelocationBlockOffset)) { yield break; } while (true) { // Read the current base relocation block var relocationBlock = MemoryMarshal.Read <ImageBaseRelocation>(PeBytes.Slice(currentRelocationBlockOffset).Span); if (relocationBlock.SizeOfBlock == 0) { yield break; } // Read the base relocations from the base relocation block var relocationBlockSize = (relocationBlock.SizeOfBlock - Unsafe.SizeOf <ImageBaseRelocation>()) / sizeof(short); var relocationBlockOffset = RvaToOffset(relocationBlock.VirtualAddress); for (var relocationIndex = 0; relocationIndex < relocationBlockSize; relocationIndex++) { // Read the base relocation var relocationOffset = currentRelocationBlockOffset + Unsafe.SizeOf <ImageBaseRelocation>() + sizeof(short) * relocationIndex; var relocation = MemoryMarshal.Read <ushort>(PeBytes.Slice(relocationOffset).Span); // The offset is located in the upper 4 bits of the base relocation var offset = relocation & 0xFFF; // The type is located in the lower 12 bits of the base relocation var type = relocation >> 12; yield return(new BaseRelocation(relocationBlockOffset + offset, (BaseRelocationType)type)); } // Calculate the offset of the next base relocation block currentRelocationBlockOffset += relocationBlock.SizeOfBlock; } }
private IEnumerable <ImportDescriptor> ReadDelayImportDescriptors() { // Calculate the offset of the delay import table if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.DelayImportTableDirectory, out var delayImportTableOffset)) { yield break; } for (var descriptorIndex = 0;; descriptorIndex++) { // Read the delay import descriptor var descriptorOffset = delayImportTableOffset + Unsafe.SizeOf <ImageDelayLoadDescriptor>() * descriptorIndex; var descriptor = MemoryMarshal.Read <ImageDelayLoadDescriptor>(PeBytes.Slice(descriptorOffset).Span); if (descriptor.DllNameRva == 0) { break; } // Read the name of the delay import descriptor var descriptorNameOffset = RvaToOffset(descriptor.DllNameRva); var descriptorName = ReadNullTerminatedString(descriptorNameOffset); // Read the functions imported under the delay import descriptor var descriptorThunkOffset = RvaToOffset(descriptor.ImportNameTableRva); var importAddressTableOffset = RvaToOffset(descriptor.ImportAddressTableRva); var delayImportedFunctions = ReadDelayImportedFunctions(descriptorThunkOffset, importAddressTableOffset); yield return(new ImportDescriptor(delayImportedFunctions, descriptorName)); } }
private IEnumerable <ImportDescriptor> ReadImportDescriptors() { // Calculate the import table offset if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.ImportTableDirectory, out var importTableOffset)) { yield break; } for (var descriptorIndex = 0;; descriptorIndex++) { // Read the import descriptor var descriptorOffset = importTableOffset + Unsafe.SizeOf <ImageImportDescriptor>() * descriptorIndex; var descriptor = MemoryMarshal.Read <ImageImportDescriptor>(PeBytes.Slice(descriptorOffset).Span); if (descriptor.Name == 0) { break; } // Read the import descriptor name var descriptorNameOffset = RvaToOffset(descriptor.Name); var descriptorName = ReadNullTerminatedString(descriptorNameOffset); // Read the functions imported under the import descriptor var descriptorThunkOffset = descriptor.OriginalFirstThunk == 0 ? RvaToOffset(descriptor.FirstThunk) : RvaToOffset(descriptor.OriginalFirstThunk); var importAddressTableOffset = RvaToOffset(descriptor.FirstThunk); var importedFunctions = ReadImportedFunctions(descriptorThunkOffset, importAddressTableOffset); yield return(new ImportDescriptor(importedFunctions, descriptorName)); } }
HexSpan?Read(PeHeaders peHeaders, DataDirectoryData dir) { uint rva = dir.VirtualAddress.Data.ReadValue(); uint size = dir.Size.Data.ReadValue(); if (rva == 0 || size == 0) { return(null); } var position = peHeaders.RvaToBufferPosition(rva); var end = position + size; if (end > HexPosition.MaxEndPosition) { return(null); } var span = HexSpan.FromBounds(position, end); if (!file.Span.Contains(span)) { return(null); } return(span); }
HexSpan?GetGoToMetadataSpan(DotNetMetadataHeaders mdHeaders, PeHeaders peHeaders, uint offsetTokenValue, GoToMetadataKind mdKind) { MDTable mdTable; switch (mdKind) { case GoToMetadataKind.Blob: if (mdHeaders.BlobStream == null) { return(null); } return(new HexSpan(mdHeaders.BlobStream.Span.Span.Start + offsetTokenValue, 0)); case GoToMetadataKind.Strings: if (mdHeaders.StringsStream == null) { return(null); } return(new HexSpan(mdHeaders.StringsStream.Span.Span.Start + offsetTokenValue, 0)); case GoToMetadataKind.US: if (mdHeaders.USStream == null) { return(null); } return(new HexSpan(mdHeaders.USStream.Span.Span.Start + (offsetTokenValue & 0x00FFFFFF), 0)); case GoToMetadataKind.GUID: if (mdHeaders.GUIDStream == null) { return(null); } return(new HexSpan(mdHeaders.GUIDStream.Span.Span.Start + (offsetTokenValue - 1) * 16, 16)); case GoToMetadataKind.Table: mdTable = GetMDTable(mdHeaders, offsetTokenValue); if (mdTable == null) { return(null); } return(new HexSpan(mdTable.Span.Start + ((offsetTokenValue & 0x00FFFFFF) - 1) * mdTable.RowSize, mdTable.RowSize)); case GoToMetadataKind.MemberRva: if (peHeaders == null) { return(null); } mdTable = GetMDTable(mdHeaders, offsetTokenValue); if (mdTable == null) { return(null); } if (mdTable.Table != Table.Method && mdTable.Table != Table.FieldRVA) { return(null); } // Column 0 is the RVA in both Method and FieldRVA tables var pos = mdTable.Span.Start + ((offsetTokenValue & 0x00FFFFFF) - 1) * mdTable.RowSize; var rva = HexView.Buffer.ReadUInt32(pos); return(new HexSpan(peHeaders.RvaToBufferPosition(rva), 0)); default: throw new InvalidOperationException(); } }
private IEnumerable <ExportedFunction> ReadExportedFunctions() { // Calculate the offset of the export table if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.ExportTableDirectory, out var exportTableOffset)) { yield break; } // Read the export table var exportTable = MemoryMarshal.Read <ImageExportDirectory>(PeBytes.Slice(exportTableOffset).Span); // Read the exported functions var functionNameBaseOffset = RvaToOffset(exportTable.AddressOfNames); var functionOffsetBaseOffset = RvaToOffset(exportTable.AddressOfFunctions); var functionOrdinalBaseOffset = RvaToOffset(exportTable.AddressOfNameOrdinals); for (var functionIndex = 0; functionIndex < exportTable.NumberOfNames; functionIndex++) { // Read the name of the function var functionNameOffsetOffset = functionNameBaseOffset + sizeof(int) * functionIndex; var functionNameOffset = RvaToOffset(MemoryMarshal.Read <int>(PeBytes.Slice(functionNameOffsetOffset).Span)); var functionName = ReadNullTerminatedString(functionNameOffset); // Read the ordinal of the function var functionOrdinalOffset = functionOrdinalBaseOffset + sizeof(short) * functionIndex; var functionOrdinal = MemoryMarshal.Read <short>(PeBytes.Slice(functionOrdinalOffset).Span); // Read the offset of the function var functionOffsetOffset = functionOffsetBaseOffset + sizeof(int) * functionOrdinal; var functionOffset = MemoryMarshal.Read <int>(PeBytes.Slice(functionOffsetOffset).Span); // Determine if the function is forwarded to another function var exportTableStartOffset = PeHeaders.PEHeader.ExportTableDirectory.RelativeVirtualAddress; var exportTableEndOffset = exportTableStartOffset + PeHeaders.PEHeader.ExportTableDirectory.Size; if (functionOffset < exportTableStartOffset || functionOffset > exportTableEndOffset) { yield return(new ExportedFunction(null, functionName, functionOffset, exportTable.Base + functionOrdinal)); continue; } // Read the forwarder string of the function var forwarderStringOffset = RvaToOffset(functionOffset); var forwarderString = ReadNullTerminatedString(forwarderStringOffset); yield return(new ExportedFunction(forwarderString, functionName, functionOffset, exportTable.Base + functionOrdinal)); } }
private IEnumerable <int> ReadTlsCallbackOffsets() { // Calculate offset of the TLS table if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.ThreadLocalStorageTableDirectory, out var tlsTableOffset)) { yield break; } if (PeHeaders.PEHeader.Magic == PEMagic.PE32) { // Calculate the offset of the TLS callbacks var tlsTable = MemoryMarshal.Read <ImageTlsDirectory32>(PeBytes.Slice(tlsTableOffset).Span); if (tlsTable.AddressOfCallbacks == 0) { yield break; } var tlsCallbacksOffset = RvaToOffset(tlsTable.AddressOfCallbacks - (int)PeHeaders.PEHeader.ImageBase); // Read the offsets of the TLS callbacks for (var tlsCallbackIndex = 0;; tlsCallbackIndex++) { var tlsCallbackVaOffset = tlsCallbacksOffset + sizeof(int) * tlsCallbackIndex; var tlsCallbackVa = MemoryMarshal.Read <int>(PeBytes.Slice(tlsCallbackVaOffset).Span); if (tlsCallbackVa == 0) { break; } yield return(tlsCallbackVa - (int)PeHeaders.PEHeader.ImageBase); } } else { // Calculate the offset of the TLS callbacks var tlsTable = MemoryMarshal.Read <ImageTlsDirectory64>(PeBytes.Slice(tlsTableOffset).Span); if (tlsTable.AddressOfCallbacks == 0) { yield break; } var tlsCallbacksOffset = RvaToOffset((int)(tlsTable.AddressOfCallbacks - (long)PeHeaders.PEHeader.ImageBase)); // Read the offsets of the TLS callbacks for (var tlsCallbackIndex = 0;; tlsCallbackIndex++) { var tlsCallbackVaOffset = tlsCallbacksOffset + sizeof(long) * tlsCallbackIndex; var tlsCallbackVa = MemoryMarshal.Read <long>(PeBytes.Slice(tlsCallbackVaOffset).Span); if (tlsCallbackVa == 0) { break; } yield return((int)(tlsCallbackVa - (long)PeHeaders.PEHeader.ImageBase)); } } }
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); } } } } } }