Was just a test, fully unpacks all the MRS files in the folder it's in.
Program.cs
Zipstructures.csCode:
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Decrypt(ref byte[] buffer, int index, int len)
{
for (var i = index; i < (index + len); ++i)
{
var a = buffer[i];
buffer[i] = (byte)(~((a >> 3) | (a << 5)));
}
}
static void Encrypt(ref byte[] buffer, int index, int len)
{
for (var i = index; i < (index + len); ++i)
{
var a = buffer[i];
buffer[i] = (byte)(~((a >> 5) | (a << 3)));
}
}
static void Main(string[] args)
{
var fileList = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.mrs");
foreach (var fileName in fileList)
{
try
{
using (var file = new BinaryReader(File.Open(fileName, FileMode.Open)))
{
file.BaseStream.Position = file.BaseStream.Length - 22;
var eocd = new byte[26];
file.Read(eocd, 0, 26);
Decrypt(ref eocd, 0, eocd.Length);
var dir = new EndOfCentralDirectory(eocd);
Console.WriteLine("Found Zip Signature: {0:X}", dir.Signature);
Console.WriteLine("File Header Position (Calculated from EOCD): {0}",
((dir.SizeOfCentralDirectory + dir.ZipFileCommentLen + 22)*-1));
Console.WriteLine("File Count: {0}", dir.FileHaderCount);
file.BaseStream.Position = ((dir.SizeOfCentralDirectory + dir.ZipFileCommentLen + 22)*-1) +
file.BaseStream.Length;
var files = new List<FileHeader>();
for (var i = 0; i < dir.FileHaderCount; ++i)
{
var header = new byte[46];
file.Read(header, 0, header.Length);
Decrypt(ref header, 0, header.Length);
files.Add(new FileHeader(header));
var name = new byte[files[i].FileNameLength];
file.Read(name, 0, name.Length);
Decrypt(ref name, 0, name.Length);
files[i].SetFileName(name);
}
var prim = fileName.Substring(fileName.LastIndexOf("\\") + 1);
prim = prim.Substring(0, prim.IndexOf("."));
Console.WriteLine("{0}", prim);
prim += "/";
if (!Directory.Exists(prim))
Directory.CreateDirectory(prim);
foreach (var fileHeader in files)
{
var local = new byte[30];
file.BaseStream.Position = fileHeader.RelativeOffset;
file.Read(local, 0, local.Length);
Decrypt(ref local, 0, local.Length);
var h = new LocalFileHeader(local);
//just skip these.
file.BaseStream.Position += h.ExtraFieldLength + h.FileNameLength;
var com = new byte[h.CompressedSize];
file.Read(com, 0, com.Length);
using (
var deflateStream = new DeflateStream(new MemoryStream(com), CompressionMode.Decompress)
)
{
var dec = new byte[h.DecompressedSize];
deflateStream.Read(dec, 0, dec.Length);
if (fileHeader.FileName.Contains("/") &&
!Directory.Exists(prim +
fileHeader.FileName.Substring(0,
fileHeader.FileName.LastIndexOf("/"))))
Directory.CreateDirectory(prim +
fileHeader.FileName.Substring(0,
fileHeader.FileName.
LastIndexOf(
"/")));
using (
var binaryWriter =
new BinaryWriter(File.Open(prim + fileHeader.FileName, FileMode.Create)))
{
binaryWriter.Write(dec, 0, dec.Length);
binaryWriter.Close();
}
}
}
}
} catch(Exception e)
{
Console.WriteLine("Eror on file: {0}", fileName);
continue;
}
}
}
}
}
Code:using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ConsoleApplication1
{
class LocalFileHeader
{
public int Signature;
public short VersionRequired;
public short GeneralFlags;
public short Compression;
public short LastModificationTime;
public short LastModificationDate;
public int Crc32;
public int CompressedSize;
public int DecompressedSize;
public short FileNameLength;
public short ExtraFieldLength;
public string FileName, ExtraField;
public LocalFileHeader(byte[] buffer)
{
using (var stream = new MemoryStream(buffer))
{
using (var reader = new BinaryReader(stream))
{
Signature = reader.ReadInt32();
VersionRequired = reader.ReadInt16();
GeneralFlags = reader.ReadInt16();
Compression = reader.ReadInt16();
LastModificationTime = reader.ReadInt16();
LastModificationDate = reader.ReadInt16();
Crc32 = reader.ReadInt32();
CompressedSize = reader.ReadInt32();
DecompressedSize = reader.ReadInt32();
FileNameLength = reader.ReadInt16();
ExtraFieldLength = reader.ReadInt16(); }
}
}
}
class FileHeader
{
public int Signature;
public short VersionCreated;
public short VersionRequired;
public short GeneralFlags;
public short Compression;
public short LastModificationTime;
public short LastModificationDate;
public int Crc32;
public int CompressedSize;
public int DecompressedSize;
public short FileNameLength;
public short ExtraFieldLength;
public short FileCommentLength;
public short DiskFileStart;
public short InteralAttributes;
public int ExternalAttributes;
public int RelativeOffset;
public string FileName, ExtraField, FileComment;
public void SetFileName (byte[] buffer)
{
FileName = ASCIIEncoding.ASCII.GetString(buffer);
}
public FileHeader(byte[] buffer)
{
using (var stream = new MemoryStream(buffer))
{
using (var reader = new BinaryReader(stream))
{
Signature = reader.ReadInt32();
VersionCreated = reader.ReadInt16();
VersionRequired = reader.ReadInt16();
GeneralFlags = reader.ReadInt16();
Compression = reader.ReadInt16();
LastModificationTime = reader.ReadInt16();
LastModificationDate = reader.ReadInt16();
Crc32 = reader.ReadInt32();
CompressedSize = reader.ReadInt32();
DecompressedSize = reader.ReadInt32();
FileNameLength = reader.ReadInt16();
ExtraFieldLength = reader.ReadInt16();
FileCommentLength = reader.ReadInt16();
DiskFileStart = reader.ReadInt16();
InteralAttributes = reader.ReadInt16();
ExternalAttributes = reader.ReadInt32();
RelativeOffset = reader.ReadInt32();
}
}
}
}
class EndOfCentralDirectory
{
public int Signature;
public short DiskFileNumber;
public short DiskCentralDirectoryStart;
public short CentralDirectoryOnDisk;
public short FileHaderCount;
public int SizeOfCentralDirectory;
public int StartOfCentralDirectory;
public short ZipFileCommentLen;
public string ZipFileComment;
public EndOfCentralDirectory(byte[] buffer)
{
using (var stream = new MemoryStream(buffer))
{
using (var reader = new BinaryReader(stream))
{
Signature = reader.ReadInt32();
DiskFileNumber = reader.ReadInt16();
DiskCentralDirectoryStart = reader.ReadInt16();
CentralDirectoryOnDisk = reader.ReadInt16();
FileHaderCount = reader.ReadInt16();
SizeOfCentralDirectory = reader.ReadInt32();
StartOfCentralDirectory = reader.ReadInt32();
ZipFileCommentLen = reader.ReadInt16();
}
}
}
}
}
