예제 #1
0
        private void ReadStringTable(BinaryReader reader, uint offset, uint rsrcStart)
        {
            reader.BaseStream.Seek((long)((offset & 0x7FFFFFFF) + rsrcStart), SeekOrigin.Begin);
            IMAGE_RESOURCE_DIRECTORY rootDir = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY> ();
            int num = (int)(rootDir.NumberOfIdEntries + rootDir.NumberOfNamedEntries);

            IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries = new IMAGE_RESOURCE_DIRECTORY_ENTRY[num];
            for (int i = 0; i < num; i++)
            {
                entries [i] = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY> ();
            }
            for (int i = 0; i < num; i++)
            {
                uint dirOffset = entries [i].OffsetToData & 0x7FFFFFFF;
                reader.BaseStream.Seek((long)(dirOffset + rsrcStart), SeekOrigin.Begin);
                reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY> ();
                IMAGE_RESOURCE_DIRECTORY_ENTRY languageEntry = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY> ();
                reader.BaseStream.Seek((long)(languageEntry.OffsetToData + rsrcStart), SeekOrigin.Begin);
                IMAGE_RESOURCE_DATA_ENTRY dataEntry = reader.ReadStruct <IMAGE_RESOURCE_DATA_ENTRY> ();
                reader.BaseStream.Seek((long)dataEntry.OffsetToData, SeekOrigin.Begin);
                int blockId = (int)((entries [i].Name - 1u) * 16);

                for (int j = 0; j < 16; j++)
                {
                    int length = (int)(reader.ReadUInt16() * 2);
                    if (length != 0)
                    {
                        byte[] bytes = reader.ReadBytes(length);
                        string str   = Encoding.Unicode.GetString(bytes);
                        Strings.Add(blockId + j, str);
                    }
                }
            }
        }
예제 #2
0
        private void ReadXML(BinaryReader reader, uint offset, uint rsrcStart)
        {
            reader.BaseStream.Seek((long)((offset & 0x7FFFFFFF) + rsrcStart), SeekOrigin.Begin);
            IMAGE_RESOURCE_DIRECTORY rootDir = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY> ();
            int num = (int)(rootDir.NumberOfIdEntries + rootDir.NumberOfNamedEntries);

            IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries = new IMAGE_RESOURCE_DIRECTORY_ENTRY[num];
            for (int i = 0; i < num; i++)
            {
                entries [i] = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY> ();
            }
            for (int j = 0; j < num; j++)
            {
                uint dirOffset = entries [j].OffsetToData & 0x7FFFFFFF;
                reader.BaseStream.Seek((long)(dirOffset + rsrcStart), SeekOrigin.Begin);
                reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY> ();
                IMAGE_RESOURCE_DIRECTORY_ENTRY languageEntry = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY> ();
                reader.BaseStream.Seek((long)(languageEntry.OffsetToData + rsrcStart), SeekOrigin.Begin);
                IMAGE_RESOURCE_DATA_ENTRY dataEntry = reader.ReadStruct <IMAGE_RESOURCE_DATA_ENTRY> ();
                reader.BaseStream.Seek((long)dataEntry.OffsetToData, SeekOrigin.Begin);
                byte[] xmlBytes = reader.ReadBytes((int)dataEntry.Size);
                int    idx      = 0;
                int    count    = xmlBytes.Length;
                if (xmlBytes[0] == 0xFF && xmlBytes[1] == 0xFE)                 //Skip BOM
                {
                    idx    = 2;
                    count -= 2;
                }
                try {
                    Infocards.Add((int)entries [j].Name, Encoding.Unicode.GetString(xmlBytes, idx, count));
                } catch (Exception) {
                    FLLog.Error("Infocards", "Infocard Corrupt: " + entries[j].Name);
                }
            }
        }
예제 #3
0
        public static IMAGE_RESOURCE_DIRECTORY_ENTRY Deserialize(MultiPartFile file)
        {
            IMAGE_RESOURCE_DIRECTORY_ENTRY irde = new IMAGE_RESOURCE_DIRECTORY_ENTRY();

            irde.Name         = file.ReadUInt32();
            irde.OffsetToData = file.ReadUInt32();

            return(irde);
        }
예제 #4
0
        public void ResourceDirectroyEntryByIdConstructorWorks_Test()
        {
            var resourceDirectroyEntry =
                new IMAGE_RESOURCE_DIRECTORY_ENTRY(RawStructures.RawResourceDirectoryEntryById, 2, 2);

            Assert.True(resourceDirectroyEntry.IsIdEntry);
            Assert.False(resourceDirectroyEntry.IsNamedEntry);
            Assert.Equal((uint)0x00332211 & 0xFFFF, resourceDirectroyEntry.ID);
            Assert.Equal((uint)0x55443322, resourceDirectroyEntry.OffsetToData);
        }
