void HeaderReader(int HeaderLenght, ref FARCFile[] Files, ref KKtIO reader) { if (Files == null) { int Count = 0; long Position = reader.BaseStream.Position; while (reader.BaseStream.Position < HeaderLenght) { reader.NullTerminated(0x00); reader.ReadInt32(); if (Signature != Farc.FArc) { reader.ReadInt32(); } reader.ReadInt32(); if (Signature == Farc.FARC && FT) { reader.ReadInt32(); } Count++; } reader.Seek(Position, 0); Files = new FARCFile[Count]; } int LocalMode = 0; for (int i = 0; i < Files.Length; i++) { Files[i].Name = Text.ToUTF8(reader.NullTerminated(0x00)); Files[i].Offset = reader.ReadInt32Endian(true); if (Signature != Farc.FArc) { Files[i].SizeComp = reader.ReadInt32Endian(true); } Files[i].SizeUnc = reader.ReadInt32Endian(true); if (Signature == Farc.FARC && FT) { LocalMode = reader.ReadInt32Endian(true); Files[i].GZip = (LocalMode & 2) == 2; Files[i].ECB = (LocalMode & 4) == 4; } } }
public void UnPack(string file, bool SaveToDisk) { Files = null; Signature = Farc.FArC; FT = false; Console.Title = "PD_Tool: FARC Extractor - Archive: " + Path.GetFileName(file); if (File.Exists(file)) { KKtIO reader = KKtIO.OpenReader(file); string directory = Path.GetFullPath(file).Replace(Path.GetExtension(file), ""); Signature = (Farc)reader.ReadInt32Endian(true); if (Signature == Farc.FARC) { Directory.CreateDirectory(directory); int HeaderLenght = reader.ReadInt32Endian(true); int Mode = reader.ReadInt32Endian(true); reader.ReadUInt32(); bool GZip = (Mode & 2) == 2; bool ECB = (Mode & 4) == 4; int FARCType = reader.ReadInt32Endian(true); FT = FARCType == 0x10; bool CBC = !FT && FARCType != 0x40; if (ECB && CBC) { byte[] Header = new byte[HeaderLenght - 0x08]; FT = true; reader.Close(); FileStream stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.Seek(0x10, 0); using (CryptoStream cryptoStream = new CryptoStream(stream, GetAes(true, null).CreateDecryptor(), CryptoStreamMode.Read)) cryptoStream.Read(Header, 0x00, HeaderLenght - 0x08); Header = SkipData(Header, 0x10); KKtIO CBCreader = new KKtIO(new MemoryStream(Header)); CBCreader.BaseStream.Seek(0, 0); FARCType = CBCreader.ReadInt32Endian(true); FT = FARCType == 0x10; if (CBCreader.ReadInt32Endian(true) == 1) { Files = new FARCFile[CBCreader.ReadInt32Endian(true)]; } CBCreader.ReadUInt32(); HeaderReader(HeaderLenght, ref Files, ref CBCreader); CBCreader.Close(); } else { if (reader.ReadInt32Endian(true) == 1) { Files = new FARCFile[reader.ReadInt32Endian(true)]; } reader.ReadUInt32(); HeaderReader(HeaderLenght, ref Files, ref reader); reader.Close(); } for (int i = 0; i < Files.Length; i++) { int FileSize = ECB || Files[i].ECB ? (int)Main. Align(Files[i].SizeComp, 0x10) : Files[i].SizeComp; FileStream stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.Seek(Files[i].Offset, 0); Files[i].Data = new byte[FileSize]; bool Encrypted = false; if (ECB) { if ((FT && Files[i].ECB) || CBC) { using (CryptoStream cryptoStream = new CryptoStream(stream, GetAes(true, null).CreateDecryptor(), CryptoStreamMode.Read)) cryptoStream.Read(Files[i].Data, 0, FileSize); Files[i].Data = SkipData(Files[i].Data, 0x10); } else { using (CryptoStream cryptoStream = new CryptoStream(stream, GetAes(false, null).CreateDecryptor(), CryptoStreamMode.Read)) cryptoStream.Read(Files[i].Data, 0, FileSize); } Encrypted = true; } bool Compressed = false; bool LocalGZip = (FT && Files[i].GZip) || GZip && Files[i].SizeUnc != 0; if (LocalGZip) { GZipStream gZipStream; if (Encrypted) { gZipStream = new GZipStream(new MemoryStream( Files[i].Data), CompressionMode.Decompress); stream.Close(); } else { gZipStream = new GZipStream(stream, CompressionMode.Decompress); } Files[i].Data = new byte[Files[i].SizeUnc]; gZipStream.Read(Files[i].Data, 0, Files[i].SizeUnc); Compressed = true; } if (!Encrypted && !Compressed) { Files[i].Data = new byte[Files[i].SizeUnc]; stream.Read(Files[i].Data, 0, Files[i].SizeUnc); stream.Close(); } if (SaveToDisk) { KKtIO writer = KKtIO.OpenWriter(Path.Combine(directory, Files[i].Name), true); writer.Write(Files[i].Data); writer.Close(); Files[i].Data = null; } } } else if (Signature == Farc.FArC) { Directory.CreateDirectory(directory); int HeaderLength = reader.ReadInt32Endian(true); reader.ReadUInt32(); HeaderReader(HeaderLength, ref Files, ref reader); reader.Close(); for (int i = 0; i < Files.Length; i++) { FileStream stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.Seek(Files[i].Offset, 0); Files[i].Data = new byte[Files[i].SizeComp]; stream.Read(Files[i].Data, 0, Files[i].SizeComp); stream.Close(); using (MemoryStream memorystream = new MemoryStream(Files[i].Data)) { GZipStream gZipStream = new GZipStream(memorystream, CompressionMode.Decompress); Files[i].Data = new byte[Files[i].SizeUnc]; gZipStream.Read(Files[i].Data, 0, Files[i].SizeUnc); } KKtIO writer = KKtIO.OpenWriter(Path.Combine(directory, Files[i].Name), true); writer.Write(Files[i].Data); writer.Close(); Files[i].Data = null; } } else if (Signature == Farc.FArc) { Directory.CreateDirectory(directory); int HeaderLength = reader.ReadInt32Endian(true); reader.ReadUInt32(); HeaderReader(HeaderLength, ref Files, ref reader); for (int i = 0; i < Files.Length; i++) { FileStream stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.Seek(Files[i].Offset, 0); Files[i].Data = new byte[Files[i].SizeUnc]; stream.Read(Files[i].Data, 0, Files[i].SizeUnc); stream.Close(); KKtIO writer = KKtIO.OpenWriter(Path.Combine(directory, Files[i].Name), true); writer.Write(Files[i].Data); writer.Close(); Files[i].Data = null; } } else { Console.WriteLine("Unknown signature"); reader.Close(); } } else { Console.WriteLine("File {0} doesn't exist.", Path.GetFileName(file)); } Console.Clear(); Console.Title = "PD_Tool: FARC Extractor"; }
public int STRReader() { KKtIO reader = KKtIO.OpenReader(filepath + ext); reader.Format = KKtMain.Format.F; Header.Signature = reader.ReadInt32(); if (Header.Signature == 0x41525453) { Header = reader.ReadHeader(true); STR = new List <String>(); POF = KKtMain.AddPOF(Header); reader.Position = Header.Lenght; Count = reader.ReadInt32Endian(); Offset = reader.ReadInt32Endian(); if (Offset == 0) { Offset = Count; OffsetX = reader.ReadInt64(); Count = reader.ReadInt64(); reader.XOffset = Header.Lenght; reader.Format = KKtMain.Format.X; } reader.LongPosition = reader.IsX ? Offset + reader.XOffset : Offset; for (int i = 0; i < Count; i++) { String Str = new String { StrOffset = reader.GetOffset(ref POF).ReadInt32Endian(), ID = reader.ReadInt32Endian() }; if (reader.IsX) { Str.StrOffset += (int)OffsetX; } STR.Add(Str); } for (int i = 0; i < Count; i++) { reader.LongPosition = STR[i].StrOffset + (reader.IsX ? reader.XOffset : 0); STR[i] = new String { ID = STR[i].ID, Str = KKtText. ToUTF8(reader.NullTerminated()), StrOffset = STR[i].StrOffset }; } reader.Seek(POF.Offset, 0); reader.ReadPOF(ref POF); } else { reader.Seek(-4, (SeekOrigin)1); int i = 0; STR = new List <String>(); while (reader.LongPosition > 0 && reader.LongPosition < reader.LongLength) { int a = reader.ReadInt32(); if (a != 0) { reader.Seek(-4, (SeekOrigin)1); STR.Add(new String { Str = KKtText.ToUTF8(reader.NullTerminated()), ID = i }); i++; } else { break; } } Count = STR.Count; } reader.Close(); return(1); }