Exemple #1
0
        private void GetResourceInfo(ResDirectoryEntry dataEntry, out string type, out string name, out int localeId)
        {
            Debug.Assert(!dataEntry.IsSubdirectory, "attempted to get type/name/locale of resource directory node.");

            localeId = dataEntry.entry.Id;

            ResDirectory localeDir = _directories[dataEntry.ownerDirectory];

            ResDirectoryEntry nameEntry = _entries[localeDir.parentEntry];

            name = nameEntry.name;

            ResDirectory nameDirectory = _directories[nameEntry.ownerDirectory];

            ResDirectoryEntry typeEntry = _entries[nameDirectory.parentEntry];

            type = typeEntry.name;
        }
Exemple #2
0
        private int ReadDirectory(Stream peStream, long virtualAddress, long baseOffset, int parentId, ref int nextId)
        {
            int dirId   = nextId++;
            var dirInfo = new ResDirectory();

            dirInfo.id          = dirId;
            dirInfo.parentEntry = parentId;

            _directories.Add(dirId, dirInfo);

            dirInfo.directory = peStream.Read <IMAGE_RESOURCE_DIRECTORY>();

            int nChildren = dirInfo.directory.NumberOfIdEntries + dirInfo.directory.NumberOfNamedEntries;

            dirInfo.childMappings = new int[nChildren];

            // read the directory table rows
            for (int i = 0; i < nChildren; i++)
            {
                int entryId = nextId++;

                var dirEntry = new ResDirectoryEntry();
                dirEntry.id             = entryId;
                dirEntry.ownerDirectory = dirId;

                dirInfo.childMappings[i] = entryId;
                dirEntry.entry           = peStream.Read <IMAGE_RESOURCE_DIRECTORY_ENTRY>();

                _entries.Add(entryId, dirEntry);
            }

            // read the child data.
            for (int i = 0; i < nChildren; i++)
            {
                ResDirectoryEntry dirEntry = _entries[dirInfo.childMappings[i]];

                ReadEntryName(dirEntry, peStream, virtualAddress, baseOffset);

                ReadEntryChildren(dirEntry, peStream, virtualAddress, baseOffset, ref nextId);
            }

            return(dirId);
        }
        public bool getFile(string dir, out ResFile result)
        {
            result = null;
            if (!dir.StartsWith("/"))
            {
                return(false);
            }

            string[] dirs = dir.Split('/');

            ResDirectory resDir = baseDir;

            for (int level = 1; level < dirs.Length - 1; ++level)
            {
                if (!baseDir.getChildDir(out resDir, dirs[level]))
                {
                    return(false);
                }
            }

            return(resDir.getChildFile(out result, dirs[dirs.Length - 1]));
        }
