public static bool IsFileType(Stream stream)
        {
            if (!stream.CanRead)
            {
                throw new ArgumentException("Stream is not available for reading", nameof(stream));
            }
            if (!stream.CanSeek)
            {
                throw new ArgumentException("Stream is not available for seeking", nameof(stream));
            }

            if (stream.Position != 0)
            {
                stream.Seek(0, SeekOrigin.Begin);
            }

            {
                var magicBuffer = new byte[MAGIC.Length];
                var bytesRead   = stream.Read(magicBuffer, 0, MAGIC.Length);
                if (bytesRead != MAGIC.Length)
                {
                    return(false);
                }
                var magicMatch = bytesRead == MAGIC.Length && Enumerable.SequenceEqual(MAGIC, magicBuffer);
                if (!magicMatch)
                {
                    return(false);
                }
            }

            // Read e_lfanew
            stream.Seek(0x3C, SeekOrigin.Begin);
            {
                var lfaNewBuffer = new byte[4];
                var bytesRead    = stream.Read(lfaNewBuffer, 0, lfaNewBuffer.Length);
                if (bytesRead != lfaNewBuffer.Length)
                {
                    return(false);
                }

                var peHeaderLocation = BitConverter.ToUInt32(lfaNewBuffer);
                stream.Seek(peHeaderLocation, SeekOrigin.Begin);
                PEHeader potentialHeader;
                if (!PEHeader.TryRead(stream, out potentialHeader))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #2
0
 public static bool TryRead(Stream stream, out PEHeader header)
 {
     try
     {
         header = new PEHeader();
         header.Read(stream);
         return(true);
     }
     catch (Exception ex)
     {
         header = default(PEHeader);
         Console.Error.WriteLine(ex);
         return(false);
     }
 }
Exemple #3
0
        public LoaderResult64 LoadImage()
        {
            if (!stream.CanRead)
            {
                throw new ArgumentException("Stream is not available for reading", nameof(stream));
            }
            if (!stream.CanSeek)
            {
                throw new ArgumentException("Stream is not available for seeking", nameof(stream));
            }

            var metadata = new List <object>();

            var msDosStubHeader = new MsDosStubHeader();

            msDosStubHeader.Read(stream);
            metadata.Add(msDosStubHeader);

            stream.Seek((long)msDosStubHeader.e_lfanew, SeekOrigin.Begin);
            var peHeader = new PEHeader();

            peHeader.Read(stream);
            metadata.Add(peHeader);

            UInt32 entryPoint = 0;

            if (peHeader.mSizeOfOptionalHeader > 0)
            {
                PEHeaderOption64 pe64;
                if (!PEHeaderOption64.TryRead(stream, out pe64))
                {
                    return(LoaderResult64.Error("Unable to read Pe64OptionalHeader"));
                }
                metadata.Add(pe64);

                entryPoint = pe64.mAddressOfEntryPoint;
            }

            return(new LoaderResult64(entryPoint, new byte[0], metadata: metadata));
        }
Exemple #4
0
        public ImmutableList <object> LoadMetadata()
        {
            var metadata = new List <object>();

            var msDosStubHeader = new MsDosStubHeader();

            msDosStubHeader.Read(stream);
            metadata.Add(msDosStubHeader);

            stream.Seek((long)msDosStubHeader.e_lfanew, SeekOrigin.Begin);
            var peHeader = new PEHeader();

            peHeader.Read(stream);
            metadata.Add(peHeader);

            var positionPeOptional = stream.Position;

            {
                var rvaAndSizes    = new PEDataDictionary();
                var sectionHeaders = new SectionHeaderTable();

                PEHeaderOption64 pe64;
                if (PEHeaderOption64.TryRead(stream, out pe64))
                {
                    metadata.Add(pe64);

                    // Read data dictionaries
                    for (int i = 0; i < pe64.mNumberOfRvaAndSizes; i++)
                    {
                        var rva = stream.ReadUInt32();
                        var sz  = stream.ReadUInt32();
                        rvaAndSizes.Add(rva, sz);
                    }

                    metadata.Add(rvaAndSizes);
                }
                else
                {
                    stream.Seek(positionPeOptional, SeekOrigin.Begin);
                }

                PEHeaderOption32 pe32;
                if (PEHeaderOption32.TryRead(stream, out pe32))
                {
                    metadata.Add(pe32);

                    // Read data dictionaries
                    for (int i = 0; i < pe32.mNumberOfRvaAndSizes; i++)
                    {
                        var rva = stream.ReadUInt32();
                        var sz  = stream.ReadUInt32();
                        rvaAndSizes.Add(rva, sz);
                    }
                    metadata.Add(rvaAndSizes);

                    // Read section headers

                    for (int i = 0; i < peHeader.mNumberOfSections; i++)
                    {
                        var shdr = new SectionHeaderEntry(stream);
                        sectionHeaders.Add(shdr);
                    }
                    metadata.Add(sectionHeaders);

                    // PE Import table (2nd entry)
                    if (rvaAndSizes.Count + 1 >= (int)PEDataDictionaryIndex.IMPORT_TABLE)
                    {
                        var rva = rvaAndSizes[(int)PEDataDictionaryIndex.IMPORT_TABLE];
                        stream.SeekToRVA(sectionHeaders, rva.RelativeVirtualAddress);

                        var idt = new PEImportDirectoryTable(stream, sectionHeaders);
                        metadata.Add(idt);

                        foreach (var ide in idt)
                        {
                            var itt = new PEImportLookupTable();
                            stream.SeekToRVA(sectionHeaders, ide.ImportLookupTableRva);
                            UInt32 ite;
                            do
                            {
                                ite = stream.ReadUInt32();
                                if (ite == 0)
                                {
                                    break;
                                }
                                itt.Add(new PEImportLookupEntry(ite));
                            } while (true);

                            foreach (var entry in itt)
                            {
                                if (!entry.Key.OrdinalNameFlag)
                                {
                                    stream.SeekToRVA(sectionHeaders, entry.Key.HintTableNameRva);
                                    var nameHint = new PEImportNameHintEntry(stream);
                                    var name     = nameHint.Name;
                                    itt.QueueNameUpdate(entry.Key, name);
                                }
                            }
                            itt.ApplyNameUpdates();

                            metadata.Add(itt);
                        }
                    }

                    // PE Resources table (3rd entry)
                    if (rvaAndSizes.Count + 1 >= (int)PEDataDictionaryIndex.RESOURCE_TABLE)
                    {
                        var rva = rvaAndSizes[(int)PEDataDictionaryIndex.RESOURCE_TABLE];
                        stream.SeekToRVA(sectionHeaders, rva.RelativeVirtualAddress);
                    }
                }
                else
                {
                    stream.Seek(positionPeOptional, SeekOrigin.Begin);
                }
            }

            return(metadata.ToImmutableList());
        }