Пример #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
        private void ReadResourceData(BlobReader resourceReader, PEReader peFile, Func <object, object, ushort, bool> resourceFilter)
        {
            DoResourceDirectoryRead(resourceReader, 0, ProcessOuterResource);
            return;

            void ProcessOuterResource(object typeName, uint offset, bool isTypeDictionaryEntry)
            {
                if (!isTypeDictionaryEntry)
                {
                    throw new ArgumentException();
                }

                DoResourceDirectoryRead(resourceReader, offset, ProcessNameList);
                return;

                void ProcessNameList(object name, uint offsetOfLanguageList, bool isNameListDictionaryEntry)
                {
                    if (!isNameListDictionaryEntry)
                    {
                        throw new ArgumentException();
                    }

                    DoResourceDirectoryRead(resourceReader, offsetOfLanguageList, ProcessLanguageList);
                    return;

                    void ProcessLanguageList(object languageName, uint offsetOfLanguageListEntry, bool isLanguageListEntryIsDictionaryEntry)
                    {
                        if (languageName is string)
                        {
                            throw new ArgumentException();
                        }

                        if (isLanguageListEntryIsDictionaryEntry)
                        {
                            throw new ArgumentException();
                        }

                        resourceReader.Offset = checked ((int)offsetOfLanguageListEntry);
                        IMAGE_RESOURCE_DATA_ENTRY resourceData = new IMAGE_RESOURCE_DATA_ENTRY(ref resourceReader);

                        // The actual resource data offset is relative to the start address of the file
                        BlobReader resourceDataBlob = peFile.GetSectionData(checked ((int)resourceData.OffsetToData)).GetReader(0, checked ((int)resourceData.Size));

                        byte[] data = resourceDataBlob.ReadBytes((int)resourceData.Size);

                        if (resourceFilter != null)
                        {
                            // If the filter returns false, don't add this resource to the model
                            if (!resourceFilter(typeName, name, (ushort)languageName))
                            {
                                return;
                            }
                        }
                        AddResource(typeName, name, (ushort)languageName, data);
                    }
                }
            }
        }
Пример #4
0
        public void ImageResourceDataEntryConstructorWorks_Test()
        {
            var resourceDataEntry = new IMAGE_RESOURCE_DATA_ENTRY(RawStructures.RawResourceDataEntry, 2);

            Assert.Equal((uint)0x33221100, resourceDataEntry.OffsetToData);
            Assert.Equal((uint)0x77665544, resourceDataEntry.Size1);
            Assert.Equal(0xbbaa9988, resourceDataEntry.CodePage);
            Assert.Equal(0xffeeddcc, resourceDataEntry.Reserved);
        }
        public static IMAGE_RESOURCE_DATA_ENTRY Deserialize(MultiPartFile file)
        {
            IMAGE_RESOURCE_DATA_ENTRY irde = new IMAGE_RESOURCE_DATA_ENTRY();

            irde.OffsetToData = file.ReadUInt32();
            irde.Size         = file.ReadUInt32();
            irde.CodePage     = file.ReadUInt32();
            irde.Reserved     = file.ReadUInt32();

            return(irde);
        }
Пример #6
0
        public ResourceDataEntry(Stream stream, long rsrcSectionRVA, long rsrcSectionPA)
        {
            using (var br = new BinaryReader(stream, Encoding.Default, true))
            {
                //read struct and record position
                entry = br.ReadStruct <IMAGE_RESOURCE_DATA_ENTRY>();
                var temp = Encoding.GetEncoding((int)entry.Codepage);
#if COVERAGE_TEST && USE_SIZE
                RemoveBack(br.BaseStream.Position, entry.GetType());
#endif
                var pos = br.BaseStream.Position;

                //go to the actual data and read it
                br.BaseStream.Seek(rsrcSectionPA + entry.DataRVA - rsrcSectionRVA, SeekOrigin.Begin);
                data = br.ReadBytes(entry.Size);
#if COVERAGE_TEST && USE_SIZE
                RemoveBack(br.BaseStream.Position, data.Length);
#endif
                //jump back
                br.BaseStream.Position = pos;
            }
        }
Пример #7
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
        }
Пример #8
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;
                    }
                }
            }
        }