Exemple #4
0
        private int ReadDirectory(Stream peStream, long baseAddress, long virtualAddress, ref int nextId)
        {
            int dirId   = nextId++;
            var dirInfo = new ResDirectory();

            _directories.Add(dirId, dirInfo);

            dirInfo.directory = peStream.Read <IMAGE_RESOURCE_DIRECTORY>();

            int nChildren = dirInfo.directory.NumberOfIdEntries + dirInfo.directory.NumberOfNamedEntries;

            dirInfo.childMappings = new int[nChildren];

            for (int i = 0; i < nChildren; i++)
            {
                int entryId = nextId++;

                var dirEntry = new ResDirectoryEntry();

                _entries.Add(entryId, dirEntry);
                dirInfo.childMappings[i] = entryId;

                dirEntry.entry = peStream.Read <IMAGE_RESOURCE_DIRECTORY_ENTRY>();

                // preserve the current stream position while we read child data
                var curOffset = peStream.Position;

                // read the name
                if (dirEntry.entry.NameIsString)
                {
                    // note: offset from beginning of section.
                    peStream.Seek(baseAddress + dirEntry.entry.NameOffset, SeekOrigin.Begin);

                    int nChars = peStream.Read <short>();

                    // names are in "Unicode"
                    int nBytes = nChars * 2;

                    var nameBytes = new byte[nBytes];
                    peStream.Read(nameBytes, 0, nBytes);

                    dirEntry.name = Encoding.Unicode.GetString(nameBytes);
                }
                else
                {
                    dirEntry.name = dirEntry.entry.Id.ToString();
                }

                // read the child node(s)
                if (dirEntry.entry.DataIsDirectory)
                {
                    // note: offset from beginning of section.
                    peStream.Seek(baseAddress + dirEntry.entry.OffsetToDirectory, SeekOrigin.Begin);

                    dirEntry.child = ReadDirectory(peStream, baseAddress, virtualAddress, ref nextId);
                }
                else
                {
                    // note: offset from beginning of section.
                    peStream.Seek(baseAddress + dirEntry.entry.OffsetToData, SeekOrigin.Begin);

                    var dataEntry = peStream.Read <IMAGE_RESOURCE_DATA_ENTRY>();

                    // decode the RVA...
                    long realDataAddr = baseAddress + dataEntry.OffsetToData - virtualAddress;
                    peStream.Seek(realDataAddr, SeekOrigin.Begin);

                    var dataBytes = new byte[dataEntry.Size];
                    peStream.Read(dataBytes, 0, dataBytes.Length);

                    int dataId = nextId++;
                    _data.Add(dataId, dataBytes);
                    dirEntry.child = dataId;
                }

                peStream.Seek(curOffset, SeekOrigin.Begin);
            }

            return(dirId);
        }
        public void readResource(string resourceFileDir)
        {
            BinaryReader reader = new BinaryReader(File.Open(resourceFileDir, FileMode.Open));

            MemoryStream headerStream = FileManagerCore.ReadGameData(reader.BaseStream);
            BinaryReader headerReader = new BinaryReader(headerStream);

            long nameDataLen = headerReader.ReadInt64();

            FileManagerCore.byteBoundaryWork(headerReader.BaseStream, false);

            for (long i = 0; i < nameDataLen; ++i)
            {
                short id     = headerReader.ReadInt16();
                long  offset = headerReader.ReadInt64();
                long  size   = headerReader.ReadInt64();

                byte[] data = new byte[size];
                FileManagerCore.readBytes(data, offset, reader.BaseStream);

                nameData.Add(id, Encoding.UTF8.GetString(data));

                FileManagerCore.byteBoundaryWork(headerReader.BaseStream, false);
            }

            long directoryDataLen = headerReader.ReadInt64();

            FileManagerCore.byteBoundaryWork(headerReader.BaseStream, false);

            for (long i = 0; i < directoryDataLen; ++i)
            {
                short id       = headerReader.ReadInt16();
                short parentID = headerReader.ReadInt16();
                short nameID   = headerReader.ReadInt16();

                ResDirectory dir = new ResDirectory(id, nameData[nameID]);

                directoryData.Add(id, dir);

                if (directoryData.ContainsKey(parentID))
                {
                    directoryData[parentID].addChildDir(dir);
                }
                else
                {
                    baseDir = dir;
                }

                FileManagerCore.byteBoundaryWork(headerReader.BaseStream, false);
            }

            long fileDataLen = headerReader.ReadInt64();

            FileManagerCore.byteBoundaryWork(headerReader.BaseStream, false);
            for (long i = 0; i < fileDataLen; ++i)
            {
                short id       = headerReader.ReadInt16();
                short parentID = headerReader.ReadInt16();
                short nameID   = headerReader.ReadInt16();
                long  offset   = headerReader.ReadInt64();
                long  size     = headerReader.ReadInt64();

                byte[] data = new byte[size];
                FileManagerCore.readBytes(data, offset, reader.BaseStream);


                ResFile file = new ResFile(id, nameData[nameID], data);

                directoryData[parentID].addChildFile(file);

                FileManagerCore.byteBoundaryWork(headerReader.BaseStream, false);
            }
        }