Esempio n. 1
0
        byte[] _Read(uint count)
        {
            byte[] data = Reader.ReadBytes((int)count);
            for (int i = 0; i < data.Length; i++)
            {
                Key      = CryptedDtbStream.XorKey(Key);
                data[i] ^= (byte)Key;
            }
            Offset += (uint)data.Length;

            return(data);
        }
Esempio n. 2
0
        void _Write(byte[] buffer, uint offset, uint count)
        {
            byte[] buf = new byte[count];
            for (int i = 0; i < count; i++)
            {
                Key    = CryptedDtbStream.XorKey(Key);
                buf[i] = (byte)(buffer[i + offset] ^ Key);
            }
            Stream.Write(buf, 0, (int)count);

            Offset += count;
        }
Esempio n. 3
0
        public ChunkedDtbStream(EndianReader reader)
        {
            Mode   = ChunkedMode.Chunk;
            Stream = reader.Base;
            Reader = reader;

            uint i, j;

            Stream.Position = 4;
            Key             = Reader.ReadInt32();

            ChunkMap = new int[Chunks + 1];
            Seeds    = new int[SeedIndexCount];

            ChunkMap[0] = -8;
            for (i = 1; i <= Chunks; i++)
            {
                int pos;
                Stream.Position = (i - 1) * ChunkSize;
                byte[] buffer = Reader.ReadBytes(ChunkSize);
                for (pos = ChunkSize; pos > 0; pos--)
                {
                    if (buffer[pos - 1] != 0)
                    {
                        break;
                    }
                }
                ChunkMap[i] = ChunkMap[i - 1] + pos;
            }

            length = (uint)ChunkMap[ChunkMap.Length - 1];
            //Length = ChunkMap[(sizeof(ChunkMap)/sizeof(ChunkMap[0]))-1];

            // calculate seeds for faster seeking
            for (i = 0; i < length; i += SeedLength)
            {
                Seeds[i / SeedLength] = Key;
                for (j = 0; j < SeedLength; j++)
                {
                    Key = CryptedDtbStream.XorKey(Key);
                }
            }

            Offset          = 0;
            Key             = Seeds[0];
            Stream.Position = 8;
        }
