ArcFile Open(byte[] basename, ArcView file, EncryptionScheme scheme, Key key) { uint key1 = scheme.BaseKey.Key1; uint key2 = scheme.BaseKey.Key2; for (int b = 0, e = basename.Length - 1; e >= 0; ++b, --e) { key1 ^= basename[e]; key2 ^= basename[b]; key1 = Binary.RotR(key1, 7); key2 = Binary.RotL(key2, 7); } if (null != key) { key1 ^= key.Key1; key2 ^= key.Key2; } uint code = file.View.ReadUInt32(4) ^ key2; int index_size = (int)(code & 0xffffff); byte flags = (byte)(code >> 24); if (0 != (flags & 1)) { index_size = (index_size << 11) - 8; } if (index_size < 5 || index_size >= file.MaxOffset) { return(null); } var index = new byte[index_size]; if (index_size != file.View.Read(8, index, 0, (uint)index_size)) { return(null); } scheme.DecryptIndex(index, index_size, key2); var lpk_info = new LpkInfo { AlignedOffset = 0 != (flags & 1), Flag1 = 0 != (flags & 2), IsEncrypted = 0 != (flags & 4), PackedEntries = 0 != (flags & 8), WholeCrypt = 0 != (flags & 0x10), Key = key1 }; var reader = new IndexReader(lpk_info); var dir = reader.Read(index); if (null == dir) { return(null); } // this condition is fishy, probably patch files have additional bitflag set if (lpk_info.WholeCrypt && Binary.AsciiEqual(basename, "PATCH")) { lpk_info.WholeCrypt = false; } return(new LuciArchive(file, this, dir, scheme, reader.Info)); }
public IndexReader(LpkInfo info) { if (!info.Flag1) { throw new NotSupportedException("Not supported LPK index format"); } m_info = info; EntrySize = m_info.PackedEntries ? 13 : 9; }
public LuciArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, EncryptionScheme scheme, LpkInfo info) : base(arc, impl, dir) { Info = info; Scheme = scheme; }
public LuciArchive(ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, EncryptionScheme scheme, LpkInfo info) : base(arc, impl, dir) { Info = info; Scheme = scheme; }
public IndexReader(LpkInfo info) { if (!info.Flag1) throw new NotSupportedException ("Not supported LPK index format"); m_info = info; EntrySize = m_info.PackedEntries ? 13 : 9; }
ArcFile Open(byte[] basename, ArcView file, EncryptionScheme scheme, Key key) { uint key1 = scheme.BaseKey.Key1; uint key2 = scheme.BaseKey.Key2; for (int b = 0, e = basename.Length-1; e >= 0; ++b, --e) { key1 ^= basename[e]; key2 ^= basename[b]; key1 = Binary.RotR (key1, 7); key2 = Binary.RotL (key2, 7); } if (null != key) { key1 ^= key.Key1; key2 ^= key.Key2; } uint code = file.View.ReadUInt32 (4) ^ key2; int index_size = (int)(code & 0xffffff); byte flags = (byte)(code >> 24); if (0 != (flags & 1)) index_size = (index_size << 11) - 8; if (index_size < 5 || index_size >= file.MaxOffset) return null; var index = new byte[index_size]; if (index_size != file.View.Read (8, index, 0, (uint)index_size)) return null; DecryptIndex (index, index_size, key2, scheme.RotatePattern); var lpk_info = new LpkInfo { AlignedOffset = 0 != (flags & 1), Flag1 = 0 != (flags & 2), IsEncrypted = 0 != (flags & 4), PackedEntries = 0 != (flags & 8), WholeCrypt = 0 != (flags & 0x10), Key = key1 }; var reader = new IndexReader (lpk_info); var dir = reader.Read (index); if (null == dir) return null; // this condition is fishy, probably patch files have additional bitflag set if (lpk_info.WholeCrypt && Binary.AsciiEqual (basename, "PATCH")) lpk_info.WholeCrypt = false; return new LuciArchive (file, this, dir, scheme, reader.Info); }