예제 #5
0
        public void ResourceDirectroyEntryByNameConstructorWorks_Test()
        {
            var resourceDirectroyEntry =
                new IMAGE_RESOURCE_DIRECTORY_ENTRY(RawStructures.RawResourceDirectoryEntryByName, 2, 2);

            Assert.IsTrue(resourceDirectroyEntry.IsNamedEntry);
            Assert.IsFalse(resourceDirectroyEntry.IsIdEntry);
            Assert.AreEqual(0x80332211, resourceDirectroyEntry.Name);
            Assert.AreEqual((uint)0x55443322, resourceDirectroyEntry.OffsetToData);
        }
예제 #6
0
 public ManagedDllProvider(Stream stream)
 {
     using (BinaryReader binaryReader = new BinaryReader(stream))
     {
         var dosHeader = binaryReader.ReadStruct <IMAGE_DOS_HEADER>();
         binaryReader.BaseStream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);
         byte[] array = binaryReader.ReadBytes(4);
         if (Encoding.ASCII.GetString(array) != "PE\0\0")
         {
             throw new Exception("Not a PE File");
         }
         var fileHeader = binaryReader.ReadStruct <IMAGE_FILE_HEADER>();
         if ((IMAGE_FILE_32BIT_MACHINE & fileHeader.Characteristics) != IMAGE_FILE_32BIT_MACHINE)
         {
             throw new Exception("Not a 32-bit PE File");
         }
         binaryReader.ReadStruct <IMAGE_OPTIONAL_HEADER>();
         var sectionHeaders = new IMAGE_SECTION_HEADER[(int)fileHeader.NumberOfSections];
         IMAGE_SECTION_HEADER?rsrcSection = default(IMAGE_SECTION_HEADER?);
         for (int i = 0; i < (int)fileHeader.NumberOfSections; i++)
         {
             sectionHeaders[i] = binaryReader.ReadStruct <IMAGE_SECTION_HEADER>();
             if (sectionHeaders[i].Section == ".rsrc")
             {
                 rsrcSection = new IMAGE_SECTION_HEADER?(sectionHeaders[i]);
             }
         }
         if (!rsrcSection.HasValue)
         {
             throw new Exception("No resources");
         }
         binaryReader.BaseStream.Seek((long)((ulong)rsrcSection.Value.PointerToRawData), SeekOrigin.Begin);
         var rootDirectory = binaryReader.ReadStruct <IMAGE_RESOURCE_DIRECTORY>();
         int num           = (int)(rootDirectory.NumberOfIdEntries + rootDirectory.NumberOfNamedEntries);
         var entries       = new IMAGE_RESOURCE_DIRECTORY_ENTRY[num];
         for (int j = 0; j < num; j++)
         {
             entries[j] = binaryReader.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY>();
         }
         Strings   = new Dictionary <int, string>();
         Infocards = new Dictionary <int, string>();
         for (int k = 0; k < num; k++)
         {
             if (entries[k].Name == RT_STRING)
             {
                 ReadStringTable(binaryReader, entries[k].OffsetToData, rsrcSection.Value.PointerToRawData);
             }
             if (entries[k].Name == RT_RCDATA)
             {
                 ReadXML(binaryReader, entries[k].OffsetToData, rsrcSection.Value.PointerToRawData);
             }
         }
         binaryReader.Close();
     }
 }
