Beispiel #1
0
        string GetResourceName(int index, out int dataOffset)
        {
            long pos = nameSectionPosition + namePositions[index];

            byte[] bytes;
            lock (reader) {
                reader.Seek(pos, SeekOrigin.Begin);
                // Can't use reader.ReadString, since it's using UTF-8!
                int byteLen = reader.Read7BitEncodedInt();
                if (byteLen < 0)
                {
                    throw new BadImageFormatException("Resource name has negative length");
                }
                bytes = new byte[byteLen];
                // We must read byteLen bytes, or we have a corrupted file.
                // Use a blocking read in case the stream doesn't give us back
                // everything immediately.
                int count = byteLen;
                while (count > 0)
                {
                    int n = reader.Read(bytes, byteLen - count, count);
                    if (n == 0)
                    {
                        throw new BadImageFormatException("End of stream within a resource name");
                    }
                    count -= n;
                }
                dataOffset = reader.ReadInt32();
                if (dataOffset < 0)
                {
                    throw new BadImageFormatException("Negative data offset");
                }
            }
            return(Encoding.Unicode.GetString(bytes));
        }
Beispiel #2
0
        public ResourcesFile(Stream stream, bool leaveOpen = true)
        {
            fileStartPosition = stream.Position;
            reader            = new MyBinaryReader(stream, leaveOpen);

            const string ResourcesHeaderCorrupted = "Resources header corrupted.";

            // Read ResourceManager header
            // Check for magic number
            int magicNum = reader.ReadInt32();

            if (magicNum != MagicNumber)
            {
                throw new BadImageFormatException("Not a .resources file - invalid magic number");
            }
            // Assuming this is ResourceManager header V1 or greater, hopefully
            // after the version number there is a number of bytes to skip
            // to bypass the rest of the ResMgr header. For V2 or greater, we
            // use this to skip to the end of the header
            int resMgrHeaderVersion = reader.ReadInt32();
            int numBytesToSkip      = reader.ReadInt32();

            if (numBytesToSkip < 0 || resMgrHeaderVersion < 0)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }
            if (resMgrHeaderVersion > 1)
            {
                reader.BaseStream.Seek(numBytesToSkip, SeekOrigin.Current);
            }
            else
            {
                // We don't care about numBytesToSkip; read the rest of the header

                // readerType:
                reader.ReadString();
                // resourceSetType:
                reader.ReadString();
            }

            // Read RuntimeResourceSet header
            // Do file version check
            version = reader.ReadInt32();
            if (version != ResourceSetVersion && version != 1)
            {
                throw new BadImageFormatException($"Unsupported resource set version: {version}");
            }

            numResources = reader.ReadInt32();
            if (numResources < 0)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }

            // Read type positions into type positions array.
            // But delay initialize the type table.
            int numTypes = reader.ReadInt32();

            if (numTypes < 0)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }
            typeTable = new string[numTypes];
            for (int i = 0; i < numTypes; i++)
            {
                typeTable[i] = reader.ReadString();
            }

            // Prepare to read in the array of name hashes
            //  Note that the name hashes array is aligned to 8 bytes so
            //  we can use pointers into it on 64 bit machines. (4 bytes
            //  may be sufficient, but let's plan for the future)
            //  Skip over alignment stuff.  All public .resources files
            //  should be aligned   No need to verify the byte values.
            long pos        = reader.BaseStream.Position - fileStartPosition;
            int  alignBytes = unchecked ((int)pos) & 7;

            if (alignBytes != 0)
            {
                for (int i = 0; i < 8 - alignBytes; i++)
                {
                    reader.ReadByte();
                }
            }

            // Skip over the array of name hashes
            try
            {
                reader.Seek(checked (4 * numResources), SeekOrigin.Current);
            }
            catch (OverflowException)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }

            // Read in the array of relative positions for all the names.
            namePositions = new int[numResources];
            for (int i = 0; i < numResources; i++)
            {
                int namePosition = reader.ReadInt32();
                if (namePosition < 0)
                {
                    throw new BadImageFormatException(ResourcesHeaderCorrupted);
                }
                namePositions[i] = namePosition;
            }

            // Read location of data section.
            int dataSectionOffset = reader.ReadInt32();

            if (dataSectionOffset < 0)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }

            // Store current location as start of name section
            nameSectionPosition = reader.BaseStream.Position;
            dataSectionPosition = fileStartPosition + dataSectionOffset;

            // _nameSectionOffset should be <= _dataSectionOffset; if not, it's corrupt
            if (dataSectionPosition < nameSectionPosition)
            {
                throw new BadImageFormatException(ResourcesHeaderCorrupted);
            }
        }