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; }
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])); }
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); } }