From 3954603fef0431028d6ec90e849160b9aa3d39d3 Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Sun, 5 Apr 2020 02:49:42 -0400 Subject: [PATCH] support XOR (and others, in the future) transformations directly on the Reader / Writer --- Libraries/UniversalEditor.Core/IO/Reader.cs | 8 ++ .../IO/ReaderWriterBase.cs | 110 +++++++++--------- .../UniversalEditor.Core/IO/Transformation.cs | 37 ++++++ .../IO/Transformations/XorTransformation.cs | 58 +++++++++ Libraries/UniversalEditor.Core/IO/Writer.cs | 20 ++-- .../UniversalEditor.Core.csproj | 5 + 6 files changed, 173 insertions(+), 65 deletions(-) create mode 100644 Libraries/UniversalEditor.Core/IO/Transformation.cs create mode 100644 Libraries/UniversalEditor.Core/IO/Transformations/XorTransformation.cs diff --git a/Libraries/UniversalEditor.Core/IO/Reader.cs b/Libraries/UniversalEditor.Core/IO/Reader.cs index 40707cdc..a8999065 100644 --- a/Libraries/UniversalEditor.Core/IO/Reader.cs +++ b/Libraries/UniversalEditor.Core/IO/Reader.cs @@ -97,6 +97,9 @@ namespace UniversalEditor.IO { return (sbyte)(ReadBytes(1)[0]); } + + private int xorkey_index = 0; + [CLSCompliant(false)] public byte[] ReadBytes(uint length) { @@ -111,6 +114,11 @@ namespace UniversalEditor.IO Array.Copy(buf2, 0, buf, lastct, buf2.Length); lastct += (uint)ct; } + + for (int i = 0; i < Transformations.Count; i++) + { + buf = Transformations[i].Transform(buf); + } return buf; } diff --git a/Libraries/UniversalEditor.Core/IO/ReaderWriterBase.cs b/Libraries/UniversalEditor.Core/IO/ReaderWriterBase.cs index ca590d0f..19737e65 100644 --- a/Libraries/UniversalEditor.Core/IO/ReaderWriterBase.cs +++ b/Libraries/UniversalEditor.Core/IO/ReaderWriterBase.cs @@ -26,65 +26,67 @@ using System.Text; namespace UniversalEditor.IO { - public abstract class ReaderWriterBase - { - private Endianness mvarEndianness = Endianness.LittleEndian; - public Endianness Endianness { get { return mvarEndianness; } set { mvarEndianness = value; } } + public abstract class ReaderWriterBase + { + private Endianness mvarEndianness = Endianness.LittleEndian; + public Endianness Endianness { get { return mvarEndianness; } set { mvarEndianness = value; } } - public void SwapEndianness() - { - if (mvarEndianness == Endianness.LittleEndian) - { - mvarEndianness = Endianness.BigEndian; - } - else - { - mvarEndianness = Endianness.LittleEndian; - } - } + public void SwapEndianness() + { + if (mvarEndianness == Endianness.LittleEndian) + { + mvarEndianness = Endianness.BigEndian; + } + else + { + mvarEndianness = Endianness.LittleEndian; + } + } - private bool mvarReverse = false; - public bool Reverse { get { return mvarReverse; } } + private bool mvarReverse = false; + public bool Reverse { get { return mvarReverse; } } - private Accessor mvarAccessor = null; - public Accessor Accessor { get { return mvarAccessor; } } + private Accessor mvarAccessor = null; + public Accessor Accessor { get { return mvarAccessor; } } - private NewLineSequence mvarNewLineSequence = NewLineSequence.Default; - public NewLineSequence NewLineSequence { get { return mvarNewLineSequence; } set { mvarNewLineSequence = value; } } - public string GetNewLineSequence() - { - string newline = System.Environment.NewLine; - switch (mvarNewLineSequence) - { - case IO.NewLineSequence.CarriageReturn: - { - newline = "\r"; - break; - } - case IO.NewLineSequence.LineFeed: - { - newline = "\n"; - break; - } - case IO.NewLineSequence.CarriageReturnLineFeed: - { - newline = "\r\n"; - break; - } - case IO.NewLineSequence.LineFeedCarriageReturn: - { - newline = "\n\r"; - break; - } - } - return newline; - } + public Transformation.TransformationCollection Transformations { get; } = new Transformation.TransformationCollection(); - public ReaderWriterBase(Accessor accessor) - { - this.mvarAccessor = accessor; - this.mvarEndianness = Endianness.LittleEndian; - this.mvarReverse = false; + private NewLineSequence mvarNewLineSequence = NewLineSequence.Default; + public NewLineSequence NewLineSequence { get { return mvarNewLineSequence; } set { mvarNewLineSequence = value; } } + public string GetNewLineSequence() + { + string newline = System.Environment.NewLine; + switch (mvarNewLineSequence) + { + case IO.NewLineSequence.CarriageReturn: + { + newline = "\r"; + break; + } + case IO.NewLineSequence.LineFeed: + { + newline = "\n"; + break; + } + case IO.NewLineSequence.CarriageReturnLineFeed: + { + newline = "\r\n"; + break; + } + case IO.NewLineSequence.LineFeedCarriageReturn: + { + newline = "\n\r"; + break; + } + } + return newline; + } + + public ReaderWriterBase(Accessor accessor) + { + this.mvarAccessor = accessor; + this.mvarEndianness = Endianness.LittleEndian; + this.mvarReverse = false; } /// diff --git a/Libraries/UniversalEditor.Core/IO/Transformation.cs b/Libraries/UniversalEditor.Core/IO/Transformation.cs new file mode 100644 index 00000000..c8faeea8 --- /dev/null +++ b/Libraries/UniversalEditor.Core/IO/Transformation.cs @@ -0,0 +1,37 @@ +// +// Transformation.cs +// +// Author: +// Mike Becker +// +// Copyright (c) 2020 Mike Becker +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +namespace UniversalEditor.IO +{ + public abstract class Transformation + { + public class TransformationCollection + : System.Collections.ObjectModel.Collection + { + } + + protected abstract byte[] TransformInternal(byte[] input); + public byte[] Transform(byte[] input) + { + return TransformInternal(input); + } + } +} diff --git a/Libraries/UniversalEditor.Core/IO/Transformations/XorTransformation.cs b/Libraries/UniversalEditor.Core/IO/Transformations/XorTransformation.cs new file mode 100644 index 00000000..e44a30b1 --- /dev/null +++ b/Libraries/UniversalEditor.Core/IO/Transformations/XorTransformation.cs @@ -0,0 +1,58 @@ +// +// XorTransform.cs +// +// Author: +// Mike Becker +// +// Copyright (c) 2020 Mike Becker +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +namespace UniversalEditor.IO.Transformations +{ + public class XorTransformation : Transformation + { + /// + /// Gets or sets a key used to encrypt or decrypt the stream. + /// + /// Pronounced "zorkie", like Sonny Eclipse ;) + /// The key used to encrypt or decrypt this stream, or if no key is needed. + public byte[] XorKey { get; set; } = null; + + public int XorKeyIndex { get; set; } = 0; + + /// + /// Initializes a new instance of the class. + /// + /// The key used to encrypt or decrypt this stream, or if no key is needed. + public XorTransformation(byte[] xorkey = null) + { + XorKey = xorkey; + XorKeyIndex = 0; + } + + protected override byte[] TransformInternal(byte[] input) + { + if (XorKey == null) return input; + for (int i = 0; i < input.Length; i++) + { + if (XorKeyIndex >= XorKey.Length) + XorKeyIndex = 0; + + input[i] ^= XorKey[XorKeyIndex]; + } + return input; + } + } +} diff --git a/Libraries/UniversalEditor.Core/IO/Writer.cs b/Libraries/UniversalEditor.Core/IO/Writer.cs index 65fdbd8b..93c4c8c5 100644 --- a/Libraries/UniversalEditor.Core/IO/Writer.cs +++ b/Libraries/UniversalEditor.Core/IO/Writer.cs @@ -50,9 +50,16 @@ namespace UniversalEditor.IO { WriteBytes(new byte[] { (byte)value }); } + + private int xorkey_index = 0; public void WriteBytes(byte[] data) { if (data == null) return; + + for (int i = 0; i < Transformations.Count; i++) + { + data = Transformations[i].Transform(data); + } Write(data, 0, data.Length); } @@ -204,21 +211,12 @@ namespace UniversalEditor.IO public void WriteNullTerminatedString(string sz) { - if (sz != null) - { - for (int i = 0; i < sz.Length; i++) - { - WriteChar(sz[i]); - } - } - WriteChar('\0'); + WriteNullTerminatedString(sz, Encoding.UTF8); } public void WriteNullTerminatedString(string sz, Encoding encoding) { - byte[] values = encoding.GetBytes(sz); - + byte[] values = encoding.GetBytes(sz + '\0'); WriteBytes(values); - WriteInt16(0); } public void WriteNullTerminatedString(string sz, int length) { diff --git a/Libraries/UniversalEditor.Core/UniversalEditor.Core.csproj b/Libraries/UniversalEditor.Core/UniversalEditor.Core.csproj index 85b3f020..171e4194 100644 --- a/Libraries/UniversalEditor.Core/UniversalEditor.Core.csproj +++ b/Libraries/UniversalEditor.Core/UniversalEditor.Core.csproj @@ -89,6 +89,8 @@ + + @@ -97,6 +99,9 @@ MBS.Framework + + +