예제 #7
0
        private static void DoResourceDirectoryRead(BlobReader resourceReaderExternal, uint startOffset, Action <object, uint, bool> entry)
        {
            // Create a copy of the Mu, so that we don't allow the delegate to affect its state
            BlobReader resourceReader = resourceReaderExternal;

            resourceReader.Offset = checked ((int)startOffset);
            IMAGE_RESOURCE_DIRECTORY directory = new IMAGE_RESOURCE_DIRECTORY(ref resourceReader);

            for (uint i = 0; i < directory.NumberOfNamedEntries + directory.NumberOfIdEntries; i++)
            {
                IMAGE_RESOURCE_DIRECTORY_ENTRY directoryEntry = new IMAGE_RESOURCE_DIRECTORY_ENTRY(ref resourceReader);

                object name;
                if ((directoryEntry.Name & 0x80000000) != 0)
                {
                    int oldPosition = resourceReader.Offset;

                    // This is a named entry, read the string
                    uint nameOffset = directoryEntry.Name & ~0x80000000;

                    resourceReader.Offset = checked ((int)nameOffset);
                    ushort stringLen     = resourceReader.ReadUInt16();
                    char[] newStringData = new char[stringLen];
                    for (int iStr = 0; iStr < stringLen; iStr++)
                    {
                        newStringData[iStr] = (char)resourceReader.ReadUInt16();
                    }
                    name = new string(newStringData);
                    // And then reset back to read more things.
                    resourceReader.Offset = oldPosition;
                }
                else
                {
                    name = checked ((ushort)directoryEntry.Name);
                }

                uint offset      = directoryEntry.OffsetToData;
                bool isDirectory = false;
                if ((offset & 0x80000000) != 0)
                {
                    offset     &= ~0x80000000;
                    isDirectory = true;
                }

                entry(name, offset, isDirectory);
            }
        }
예제 #8
0
        public ResourceDirectoryEntry(Stream stream, long rsrcSectionFileAddress)
        {
            using (var br = new BinaryReader(stream, Encoding.Unicode, true))
            {
                header = br.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY>();
#if COVERAGE_TEST && USE_SIZE
                RemoveBack(br.BaseStream.Position, header.GetType());
#endif
                if (header.IsString)
                {
                    var pos = br.BaseStream.Position;
                    br.BaseStream.Seek(rsrcSectionFileAddress + header.StringOffset, SeekOrigin.Begin);
                    //need to use this function because of the variable length
                    name = IMAGE_RESOURCE_DIR_STRING_U.FromStream(br);
#if COVERAGE_TEST && USE_SIZE
                    RemoveBack(br.BaseStream.Position, name.Value.Size);
#endif
                    br.BaseStream.Position = pos;
                }
            }
        }
예제 #9
0
        public void WriteResources(ISymbolNode nodeAssociatedWithDataBuilder, ref ObjectDataBuilder dataBuilder)
        {
            Debug.Assert(dataBuilder.CountBytes == 0);

            SortedDictionary <string, List <ObjectDataBuilder.Reservation> > nameTable = new SortedDictionary <string, List <ObjectDataBuilder.Reservation> >();
            Dictionary <ResLanguage, int> dataEntryTable = new Dictionary <ResLanguage, int>();
            List <Tuple <ResType, ObjectDataBuilder.Reservation> >     resTypes     = new List <Tuple <ResType, ObjectDataBuilder.Reservation> >();
            List <Tuple <ResName, ObjectDataBuilder.Reservation> >     resNames     = new List <Tuple <ResName, ObjectDataBuilder.Reservation> >();
            List <Tuple <ResLanguage, ObjectDataBuilder.Reservation> > resLanguages = new List <Tuple <ResLanguage, ObjectDataBuilder.Reservation> >();

            IMAGE_RESOURCE_DIRECTORY.Write(ref dataBuilder, checked ((ushort)_resTypeHeadName.Count), checked ((ushort)_resTypeHeadID.Count));
            foreach (KeyValuePair <string, ResType> res in _resTypeHeadName)
            {
                resTypes.Add(new Tuple <ResType, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key, nameTable)));
            }
            foreach (KeyValuePair <ushort, ResType> res in _resTypeHeadID)
            {
                resTypes.Add(new Tuple <ResType, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key)));
            }

            foreach (Tuple <ResType, ObjectDataBuilder.Reservation> type in resTypes)
            {
                dataBuilder.EmitUInt(type.Item2, (uint)dataBuilder.CountBytes | 0x80000000);
                IMAGE_RESOURCE_DIRECTORY.Write(ref dataBuilder, checked ((ushort)type.Item1.NameHeadName.Count), checked ((ushort)type.Item1.NameHeadID.Count));

                foreach (KeyValuePair <string, ResName> res in type.Item1.NameHeadName)
                {
                    resNames.Add(new Tuple <ResName, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key, nameTable)));
                }
                foreach (KeyValuePair <ushort, ResName> res in type.Item1.NameHeadID)
                {
                    resNames.Add(new Tuple <ResName, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key)));
                }
            }

            foreach (Tuple <ResName, ObjectDataBuilder.Reservation> type in resNames)
            {
                dataBuilder.EmitUInt(type.Item2, (uint)dataBuilder.CountBytes | 0x80000000);
                IMAGE_RESOURCE_DIRECTORY.Write(ref dataBuilder, 0, checked ((ushort)type.Item1.Languages.Count));
                foreach (KeyValuePair <ushort, ResLanguage> res in type.Item1.Languages)
                {
                    resLanguages.Add(new Tuple <ResLanguage, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key)));
                }
            }

            // Emit name table
            dataBuilder.PadAlignment(2); // name table is 2 byte aligned
            foreach (KeyValuePair <string, List <ObjectDataBuilder.Reservation> > name in nameTable)
            {
                foreach (ObjectDataBuilder.Reservation reservation in name.Value)
                {
                    dataBuilder.EmitUInt(reservation, (uint)dataBuilder.CountBytes | 0x80000000);
                }

                dataBuilder.EmitUShort(checked ((ushort)name.Key.Length));
                foreach (char c in name.Key)
                {
                    dataBuilder.EmitUShort((ushort)c);
                }
            }

            // Emit byte arrays of resource data, capture the offsets
            foreach (Tuple <ResLanguage, ObjectDataBuilder.Reservation> language in resLanguages)
            {
                dataBuilder.PadAlignment(4); // Data in resource files is 4 byte aligned
                dataEntryTable.Add(language.Item1, dataBuilder.CountBytes);
                dataBuilder.EmitBytes(language.Item1.DataEntry);
            }

            dataBuilder.PadAlignment(4); // resource data entries are 4 byte aligned
            foreach (Tuple <ResLanguage, ObjectDataBuilder.Reservation> language in resLanguages)
            {
                dataBuilder.EmitInt(language.Item2, dataBuilder.CountBytes);
                IMAGE_RESOURCE_DATA_ENTRY.Write(ref dataBuilder, nodeAssociatedWithDataBuilder, dataEntryTable[language.Item1], language.Item1.DataEntry.Length);
            }
            dataBuilder.PadAlignment(4); // resource data entries are 4 byte aligned
        }
