Exemple #1
0
        /// <summary>
        /// Decrypts the given buffer. The buffer must be 64 bytes long.
        /// </summary>
        /// <param name="buffer"></param>
        public void Decrypt64(RandomAccess buffer)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (buffer.Length != 64)
            {
                throw new ArgumentException($"The given buffer was not 64 bytes ({buffer.Length}).", nameof(buffer));
            }

            for (int i = 0x0F; i >= 0; i--)
            {
                int positionA = i;
                int keyA      = GetWord(positionA);
                int positionB = keyA & 0x0F;

                int data1 = buffer.JumpAbsolute(positionA * 4).LongLE();
                data1 -= keyA;
                int data2 = buffer.JumpAbsolute(positionB * 4).LongLE();
                data2 -= keyA;

                int opAnd1 = data1 & keyA;
                int opNotA = ~keyA;
                int opAnd2 = data2 & opNotA;
                int opOr1  = opAnd1 | opAnd2;
                buffer.JumpAbsolute(positionA * 4).WriteLongLE(opOr1);

                int opAnd3 = data2 & keyA;
                int opAnd4 = data1 & opNotA;
                int opOr2  = opAnd3 | opAnd4;
                buffer.JumpAbsolute(positionB * 4).WriteLongLE(opOr2);
            }
        }
        public void LEReadWriteTest()
        {
            var ra    = new RandomAccess(new byte[] { 1, 2, 3, 4 });
            int value = ra.LongLE();

            ra.JumpAbsolute(0);
            ra.WriteLongLE(value);
            ra.JumpAbsolute(0);
            int value2 = ra.LongLE();

            Assert.AreEqual(value, value2);
        }
Exemple #3
0
        public void ShouldSkipPartiallyOverwrittenBlock()
        {
            var rx = new RandomAccess(new byte[4 * 256]);

            rx.WriteLongLE(0);
            rx.WriteLongLE(0x300);

            rx.JumpAbsolute(0x100); // Inside the previous block!
            rx.WriteLongLE(0x100);
            rx.WriteLongLE(0x200);

            rx.JumpAbsolute(0);

            var block = new TpsBlock(rx, 0, 0x300, false);

            Assert.AreEqual(1, block.Pages.Count);
            Assert.AreEqual(0x100, block.Pages[0].Address);
            Assert.AreEqual(0x200, block.Pages[0].Size);
        }
Exemple #4
0
        public void ShouldReadTwoBlocksWithGap()
        {
            var rx = new RandomAccess(new byte[4 * 256]);

            rx.WriteLongLE(0);
            rx.WriteLongLE(0x100);

            rx.JumpAbsolute(0x200);
            rx.WriteLongLE(0x200);
            rx.WriteLongLE(0x100);

            rx.JumpAbsolute(0);

            var block = new TpsBlock(rx, 0, 0x300, false);

            Assert.AreEqual(2, block.Pages.Count);
            Assert.AreEqual(0x100, block.Pages[0].Size);
            Assert.AreEqual(0x100, block.Pages[1].Size);
        }
Exemple #5
0
        /// <summary>
        /// Encrypts the given buffer. The buffer must be 64 bytes long.
        /// </summary>
        /// <param name="buffer">The buffer to encrypt.</param>
        public void Encrypt64(RandomAccess buffer)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (buffer.Length != 64)
            {
                throw new ArgumentException($"The given buffer was not 64 bytes ({buffer.Length}).", nameof(buffer));
            }

            for (int i = 0; i < 0x10; i++)
            {
                int positionA = i;
                int keyA      = GetWord(i);
                int positionB = keyA & 0x0F;

                int data2 = buffer.JumpAbsolute(positionA * 4).LongLE();
                int data1 = buffer.JumpAbsolute(positionB * 4).LongLE();

                int opAnd1 = keyA & data2;
                int opNotA = ~keyA;
                int opAnd2 = opNotA & data1;
                int opOr1  = opAnd1 | opAnd2;

                int sum1 = keyA + opOr1;
                buffer.JumpAbsolute(positionA * 4).WriteLongLE(sum1);

                int opAnd3 = keyA & data1;
                int opAnd4 = opNotA & data2;
                int opOr2  = opAnd3 | opAnd4;
                int sum2   = opOr2 + keyA;

                buffer.JumpAbsolute(positionB * 4).WriteLongLE(sum2);
            }
        }
Exemple #6
0
        public TpsBlock(RandomAccess rx, int start, int end, bool ignorePageErrors)
        {
            Data   = rx ?? throw new ArgumentNullException(nameof(rx));
            Start  = start;
            End    = end;
            _pages = new List <TpsPage>();

            Data.PushPosition();
            Data.JumpAbsolute(Start);

            try
            {
                // Some blocks are 0 in length and should be skipped
                while (Data.Position < End)
                {
                    if (IsCompletePage())
                    {
                        try
                        {
                            var page = new TpsPage(Data);
                            _pages.Add(page);
                        }
                        catch (RunLengthEncodingException ex)
                        {
                            if (ignorePageErrors)
                            {
                                Debug.WriteLine($"Ignored RLE error: {ex.ToString()}");
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }
                    else
                    {
                        Data.JumpRelative(0x100);
                    }

                    NavigateToNextPage();
                }
            }
            finally
            {
                Data.PopPosition();
            }
        }