Skip to content

Commit 6e7ed93

Browse files
committed
Close #8 and bump version number a little for a new release
1 parent c92b498 commit 6e7ed93

File tree

6 files changed

+248
-6
lines changed

6 files changed

+248
-6
lines changed

ArchiveExplorer/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("0.11.0.*")]
36-
[assembly: AssemblyFileVersion("0.11.0.0")]
35+
[assembly: AssemblyVersion("0.11.1.*")]
36+
[assembly: AssemblyFileVersion("0.11.1.0")]

Library/Ark/ArkPackage.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* ArkPackage.cs
33
*
4-
* Copyright (c) 2015,2016, maxton. All rights reserved.
4+
* Copyright (c) 2015,2016,2017 maxton. All rights reserved.
55
*
66
* This library is free software; you can redistribute it and/or
77
* modify it under the terms of the GNU Lesser General Public
@@ -162,6 +162,18 @@ private void readHeader(Stream header, IFile hdrFile, uint version, bool brokenv
162162
for (var i = 0; i < numArkPaths; i++)
163163
{
164164
IFile arkFile = hdrFile.Parent.GetFile(header.ReadLengthUTF8().Split('/').Last());
165+
if(version == 10)
166+
{
167+
using(var tmpStream = arkFile.GetStream())
168+
{
169+
tmpStream.Seek(-32, SeekOrigin.End);
170+
if(tmpStream.ReadASCIINullTerminated(32) == "mcnxyxcmvmcxyxcmskdldkjshagsdhfj")
171+
{
172+
contentFiles[i] = new ProtectedFileStream(arkFile.GetStream());
173+
continue;
174+
}
175+
}
176+
}
165177
contentFiles[i] = arkFile.GetStream();
166178
}
167179

Library/Ark/HdrCryptStream.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* HdrCryptStream.cs
33
*
4-
* Copyright (c) 2015,2016, maxton. All rights reserved.
4+
* Copyright (c) 2015,2016,2017 maxton. All rights reserved.
55
*
66
* This library is free software; you can redistribute it and/or
77
* modify it under the terms of the GNU Lesser General Public

Library/Ark/ProtectedFileStream.cs

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
/*
2+
* ProtectedFileStream.cs
3+
*
4+
* Copyright (c) 2017 maxton. All rights reserved.
5+
*
6+
* This library is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3.0 of the License, or (at your option) any later version.
10+
*
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with this library; If not, see
18+
* <http://www.gnu.org/licenses/>.
19+
*/
20+
using System;
21+
using System.IO;
22+
23+
namespace GameArchives.Ark
24+
{
25+
/// <summary>
26+
/// A "protected file" wrapper.
27+
/// </summary>
28+
public class ProtectedFileStream : Stream
29+
{
30+
public override bool CanRead => true;
31+
32+
public override bool CanSeek => true;
33+
34+
public override bool CanWrite => false;
35+
36+
public override long Length { get; }
37+
38+
private Stream pkg;
39+
private long data_offset;
40+
private byte[] metadata;
41+
private byte key;
42+
43+
private long _position;
44+
public override long Position
45+
{
46+
get
47+
{
48+
return _position;
49+
}
50+
51+
set
52+
{
53+
Seek(value, SeekOrigin.Begin);
54+
}
55+
}
56+
57+
/// <summary>
58+
/// Constructs a new offset stream on the given base stream with the given offset and length.
59+
/// </summary>
60+
/// <param name="package">The base stream</param>
61+
/// <param name="offset">Offset into the base stream where this stream starts</param>
62+
/// <param name="length">Number of bytes in this stream</param>
63+
public ProtectedFileStream(Stream package)
64+
{
65+
this.pkg = package;
66+
package.Seek(-36, SeekOrigin.End);
67+
var size = package.ReadInt32LE();
68+
package.Seek(-size, SeekOrigin.End);
69+
metadata = new byte[size];
70+
package.Read(metadata, 0, size);
71+
init_prot_data(metadata);
72+
73+
data_offset = 0;
74+
Length = package.Length - size;
75+
}
76+
77+
78+
79+
public override int Read(byte[] buffer, int offset, int count)
80+
{
81+
pkg.Seek(data_offset + Position, SeekOrigin.Begin);
82+
if (count + Position > Length)
83+
{
84+
count = (int)(Length - Position);
85+
}
86+
int bytes_read = pkg.Read(buffer, offset, count);
87+
88+
for(int i = 0; i < bytes_read; i++)
89+
{
90+
byte tmp = buffer[offset+i];
91+
buffer[offset+i] ^= key;
92+
key = (byte)((metadata[5] ^ tmp) - _position);
93+
_position++;
94+
}
95+
return bytes_read;
96+
}
97+
98+
public override long Seek(long offset, SeekOrigin origin)
99+
{
100+
switch (origin)
101+
{
102+
case SeekOrigin.Begin:
103+
break;
104+
case SeekOrigin.Current:
105+
offset += _position;
106+
break;
107+
case SeekOrigin.End:
108+
offset += Length;
109+
break;
110+
}
111+
if (offset > Length)
112+
{
113+
offset = Length;
114+
}
115+
else if (offset < 0)
116+
{
117+
offset = 0;
118+
}
119+
_position = offset;
120+
121+
if(_position > 0)
122+
{
123+
pkg.Position = data_offset + _position - 1;
124+
key = (byte)((metadata[5] ^ pkg.ReadByte()) - _position + 1);
125+
}
126+
127+
return _position;
128+
}
129+
130+
private static uint rol(uint value, int count)
131+
{
132+
const int bits = 32;
133+
count %= bits;
134+
135+
uint high = value >> (bits - count);
136+
value <<= count;
137+
value |= high;
138+
return value;
139+
}
140+
141+
private static byte BYTE(int num, uint value)
142+
{
143+
return (byte)(value >> (num * 8));
144+
}
145+
146+
private static uint mangle(byte[] bytes, int offset, int count)
147+
{
148+
var mangled = 0U;
149+
for(var i = 0; i < count; i++)
150+
{
151+
mangled = bytes[offset + i] ^ 2 * (bytes[offset + i] + mangled);
152+
}
153+
return mangled;
154+
}
155+
156+
private static uint collapse(uint value)
157+
{
158+
return (uint)(BYTE(0, value) + BYTE(1, value) + BYTE(2, value) + BYTE(3, value));
159+
}
160+
161+
public static uint do_hash(byte[] key, int offset, long count)
162+
{
163+
uint tmp;
164+
165+
byte counter = 0;
166+
var seed = 0xE3AFEC21;
167+
for (var i = 0L; i < count; i++)
168+
{
169+
tmp = (key[offset + i] ^ collapse(seed));
170+
key[offset + i] = (byte)tmp;
171+
seed = rol((tmp | ((tmp | ((tmp | (tmp << 8)) << 8)) << 8)) + rol(seed, (int)(tmp & 0x1F)), 1);
172+
if (counter > 16)
173+
{
174+
seed = (2 * seed);
175+
counter = 0;
176+
}
177+
counter++;
178+
}
179+
return seed;
180+
}
181+
182+
public static void init_prot_data(byte[] metadata)
183+
{
184+
var word_0xE = BitConverter.ToUInt16(metadata, 0xE);
185+
uint size = (uint)metadata.Length;
186+
187+
var mangled_24 = 0U;
188+
if (word_0xE != 0)
189+
{
190+
mangled_24 = mangle(metadata, 24, word_0xE);
191+
}
192+
193+
byte mangled = (byte)collapse(
194+
mangle(metadata, 4, 9) +
195+
mangle(metadata, 0, 4) +
196+
mangle(metadata, 13, 1) +
197+
mangle(metadata, 16, 4) +
198+
mangled_24);
199+
200+
do_hash(metadata, 24, word_0xE);
201+
do_hash(metadata, 13, 1);
202+
do_hash(metadata, 16, 4);
203+
do_hash(metadata, 0, 4);
204+
do_hash(metadata, 4, 9);
205+
206+
metadata[20] = BYTE(0, size);
207+
metadata[21] = BYTE(1, size);
208+
metadata[22] = BYTE(2, size);
209+
metadata[23] = BYTE(3, size);
210+
metadata[5] ^= mangled;
211+
}
212+
213+
#region Not Supported
214+
public override void Flush()
215+
{
216+
throw new NotSupportedException();
217+
}
218+
public override void SetLength(long value)
219+
{
220+
throw new NotSupportedException();
221+
}
222+
223+
public override void Write(byte[] buffer, int offset, int count)
224+
{
225+
throw new NotSupportedException();
226+
}
227+
#endregion
228+
}
229+
}

Library/GameArchives.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
<Compile Include="Ark\ArkDirectory.cs" />
5555
<Compile Include="Ark\ArkPackage.cs" />
5656
<Compile Include="Ark\HdrCryptStream.cs" />
57+
<Compile Include="Ark\ProtectedFileStream.cs" />
5758
<Compile Include="Common\DefaultDirectory.cs" />
5859
<Compile Include="Common\OffsetFile.cs" />
5960
<Compile Include="Common\MultiStream.cs" />

Library/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@
5151
// You can specify all the values or you can default the Build and Revision Numbers
5252
// by using the '*' as shown below:
5353
// [assembly: AssemblyVersion("1.0.*")]
54-
[assembly: AssemblyVersion("0.11.0.*")]
55-
[assembly: AssemblyFileVersion("0.11.0.0")]
54+
[assembly: AssemblyVersion("0.11.1.*")]
55+
[assembly: AssemblyFileVersion("0.11.1.0")]

0 commit comments

Comments
 (0)