MCPcopy Create free account
hub / github.com/Hiro420/NikkeTools / DecryptFile

Method DecryptFile

Catalog/NikkeCatalog/Program.cs:44–102  ·  view source on GitHub ↗
(string inputPath, string outputPath)

Source from the content-addressed store, hash-verified

42 }
43
44 static bool DecryptFile(string inputPath, string outputPath)
45 {
46 using var fs = new FileStream(inputPath, FileMode.Open, FileAccess.Read);
47 using var reader = new BinaryReader(fs);
48
49 var header = new NikkeDatabaseHeader
50 {
51 Magic = reader.ReadBytes(4),
52 Version = ReadUInt32BigEndian(reader),
53 AesKey = reader.ReadBytes(16),
54 SegmentSize = ReadUInt32BigEndian(reader),
55 SegmentCount = ReadUInt32BigEndian(reader)
56 };
57
58 if (!header.Magic.SequenceEqual(Encoding.ASCII.GetBytes("NKDB")))
59 return false; // invalid magic
60
61 if (header.Version != 1)
62 return false; // invalid version
63
64 int lengthByteCount = (header.SegmentSize * header.SegmentCount > 0xFFFFFFFF) ? 5 : 4;
65
66 long ReadOffset()
67 {
68 byte[] offsetBytes = reader.ReadBytes(lengthByteCount);
69 return offsetBytes.Aggregate(0L, (acc, b) => (acc << 8) | b);
70 }
71
72 long currentOffset = ReadOffset();
73 var segments = new (long Offset, long Length, int Index)[header.SegmentCount];
74
75 for (int i = 0; i < header.SegmentCount; i++)
76 {
77 long nextOffset = ReadOffset();
78 segments[i] = (currentOffset, nextOffset - currentOffset, i);
79 currentOffset = nextOffset;
80 }
81
82 using var output = new FileStream(outputPath, FileMode.Create, FileAccess.Write);
83
84 foreach (var (offset, length, index) in segments)
85 {
86 fs.Seek(offset, SeekOrigin.Begin);
87 byte[] segment = reader.ReadBytes((int)length);
88
89 byte[] iv = new byte[16];
90 BitConverter.GetBytes(index).CopyTo(iv, 0);
91 BitConverter.GetBytes((int)offset).CopyTo(iv, 4);
92
93 byte[] decrypted = DecryptAES_OFB(header.AesKey, iv, segment);
94
95 using var ms = new MemoryStream(decrypted);
96 using var zlib = new ZLibStream(ms, CompressionMode.Decompress);
97 zlib.CopyTo(output);
98
99 }
100
101 return true;

Callers

nothing calls this directly

Calls 1

SeekMethod · 0.45

Tested by

no test coverage detected