public IEnumerable<FileEntry> ListFiles(Stream strm, Callbacks callbacks) { byte[] buf = new byte[4]; BinaryReader rd = new BinaryReader(strm); int numFiles; List<FileEntry> results = new List<FileEntry>(); rd.Read(buf, 0, 4); if (Encoding.ASCII.GetString(buf, 0, 4) != "TGP0") return results; if (rd.ReadInt32() != 1) // version check return results; if (rd.ReadInt32() != 0) // should be zero return results; numFiles = rd.ReadInt32(); buf = new byte[0x60]; for (int i = 0; i < numFiles; i++) { FileEntry ent = new FileEntry(); rd.Read(buf, 0, 0x60); ent.Filename = Encoding.ASCII.GetString(buf); ent.Filename = ent.Filename.Substring(0, ent.Filename.IndexOf('\0')); ent.Offset = rd.ReadInt64(); ent.UncompressedSize = rd.ReadInt64(); results.Add(ent); } return results; }
public IEnumerable<FileEntry> ListFiles(Stream strm, Callbacks callbacks) { ZipEntry ze; ZipInputStream zstrm = new ZipInputStream(strm, true); List<FileEntry> results = new List<FileEntry>(); FileEntry fe; SetupZIPParams(); while (true) { ze = zstrm.GetNextEntry(); if (ze == null) break; if (ze.IsDirectory) continue; fe = new FileEntry(); fe.Filename = ze.FileName; fe.UncompressedSize = ze.UncompressedSize; fe.Timestamp = ze.LastModified; results.Add(fe); }; return results; }
public IEnumerable<FileEntry> ListFiles(Stream strm, Callbacks callbacks) { ArcEntry[] entries = GetDirectory(strm, false); List<FileEntry> results = new List<FileEntry>(); for (int i = 0; i < entries.Length; i++) { FileEntry fe = new FileEntry(); fe.Filename = NormalizeFileName(entries[i].Filename); fe.UncompressedSize = entries[i].UncompressedLength; yield return fe; } }
public IEnumerable<FileEntry> ListFiles(Stream strm, Callbacks callbacks) { List<FileEntry> results = new List<FileEntry>(); foreach (ArcEntry ae in GetDirectory(strm, false)) { FileEntry fe = new FileEntry(); fe.Filename = ae.Filename; fe.UncompressedSize = ae.Length; results.Add(fe); } return results; }
public IEnumerable<FileEntry> ListFiles(Stream strm, Callbacks callbacks) { ArcEntry[] files = GetDirectory(strm); List<FileEntry> results = new List<FileEntry>(); for (int i = 0; i < files.Length; i++) { FileEntry fe = new FileEntry(); fe.Filename = files[i].FileName; fe.UncompressedSize = files[i].Length; results.Add(fe); } return results; }
public IEnumerable<FileEntry> ListFiles(Stream strm, Callbacks callbacks) { List<FileEntry> results = new List<FileEntry>(); if (!ReadHeader(strm)) return null; foreach (System.Xml.XmlElement elt in fileList.SelectNodes("Files/File")) { FileEntry f = new FileEntry(); f.Filename = elt.SelectNodes("@Name").Item(0).InnerText; f.UncompressedSize = Convert.ToInt64(elt.SelectNodes("@Size").Item(0).InnerText); results.Add(f); } return results; }
public List<FileEntry> GetDirectory(Stream strm) { List<FileEntry> results = new List<FileEntry>(); BinaryReader rd = new BinaryReader(strm); int numFiles; numFiles = rd.ReadInt32(); // check if header is within file if (strm.Length < 8 * numFiles + 4) return null; // sanity check file count if (numFiles > 1000000) return null; for (int i = 0; i < numFiles; i++) { FileEntry ent = new FileEntry(); ent.Offset = rd.ReadUInt32(); ent.UncompressedSize = rd.ReadUInt32(); ent.FileIndex = i; ent.Filename = String.Format("{0:000000}", i); results.Add(ent); } // sanity check for (int i = 0; i < results.Count; i++) { // check if size is within file if (results[i].Offset + results[i].UncompressedSize > strm.Length) return null; // check if size is sane if ((results[i].Offset < 0) || (results[i].UncompressedSize < 0)) return null; if ((results[i].Offset > 2U * 1024U * 1024U * 1024U) || (results[i].UncompressedSize > 2U * 1024U * 1024U * 1024U)) return null; if (i > 0) { // file must start after previous file if (results[i].Offset < results[i - 1].Offset + results[i - 1].UncompressedSize) return null; } } return results; }
public IEnumerable<FileEntry> ListFiles(Stream strm, Callbacks callbacks) { ArchiveFile afile; if (!IsTankFile(strm)) yield break; afile = ReadDirectory(strm); foreach (FileSetEntry fse in afile.FileSet.Entries) { FileEntry fe = new FileEntry(); fe.UncompressedSize = fse.Size; fe.Filename = GetRelPath(afile, fse); yield return fe; } }
List<FileEntry> GetDirectory(Stream strm) { List<FileEntry> results = new List<FileEntry>(); BinaryReader rd = new BinaryReader(strm); int numFiles; if (rd.ReadUInt32() != 0x00534641) return null; numFiles = rd.ReadInt32(); for (int i = 0; i < numFiles; i++) { FileEntry fe = new FileEntry(); fe.Offset = rd.ReadInt32(); fe.UncompressedSize = rd.ReadInt32(); fe.Filename = String.Format("{0,8:00000000}.raw", i); results.Add(fe); } return results; }
private List<FileEntry> GetDirectory(Stream strm) { byte[] buf = new byte[8]; List<FileEntry> results; BinaryReader rd = new BinaryReader(strm); int numFiles; byte[] fname = new byte[32]; strm.Read(buf, 0, 8); if (Encoding.ASCII.GetString(buf) != "NISPACK\0") return null; rd.ReadInt32(); // unknown, 0x10000000 numFiles = FromBE(rd.ReadInt32()); results = new List<FileEntry>(); for (int i = 0; i < numFiles; i++) { FileEntry ent = new FileEntry(); rd.Read(fname, 0, 32); ent.Filename = Encoding.GetEncoding("SJIS").GetString(fname); if (ent.Filename.Contains("\0")) ent.Filename = ent.Filename.Substring(0, ent.Filename.IndexOf('\0')); ent.Offset = FromBE(rd.ReadInt32()); ent.UncompressedSize = FromBE(rd.ReadInt32()); ent.StringData["Unknown"] = String.Format("0x{0:x8}", FromBE(rd.ReadInt32())); results.Add(ent); } return results; }
List<FileEntry> ReadDirectory(Stream strm, Callbacks callbacks) { List<FileEntry> results = new List<FileEntry>(); BinaryReader rd = new BinaryReader(strm); Int32 numFiles; if (rd.ReadUInt32() != 0x5041434b) return null; numFiles = rd.ReadInt32(); if (numFiles > 100000) return null; for (int i = 0; i < numFiles; i++) { FileEntry ent = new FileEntry(); byte[] namebuf = new byte[24]; ent.LongData["type"] = rd.ReadUInt32(); // 0x0, 0x1 = file, 0xcccccccc = dir? if ((ent.LongData["type"] != 1) && (ent.LongData["type"] != 0) && (ent.LongData["type"] != 0xcccccccc)) return null; rd.Read(namebuf, 0, 24); ent.Filename = Encoding.GetEncoding("SJIS").GetString(namebuf).TrimEnd('\0'); ent.Offset = rd.ReadUInt32(); ent.UncompressedSize = rd.ReadUInt32(); if (ent.UncompressedSize > 1024 * 1024 * 1024) return null; if (ent.Offset > 1024 * 1024 * 1024) return null; results.Add(ent); } return results; }
public IEnumerable<FileEntry> ListFiles(Stream strm, Callbacks callbacks) { DirEntry[] files = GetDirectory(strm, false); List<FileEntry> fes = new List<FileEntry>(); for (int i = 0; i < files.Length; i++) { FileEntry fe = new FileEntry(); fe.Filename = String.Format("{0:x8}.{1}", i, GetExtension(files[i].Flags)); fe.UncompressedSize = files[i].Size; fes.Add(fe); } return fes; }
public IEnumerable<FileEntry> ListFiles(Stream strm, Callbacks callbacks) { List<FileEntry> results = new List<FileEntry>(); int magic; BinaryReader rd; int numFiles; int baseOffset; int totalSize; Stream xorStream; BinaryReader xrd; if (!IsSupported(strm, callbacks)) return null; strm.Seek(2 + 4 + 4, SeekOrigin.Current); rd = new BinaryReader(strm); magic = rd.ReadInt32(); m_XORValue = (byte)(~magic & 0xff); xorStream = new Shared.XORStream(strm, callbacks.TransformerRegistry, m_XORValue); xrd = new BinaryReader(xorStream); xrd.ReadInt32(); xrd.ReadInt32(); numFiles = xrd.ReadInt32(); xrd.ReadInt32(); baseOffset = xrd.ReadInt32(); totalSize = xrd.ReadInt32(); // read file info region for (int i = 0; i < numFiles; i++) { FileEntry ent = new FileEntry(); ent.UncompressedSize = xrd.ReadInt32(); ent.Offset = xrd.ReadInt32() + baseOffset; Int32 nameOffset = xrd.ReadByte(); nameOffset |= (int)xrd.ReadByte() << 8; nameOffset |= (int)xrd.ReadByte() << 16; ent.LongData["nameoffset"] = nameOffset; xrd.ReadByte(); xrd.ReadInt32(); results.Add(ent); } // read the file name region byte[] fnames = new byte[baseOffset - 16 * numFiles - 0x34]; int xbyte = fnames.Length; xrd.Read(fnames, 0, fnames.Length); for (int i = 0; i < fnames.Length; i++) { byte by = (byte)(fnames[i] ^ 0xc4); by += (byte)(xbyte & 0xff); fnames[i] = by; xbyte--; } // get names for every file foreach (FileEntry ent in results) { int nameOffset = (int)ent.LongData["nameoffset"] + 2; StringBuilder sb = new StringBuilder(); while (fnames[nameOffset] != 0) sb.Insert(0, (char)fnames[nameOffset++]); ent.Filename = sb.ToString(); } return results; }
private List<FileEntry> GetDirectory(Stream strm) { byte[] idbuf = new byte[8]; byte[] namebuf; BinaryReader rd; UInt32 numFiles; UInt32 OffsetDelta; List<FileEntry> results = new List<FileEntry>(); FileEntry ent; strm.Read(idbuf, 0, 8); if (Encoding.ASCII.GetString(idbuf) != "DW_PACK\0") return null; rd = new BinaryReader(strm); if (rd.ReadUInt32() != 0) return null; numFiles = rd.ReadUInt32(); if ((numFiles == 0) || (numFiles > 0x100000)) // arbitrary upper limit return null; rd.ReadUInt32(); // skip 8 bytes rd.ReadUInt32(); OffsetDelta = numFiles * 0x120 + 0x18; // the header size for (uint i = 0; i < numFiles; i++) { ent = new FileEntry(); ent.LongData["unk1"] = rd.ReadUInt32(); // lower 16 bits contain file index, upper 16 bit = 1 for compressed?? namebuf = new byte[0x100]; rd.Read(namebuf, 0, 0x100); ent.Filename = Encoding.ASCII.GetString(namebuf).Trim('\0'); rd.ReadUInt32(); rd.ReadUInt32(); ent.CompressedSize = rd.ReadUInt32(); ent.UncompressedSize = rd.ReadUInt32(); ent.LongData["unk2"] = rd.ReadInt32(); ent.Offset = rd.ReadInt32() + OffsetDelta; ent.LongData["unk3"] = rd.ReadUInt32(); // =0 except for last file which has 0x1234 results.Add(ent); } return results; }
List<FileEntry> GetDirectory(Stream strm) { List<FileEntry> results = new List<FileEntry>(); BinaryReader rd = new BinaryReader(strm); byte[] tocEntry = new byte[28]; int numFiles; FileEntry ent; rd.Read(tocEntry, 0, 28); tocEntry = DecryptBuffer(tocEntry, "32768GLB"); numFiles = BitConverter.ToInt32(tocEntry, 4); for (int i = 0; i < numFiles; i++) { rd.Read(tocEntry, 0, 28); tocEntry = DecryptBuffer(tocEntry, "32768GLB"); ent = new FileEntry(); ent.Offset = BitConverter.ToInt32(tocEntry, 4); ent.UncompressedSize = BitConverter.ToInt32(tocEntry, 8); ent.LongData["encrypted"] = BitConverter.ToInt32(tocEntry, 0); ent.Filename = Encoding.ASCII.GetString(tocEntry, 12, 16); ent.Filename = String.Format("0x{0:x8}_{1}", ent.Offset, ent.Filename.Substring(0, ent.Filename.IndexOf((char)0x00))); results.Add(ent); } return results; }
List<FileEntry> GetDirectory(Stream strm, bool CheckOnly) { byte[] buf = new byte[8]; byte[] namebuf = new byte[16]; BinaryReader rd = new BinaryReader(strm); int numFiles; List<FileEntry> results = new List<FileEntry>(); // read ID string rd.Read(buf, 0, 8); // ID string must be zero terminated if (rd.ReadByte() != 0) return null; // sanity check for number of files numFiles = rd.ReadInt32(); if (numFiles < 0 || numFiles > 100000) return null; if (Encoding.ASCII.GetString(buf) != "PAC_FILE") return null; if (CheckOnly) return results; // anything that is not-null will suffice here... for (int i = 0; i < numFiles; i++) { FileEntry ent = new FileEntry(); // read filename and size rd.Read(namebuf, 0, 16); // TODO: check if the file name encoding is correct! it's only a guess since it is definitely NOT US-ASCII ent.Filename = Encoding.GetEncoding("shift_jis").GetString(namebuf).TrimEnd('\0'); ent.Offset = rd.ReadInt32() + 4; if (i > 0) { results[i - 1].UncompressedSize = ent.Offset - results[i - 1].Offset; } results.Add(ent); } // calculate the length of the final file results[numFiles - 1].UncompressedSize = (int)(strm.Length - results[numFiles - 1].Offset); return results; }
private List<FileEntry> GetDirectory(Stream strm) { List<FileEntry> results = new List<FileEntry>(); byte[] buf; string subdir; UInt32 DirectoryStart = 0, DirectoryLength = 0, NumFiles = 0; // check for "LOD\0" signature buf = new byte[4]; strm.Read(buf, 0, 4); if (Encoding.ASCII.GetString(buf, 0, 3) != "LOD" || buf[3] != 0) return null; // check if the 'game name' is ASCII buf = new byte[12]; strm.Read(buf, 0, 12); string name = Encoding.ASCII.GetString(buf).TrimEnd('\0'); foreach (char c in name) { if (c < 32 || c > 127) return null; } // skip some unknown bytes strm.Seek(256-16, SeekOrigin.Current); // get the subdirectory name and trim it buf = new byte[16]; strm.Read(buf, 0, 16); subdir = Encoding.ASCII.GetString(buf); if (subdir.Contains("\0")) subdir = subdir.Substring(0, subdir.IndexOf('\0')); if (!ReadUInt32(strm, ref DirectoryStart)) return null; if (!ReadUInt32(strm, ref DirectoryLength)) return null; strm.Seek(4, SeekOrigin.Current); if (!ReadUInt32(strm, ref NumFiles)) return null; strm.Seek(DirectoryStart, SeekOrigin.Begin); // read the file directory for (int i = 0; i < NumFiles; i++) { FileEntry ent = new FileEntry(); UInt32 tmp = 0; buf = new byte[16]; strm.Read(buf, 0, 16); string fname = Encoding.ASCII.GetString(buf); if (fname.Contains("\0")) fname = fname.Substring(0, fname.IndexOf('\0')); ent.Filename = String.Format("{0}/{1}", subdir, fname); // read the start offset if (!ReadUInt32(strm, ref tmp)) return null; ent.Offset = DirectoryStart + tmp; // make sure the offset is relative to the file // read the size if (!ReadUInt32(strm, ref tmp)) return null; ent.UncompressedSize = tmp; // skip the next 8 bytes strm.Seek(8, SeekOrigin.Current); results.Add(ent); } return results; }
public static List<FileEntry> Load(byte[] buffer, int xorkey) { List<FileEntry> results = new List<FileEntry>(); Stack<Object> stack = new Stack<object>(); Stack<int> marks = new Stack<int>(); int pos = 2; byte opcode; bool stop = false; // we only support the binary Python Pickle Protocol 2 if ((buffer[0] != 0x80) || (buffer[1] != 0x02)) return results; while (pos < buffer.Length && !stop) { opcode = buffer[pos++]; switch (opcode) { case 0x7d: // '}' EMPTY_DICT stack.Push(new Dictionary<string, object>()); break; case 0x71: // 'q' BINPUT // skip 1 additional byte pos++; break; case 0x72: // 'r' LONG_BINPUT // skip 4 bytes pos += 4; break; case 0x28: // '(' MARK // skip marks.Push(stack.Count); break; case 0x58: // 'X' BINUNICODE Int32 strlen = (Int32)buffer[pos] + 256 * (Int32)buffer[pos + 1] + 256 * 256 * (Int32)buffer[pos + 2] + 256 * 256 * 256 * (Int32)buffer[pos + 3]; string s; s = Encoding.UTF8.GetString(buffer, pos + 4, strlen); stack.Push(s); pos += 4 + strlen; break; case 0x5d: // ']' EMPTY_LIST stack.Push(new List<object>()); break; case 0x4a: // 'J' BININT Int32 value = (Int32)buffer[pos] + 256 * (Int32)buffer[pos + 1] + 256 * 256 * (Int32)buffer[pos + 2] + 256 * 256 * 256 * (Int32)buffer[pos + 3]; stack.Push(value); pos += 4; break; case 0x55: // 'U' SHORT_BINSTRING byte datalen = buffer[pos++]; byte[] data = new byte[datalen]; for (int i = 0; i < datalen; i++) data[i] = buffer[pos++]; stack.Push(data); break; case 0x87: // '.' BUILD_TUPLE3 object obj3 = stack.Pop(); object obj2 = stack.Pop(); object obj1 = stack.Pop(); Tuple<object, object, object> tuple = new Tuple<object,object,object>(obj1, obj2, obj3); stack.Push(tuple); break; case 0x61: // 'a' APPEND object toAppend = stack.Pop(); object theList = stack.Peek(); if (theList is List<object>) (theList as List<object>).Add(toAppend); break; case 0x75: // 'u' SETITEMS int numItems = stack.Count - marks.Pop(); List<object> itemsToSet = new List<object>(); for (int i = 0; i < numItems; i++) itemsToSet.Add(stack.Pop()); itemsToSet.Reverse(); // check item on stack if (stack.Peek() is Dictionary<string, object>) { Dictionary<string, object> thedict = stack.Peek() as Dictionary<string, object>; for (int i = 0; i < numItems; i += 2) { string key = itemsToSet[i].ToString(); object val = itemsToSet[i + 1]; thedict.Add(key, val); } } // TODO: handle other SETITEMs (for lists etc)... break; case 0x8a: // '.' Make BigInt with <2048 bits byte count = buffer[pos++]; if (count > 8) throw new InvalidOperationException("Unsupported BIGINT with >64bit"); long res = 0; for (int i = 0; i < count; i++) { res |= ((long)(buffer[pos++]) << (8*i)); } if (count <= 4) { Int32 val = (int)res; stack.Push(val); } else { Int64 val = res; stack.Push(res); } break; case 0x2e: // '.' STOP stop = true; break; default: if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break(); throw new NotSupportedException(String.Format("Invalid Pickle opcode 0x{0:02x}", opcode)); } } // stack contains one dictionary (at least we hope so) Dictionary<string, object> dict = stack.Pop() as Dictionary<string, object>; if (dict == null) return null; foreach (string s in dict.Keys) { FileEntry ent = new FileEntry(); List<object> ldata = dict[s] as List<object>; Tuple<object, object, object> data3; if (ldata == null) { System.Diagnostics.Debugger.Break(); } data3 = ldata[0] as Tuple<object, object, object>; if (data3 == null) { // TODO: handle 2-tuples (as soon as I find a game which uses them) return null; } ent.Filename = s; ent.Offset = ((int)data3.Item1) ^ xorkey; ent.UncompressedSize = ((int)data3.Item2) ^ xorkey; if ((data3.Item3 as byte[]).Length > 0) ent.ObjectData["prefix"] = data3.Item3; results.Add(ent); } return results; }
private List<FileEntry> GetDirectory(Stream strm) { List<FileEntry> results = new List<FileEntry>(); BinaryReader rd = new BinaryReader(strm); ArchiveHeader ahdr; FileHeader fhdr; int i = 0; ahdr = ReadArchiveHeader(rd); if (ahdr == null) return null; fhdr = ReadFileHeader(rd); while (fhdr != null) { FileEntry ent = new FileEntry(); ent.FileIndex = i++; ent.Filename = fhdr.Filename; ent.CompressedSize = fhdr.CompressedSize; ent.UncompressedSize = fhdr.OriginalSize; ent.Timestamp = fhdr.FileModified; ent.ObjectData["FileHeader"] = fhdr; rd.BaseStream.Seek(fhdr.CompressedSize, SeekOrigin.Current); results.Add(ent); // read next header fhdr = ReadFileHeader(rd); } return results; }