예제 #10
0
        internal ResourceDirectoryEntry(PortableExecutableImage image, DataDirectory dataDirectory, Location location, ResourceDirectory parentDirectory, IMAGE_RESOURCE_DIRECTORY_ENTRY entry) : base(image, dataDirectory, location)
        {
            _name      = null;
            _directory = null;
            _data      = null;

            ParentDirectory = parentDirectory;
            NameType        = ((entry.Name & 0x80000000) == 0x80000000 ? NameType.Name : NameType.ID);
            OffsetType      = ((entry.OffsetToData & 0x80000000) == 0x80000000 ? OffsetType.Directory : OffsetType.Data);

            Name         = entry.Name;
            OffsetToData = entry.OffsetToData;
        }
예제 #11
0
        public PEReader(string filePath)
        {
            // Read in the DLL or EXE and get the timestamp
            using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                BinaryReader reader = new BinaryReader(stream);
                dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

                // Add 4 bytes to the offset
                stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

                UInt32 ntHeadersSignature = reader.ReadUInt32();
                fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
                if (this.Is32BitHeader)
                {
                    optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader);
                }
                else
                {
                    optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader);
                }

                // image data directory
                int numberOfRvaAndSizes = (int)((this.Is32BitHeader) ? optionalHeader32.NumberOfRvaAndSizes : optionalHeader64.NumberOfRvaAndSizes);
                imageDataDirectory = new IMAGE_DATA_DIRECTORY[numberOfRvaAndSizes];

                for (int i = 0; i < numberOfRvaAndSizes; i++)
                {
                    IMAGE_DATA_DIRECTORY direc = FromBinaryReader <IMAGE_DATA_DIRECTORY>(reader);
                    imageDataDirectory[i] = direc;
                }

                // image section header, optionalHeader offset 18h = 24
                uint optionSize = fileHeader.SizeOfOptionalHeader;
                stream.Seek(dosHeader.e_lfanew + 24 + optionSize, SeekOrigin.Begin);

                imageSectionHeader = new IMAGE_SECTION_HEADER[FileHeader.NumberOfSections];
                for (int i = 0; i < FileHeader.NumberOfSections; i++)
                {
                    IMAGE_SECTION_HEADER sectionHeader = FromBinaryReader <IMAGE_SECTION_HEADER>(reader);
                    imageSectionHeader[i] = sectionHeader;
                }

                // read resource
                IMAGE_DATA_DIRECTORY resourceDataDirectory = imageDataDirectory[2];
                uint resDataRVA  = resourceDataDirectory.VirtualAddress;
                uint resDataSize = resourceDataDirectory.Size;
                uint resEndRVA   = resDataRVA + resDataSize;
                resource_offset      = 0;
                resource_rva         = 0;
                resource_rawDataSize = 0;
                foreach (IMAGE_SECTION_HEADER sectionHeader in imageSectionHeader)
                {
                    uint secRVA    = sectionHeader.VirtualAddress;
                    uint secEndRVA = secRVA + sectionHeader.SizeOfRawData;
                    if (secRVA <= resDataRVA && resEndRVA > secRVA && secEndRVA >= resEndRVA)
                    {
                        resource_offset      = sectionHeader.PointerToRawData;
                        resource_rva         = secRVA;
                        resource_rawDataSize = sectionHeader.SizeOfRawData;
                    }
                }

                if (resource_offset == 0)
                {
                    ResourceEntry_ALL = new PEResourceEntries[0];
                }
                else
                {
                    stream.Seek(resource_offset, SeekOrigin.Begin);

                    // resource level 1
                    IMAGE_RESOURCE_DIRECTORY d1 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY>(reader);
                    int entriesCount1           = d1.NumberOfIdEntries + d1.NumberOfNamedEntries;
                    IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries1 = new IMAGE_RESOURCE_DIRECTORY_ENTRY[entriesCount1];
                    ResourceEntry_ALL = new PEResourceEntries[entriesCount1];
                    for (int i = 0; i < entriesCount1; i++)
                    {
                        IMAGE_RESOURCE_DIRECTORY_ENTRY entry = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY_ENTRY>(reader);
                        entries1[i] = entry;
                    }

                    for (int i = 0; i < entriesCount1; i++)
                    {
                        IMAGE_RESOURCE_DIRECTORY_ENTRY entry = entries1[i];
                        PEResourceEntries resEntries         = new PEResourceEntries();
                        resEntries.level1Entry       = entry;
                        resEntries.level2Map3Entries = new Hashtable();
                        resEntries.level3DATA        = new Hashtable();

                        // level 2
                        // type
                        long offset_2 = resource_offset + entry.OffsetToData_l;
                        stream.Seek(offset_2, SeekOrigin.Begin);
                        if (PEUtil.ConvertIntToBin((int)entry.OffsetToData_h).StartsWith("1"))
                        {
                            IMAGE_RESOURCE_DIRECTORY d2 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY>(reader);
                            int entriesCount2           = d2.NumberOfIdEntries + d2.NumberOfNamedEntries;
                            IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries2 = new IMAGE_RESOURCE_DIRECTORY_ENTRY[entriesCount2];
                            for (int ii = 0; ii < entriesCount2; ii++)
                            {
                                IMAGE_RESOURCE_DIRECTORY_ENTRY entry2 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY_ENTRY>(reader);
                                entries2[ii] = entry2;
                            }
                            resEntries.level2Entries = entries2;

                            // level 3
                            for (int j = 0; j < entriesCount2; j++)
                            {
                                IMAGE_RESOURCE_DIRECTORY_ENTRY entry2 = entries2[j];
                                // type
                                long offset_3 = resource_offset + entry2.OffsetToData_l;
                                stream.Seek(offset_3, SeekOrigin.Begin);

                                IMAGE_RESOURCE_DIRECTORY d3 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY>(reader);
                                int entriesCount3           = d3.NumberOfIdEntries + d3.NumberOfNamedEntries;
                                IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries3 = new IMAGE_RESOURCE_DIRECTORY_ENTRY[entriesCount3];
                                for (int k = 0; k < entriesCount3; k++)
                                {
                                    IMAGE_RESOURCE_DIRECTORY_ENTRY entry3 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY_ENTRY>(reader);
                                    entries3[k] = entry3;

                                    long offset_4 = resource_offset + entry3.OffsetToData_l;
                                    stream.Seek(offset_4, SeekOrigin.Begin);
                                    IMAGE_RESOURCE_DATA_ENTRY dataEntry = FromBinaryReader <IMAGE_RESOURCE_DATA_ENTRY>(reader);

                                    if (!resEntries.level3DATA.ContainsKey(entry3))
                                    {
                                        resEntries.level3DATA.Add(entry3, dataEntry);
                                    }
                                }
                                resEntries.level2Map3Entries.Add(entry2, entries3);
                            }
                        }
                        else
                        {
                            throw new Exception("Resource level 2 OffsetToData_h can not start with 0");
                            //                        IMAGE_RESOURCE_DATA_ENTRY dataEntry = FromBinaryReader<IMAGE_RESOURCE_DATA_ENTRY>(reader);
                        }

                        ResourceEntry_ALL[i] = resEntries;
                    }
                }
            }
        }