73 lines
2.8 KiB
C#
73 lines
2.8 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Text;
|
||
using Org.BouncyCastle.Asn1;
|
||
|
||
namespace VipNetExtract
|
||
{
|
||
class VipNetContainer
|
||
{
|
||
private VipNetContainer(
|
||
string type, uint version, int headerSize,
|
||
byte[] header, IList<VipNetContainerEntry> entries)
|
||
{
|
||
Type = type;
|
||
Version = version;
|
||
HeaderSize = headerSize;
|
||
Header = header;
|
||
Entries = entries;
|
||
}
|
||
|
||
public string Type { get; }
|
||
public uint Version { get; }
|
||
public int HeaderSize { get; }
|
||
public byte[] Header { get; }
|
||
public IList<VipNetContainerEntry> Entries { get; }
|
||
|
||
public static VipNetContainer LoadFromStream(Stream strm)
|
||
{
|
||
using (var reader = new BinaryReader(strm)) {
|
||
var type = Encoding.ASCII.GetString(reader.ReadBytes(4));
|
||
if (type != "ITCS" && type != "PKEY" && type != "_CCK" && type != "_LCK")
|
||
throw new NotSupportedException($"Неподдерживаемый тип контейнера: {type}.");
|
||
|
||
var version = reader.ReadUInt32();
|
||
if (LoWord(version) > 0xFF || HiWord(version) > 2)
|
||
throw new NotSupportedException($"Неподдерживаемая версия контейнера: {version}.");
|
||
|
||
var headerSize = reader.ReadInt32();
|
||
var header = new byte[headerSize];
|
||
if (headerSize > 0)
|
||
header = reader.ReadBytes(headerSize);
|
||
|
||
var entries = new List<VipNetContainerEntry>();
|
||
while (strm.Position < strm.Length) {
|
||
var entrySize = reader.ReadInt32();
|
||
var entryStartPos = strm.Position;
|
||
var entrySeq = (Asn1Sequence)Asn1Object.FromStream(strm);
|
||
var keySize = reader.ReadInt32();
|
||
if (keySize < 0 || strm.Position + keySize - entryStartPos != entrySize)
|
||
throw new InvalidOperationException($"Некорректный размер блока с ключом: {keySize}.");
|
||
var key = reader.ReadBytes(keySize);
|
||
entries.Add(new VipNetContainerEntry(entrySeq, key));
|
||
}
|
||
|
||
if (entries.Count == 0)
|
||
throw new InvalidOperationException("Контейнер не содержит записей.");
|
||
|
||
return new VipNetContainer(type, version, headerSize, header, entries);
|
||
}
|
||
}
|
||
|
||
public static VipNetContainer LoadFromFile(string fileName)
|
||
{
|
||
using (var strm = File.OpenRead(fileName))
|
||
return LoadFromStream(strm);
|
||
}
|
||
|
||
static uint LoWord(uint x) => x & 0x0000FFFF;
|
||
static uint HiWord(uint x) => x >> 16;
|
||
}
|
||
}
|