Esempio n. 4
0
        public Ark(EndianReader hdrstream, params Stream[] arkstreams) : this()
        {
            HdrStream  = hdrstream;
            ArkStreams = arkstreams;

            HdrStream.Position = 0;
            Version            = HdrStream.ReadUInt32();
            uint numArks;
            uint numArks2;

            long[] arkSizes;
            int    stringSize;
            Stream stringTable;
            int    numOffsets;

            int[] offsetTable;
            int   numEntries;

            if (Version == ArkMagic || Version == ArkMagicLE)     // FreQuency
            {
                Version = HdrStream.ReadUInt32();                 // == 2
                int fileoffset = HdrStream.ReadInt32();
                numEntries = HdrStream.ReadInt32();
                int diroffset = HdrStream.ReadInt32();
                numOffsets = HdrStream.ReadInt32();
                int stringoffset = HdrStream.ReadInt32();
                int numStrings   = HdrStream.ReadInt32();
                HdrStream.ReadInt32();
                int sectorSize = HdrStream.ReadInt32();

                HdrStream.Position = diroffset;
                offsetTable        = new int[numOffsets];
                for (int i = 0; i < numOffsets; i++)
                {
                    HdrStream.ReadInt32();                     // Hash + 0x0000
                    offsetTable[i] = HdrStream.ReadInt32();
                }

                HdrStream.Position = stringoffset;
                stringTable        = new MemoryStream();
                EndianReader writer = new EndianReader(stringTable, Endianness.BigEndian);
                for (int i = 0; i < numStrings; i++)
                {
                    writer.Write(Util.ReadCString(HdrStream));
                    writer.Write((byte)0);
                }

                HdrStream.Position = fileoffset;
                for (int i = 0; i < numEntries; i++)
                {
                    HdrStream.ReadInt16();                     // Hash
                    HdrStream.ReadInt16();                     // Flags
                    int  nameoffset   = HdrStream.ReadInt32(); // Filename
                    int  directory    = HdrStream.ReadInt16();
                    int  sectoroffset = HdrStream.ReadInt16();
                    int  sector       = HdrStream.ReadInt32();
                    uint size         = HdrStream.ReadUInt32();
                    HdrStream.ReadInt32();                     // Extracted length

                    stringTable.Position = offsetTable[directory] - stringoffset;
                    string pathname = Util.ReadCString(stringTable);
                    stringTable.Position = nameoffset - stringoffset;
                    string filename = Util.ReadCString(stringTable);

                    DirectoryNode dir = Root.Navigate(pathname, true) as DirectoryNode;
                    dir.AddChild(new FileNode(filename, size, new Substream(HdrStream, sector * sectorSize + sectoroffset, (long)size)));
                }
            }
            else
            {
                if (Version > 5)                   // Invalid version number, encrypted
                {
                    Stream stream = new CryptedDtbStream(HdrStream);
                    HdrStream          = new EndianReader(stream, HdrStream.Endian);
                    HdrStream.Position = 0;
                    Version            = HdrStream.ReadUInt32();
                }

                if (Version <= 2)
                {
                    numArks  = 1;
                    numArks2 = 1;
                    arkSizes = new long[1] {
                        HdrStream.Base.Length
                    };
                    ArkStreams = new Stream[1] {
                        HdrStream.Base
                    };

                    numEntries          = HdrStream.ReadInt32();
                    HdrStream.Position += numEntries * (4 * 4 + 4);
                }
                else if (Version <= 5)
                {
                    numArks  = HdrStream.ReadUInt32();
                    numArks2 = HdrStream.ReadUInt32();

                    arkSizes = new long[numArks];

                    for (int i = 0; i < numArks; i++)
                    {
                        if (Version == 4)
                        {
                            arkSizes[i] = HdrStream.ReadInt64();
                        }
                        else
                        {
                            arkSizes[i] = (long)HdrStream.ReadUInt32();
                        }
                    }

                    if (Version == 5)                       // ark file string list
                    {
                        numArks = HdrStream.ReadUInt32();
                        for (int i = 0; i < numArks; i++)
                        {
                            int strsize = HdrStream.ReadInt32();
                            HdrStream.PadRead(strsize);                             // I'm not using them >.>
                        }
                    }
                }
                else
                {
                    throw new FormatException();
                }

                stringSize  = HdrStream.ReadInt32();
                stringTable = new MemoryStream(HdrStream.ReadBytes(stringSize), false);
                numOffsets  = HdrStream.ReadInt32();
                offsetTable = new int[numOffsets];
                for (int i = 0; i < numOffsets; i++)
                {
                    offsetTable[i] = HdrStream.ReadInt32();
                }

                if (Version <= 2)
                {
                    HdrStream.Position = 0x04;
                }

                numEntries = HdrStream.ReadInt32();

                for (int i = 0; i < numEntries; i++)
                {
                    long offset;
                    if (Version <= 3)
                    {
                        offset = (long)HdrStream.ReadUInt32();
                    }
                    else
                    {
                        offset = HdrStream.ReadInt64();
                    }
                    uint  filenameStringIndex = HdrStream.ReadUInt32();
                    uint  dirnameStringIndex  = HdrStream.ReadUInt32();
                    ulong size = 0;

                    if (Version <= 2)
                    {
                        size = HdrStream.ReadUInt32();
                        HdrStream.ReadInt32();                         // unknown, flags?
                    }
                    else
                    {
                        size = HdrStream.ReadUInt64();
                    }

                    string pathname;
                    if (dirnameStringIndex == 0xFFFFFFFF)
                    {
                        pathname = string.Empty;
                    }
                    else
                    {
                        stringTable.Position = offsetTable[dirnameStringIndex];
                        pathname             = Util.ReadCString(stringTable);
                    }

                    stringTable.Position = offsetTable[filenameStringIndex];
                    string filename = Util.ReadCString(stringTable);

                    DirectoryNode dir = Root.Navigate(pathname, true) as DirectoryNode;
                    int           ark;
                    for (ark = 0; offset >= arkSizes[ark]; offset -= arkSizes[ark++])
                    {
                        ;
                    }
                    if (dir != null)                     // Arks sometimes have paths like "../../etc", so we're just going to ignore them
                    {
                        dir.AddChild(new FileNode(filename, size, new Substream(ArkStreams[ark], offset, (long)size)));
                    }
                }
            }
        }