Example #1
0
        private static async Task <bool> GetHeader(Stream stream, byte[] messageHeader, ISharedArrayPool sharedArrayPool)
        {
            var binaryReader        = new AsyncBinaryReader(stream);
            var messageHeaderLength = await binaryReader.ReadUInt16Async();

            Debug.Assert(messageHeaderLength == messageHeader.Length);
            if (messageHeaderLength != messageHeader.Length)
            {
                // 消息不对,忽略
                return(false);
            }

            var messageHeaderBuffer = sharedArrayPool.Rent(messageHeader.Length);

            try
            {
                var readCount = await ReadBufferAsync(stream, messageHeaderBuffer, messageHeader.Length);

                Debug.Assert(readCount == messageHeader.Length);
                if (ByteListExtension.Equals(messageHeaderBuffer, messageHeader, readCount))
                {
                    // 读对了
                    return(true);
                }
                else
                {
                    // 发过来的消息是出错的
                    return(false);
                }
            }
            finally
            {
                sharedArrayPool.Return(messageHeaderBuffer);
            }
        }
Example #2
0
        public static async Task <IpcMessageResult> ReadAsync(Stream stream,
                                                              byte[] messageHeader, ISharedArrayPool sharedArrayPool)
        {
            /*
             * UInt16 Message Header Length 消息头的长度
             * byte[] Message Header        消息头的内容
             * UInt32 Version        当前IPC服务的版本
             * UInt64 Ack            用于给对方确认收到消息使用
             * UInt32 Empty          给以后版本使用的值
             * UInt16 Command Type   命令类型,业务端的值将会是 0 而框架层采用其他值
             * UInt32 Content Length 这条消息的内容长度
             * byte[] Content        实际的内容
             */

            if (!await GetHeader(stream, messageHeader, sharedArrayPool))
            {
                // 消息不对,忽略
                return(new IpcMessageResult("Message Header no match"));
            }

            var binaryReader = new AsyncBinaryReader(stream);
            // UInt32 Version        当前IPC服务的版本
            var version = await binaryReader.ReadUInt32Async();

            Debug.Assert(version == 1);
            if (version == 0)
            {
                // 这是上个版本的,但是不兼容了
                return(new IpcMessageResult("收到版本为 0 的旧版本消息,但是不兼容此版本"));
            }

            // UInt64 Ack            用于给对方确认收到消息使用
            var ack = await binaryReader.ReadReadUInt64Async();

            // UInt32 Empty          给以后版本使用的值
            var empty = await binaryReader.ReadUInt32Async();

            Debug.Assert(empty == 0);

            // UInt16 Command Type   命令类型,业务端的值将会是大于 0 而框架层采用其他值
            var commandType = (IpcMessageCommandType)await binaryReader.ReadUInt16Async();

            // UInt32 Content Length 这条消息的内容长度
            var messageLength = await binaryReader.ReadUInt32Async();

            if (messageLength > IpcConfiguration.MaxMessageLength)
            {
                // 太长了
                return(new IpcMessageResult(
                           $"Message Length too long  MessageLength={messageLength} MaxMessageLength={IpcConfiguration.MaxMessageLength}. {DebugContext.OverMaxMessageLength}"));
            }

            var messageBuffer = sharedArrayPool.Rent((int)messageLength);
            // byte[] Content        实际的内容
            var readCount = await ReadBufferAsync(stream, messageBuffer, (int)messageLength);

            Debug.Assert(readCount == messageLength);

            var ipcMessageContext = new IpcMessageContext(ack, messageBuffer, messageLength, sharedArrayPool);

            return(new IpcMessageResult(success: true, ipcMessageContext, commandType));
        }
Example #3
0
        public async Task TestAsyncBinaryReader()
        {
            byte customByte = 39;
            bool customBool = Unsafe.As <byte, bool>(ref customByte);

            object[] expectedResults =
            {
                true,
                false,
                customBool,
                (byte)42,
                (sbyte)-28,
                (short)-279,
                (ushort)64221,
                (int)-288888,
                (uint)3310229011,
                (float)3811.55f,
                (long)-19195205991011,
                (ulong)11223372036854775807,
                (double)Math.PI,
                (decimal)295222.2811m
            };

            using (var ms = new MemoryStream())
            {
                using (var wr = new BinaryWriter(ms, Encoding.Default, leaveOpen: true))
                {
                    foreach (dynamic obj in expectedResults)
                    {
                        wr.Write(obj);
                    }
                }

                ms.Position = 0;

                using (var rd = new AsyncBinaryReader(ms, Encoding.Default, leaveOpen: true))
                {
                    foreach (var obj in expectedResults)
                    {
                        switch (obj)
                        {
                        case bool b8:
                            ////Assert.Equal(b8, await rd.ReadBooleanAsync());
                            if (b8)
                            {
                                Assert.True(await rd.ReadBooleanAsync());
                            }
                            else
                            {
                                Assert.False(await rd.ReadBooleanAsync());
                            }

                            break;

                        case byte u8:
                            Assert.Equal(u8, await rd.ReadByteAsync());
                            break;

                        case sbyte s8:
                            Assert.Equal(s8, await rd.ReadSByteAsync());
                            break;

                        case short s16:
                            Assert.Equal(s16, await rd.ReadInt16Async());
                            break;

                        case ushort u16:
                            Assert.Equal(u16, await rd.ReadUInt16Async());
                            break;

                        case int s32:
                            Assert.Equal(s32, await rd.ReadInt32Async());
                            break;

                        case uint u32:
                            Assert.Equal(u32, await rd.ReadUInt32Async());
                            break;

                        case long s64:
                            Assert.Equal(s64, await rd.ReadInt64Async());
                            break;

                        case ulong u64:
                            Assert.Equal(u64, await rd.ReadUInt64Async());
                            break;

                        case float f32:
                            Assert.Equal(f32, await rd.ReadSingleAsync());
                            break;

                        case double f64:
                            Assert.Equal(f64, await rd.ReadDoubleAsync());
                            break;

                        case decimal d128:
                            Assert.Equal(d128, await rd.ReadDecimalAsync());
                            break;
                        }
                    }
                }
            }
        }
Example #4
0
        private async Task HandleLogonChallengeAsync()
        {
            var error = await _reader.ReadUInt8Async(); // always 3

            var size = await _reader.ReadUInt16Async();

            if (_client.Available < size)
            {
                await CloseAsync(AuthStatus.ProtocolError);

                return;
            }

            var gameName = await _reader.ReadUInt32Async();

            if (gameName != GameName)
            {
                await CloseAsync(AuthStatus.ProtocolError);

                return;
            }

            var versionMajor = await _reader.ReadUInt8Async();

            var versionMinor = await _reader.ReadUInt8Async();

            var versionPatch = await _reader.ReadUInt8Async();

            _buildNumber = await _reader.ReadUInt16Async();

            var platform = (Architecture)await _reader.ReadUInt32Async();

            var os = (OperatingSystem)await _reader.ReadUInt32Async();

            var locale = (Locale)await _reader.ReadUInt32Async();

            var timezoneBias = await _reader.ReadUInt32Async();

            var ipAddress   = new IPAddress(await _reader.ReadUInt32Async());
            var realAddress = (_client.Client.RemoteEndPoint as IPEndPoint).Address;

            var accountNameLength = await _reader.ReadUInt8Async();

            var accountName = await _reader.ReadStringAsync(accountNameLength);

            accountName = accountName.ToUpperInvariant();

            _info = Program.authDatabase.Accounts.Single(a => a.username == accountName);

            _info.last_ip = realAddress.ToString();
            //_info.last_login = new DateTime().ToUniversalTime().ToString();
            _info.os = os.ToString();
            //_info.locale = (int)locale; <not the same>

            byte[]     passhash = MimicUtils.HexStringToByteArray(_info.pass_hash);
            BigInteger s, v;

            if (_info.s != "" && _info.v != "")
            {
                s = SrpHandler.BigIntFromHexString(_info.s);
                v = SrpHandler.BigIntFromHexString(_info.v);
            }
            else
            {
                s = BigInteger.Zero;
                v = BigInteger.Zero;
            }
            _authentication.ComputePrivateFields(accountName, passhash, s, v);

            List <byte> data = new List <byte>();

            data.Add((byte)_currentCommand);
            data.Add(0);

            data.Add((byte)AuthStatus.Success);

            data.AddRange(_authentication.PublicKey); // B

            data.Add((byte)_authentication.Generator.Length);
            data.AddRange(_authentication.Generator); // g

            data.Add((byte)_authentication.SafePrime.Length);
            data.AddRange(_authentication.SafePrime); // N

            data.AddRange(_authentication.Salt);      // s

            data.AddRange(Enumerable.Repeat((byte)0, 16));

            data.Add(0); // security flags;

            await _clientStream.WriteAsync(data.ToArray(), 0, data.Count);
        }
Example #5
0
        private async Task HandleLogonChallengeAsync()
        {
            var error = await _reader.ReadUInt8Async(); // always 3

            var size = await _reader.ReadUInt16Async();

            if (_reader.Available < size)
            {
                await _writer.FailChallengeAsync(AuthStatus.ProtocolError);

                return;
            }

            var gameName = await _reader.ReadUInt32Async();

            if (gameName != GameName)
            {
                await _writer.FailChallengeAsync(AuthStatus.ProtocolError);

                return;
            }

            var versionMajor = await _reader.ReadUInt8Async();

            var versionMinor = await _reader.ReadUInt8Async();

            var versionPatch = await _reader.ReadUInt8Async();

            _buildNumber = await _reader.ReadUInt16Async();

            var platform = (Architecture)await _reader.ReadUInt32Async();

            var os = (OperatingSystem)await _reader.ReadUInt32Async();

            var locale = (Locale)await _reader.ReadUInt32Async();

            var timezoneBias = await _reader.ReadUInt32Async();

            var ipAddress   = new IPAddress(await _reader.ReadUInt32Async());
            var realAddress = (_client.Client.RemoteEndPoint as IPEndPoint).Address;

            var accountName = await _reader
                              .ReadStringAsync(StringEncoding.LengthPrefixedUInt8);

            accountName = accountName.ToUpperInvariant();

            using (var sha = SHA1.Create())
            {
                var pw = Encoding.UTF8.GetBytes(
                    $"{accountName}:{TestPassword}");
                var hash = sha.ComputeHash(pw);

                _authentication.ComputePrivateFields(accountName, hash);
            }

            await _writer.PassChallengeAsync(
                _authentication.PublicKey,
                _authentication.Generator,
                _authentication.SafePrime,
                _authentication.Salt);
        }
Example #6
0
        public static async Task<ISymbolMetadata> TryOpenAsync(Stream stream, CancellationToken cancellationToken)
        {
            using (var reader = new AsyncBinaryReader(stream))
            {
                try
                {
                    var IMAGE_DOS_HEADER_e_magic = await reader.ReadBytesAsync(_mzHeader.Length, cancellationToken);
                    if (!NativeMethods.MemoryEquals(IMAGE_DOS_HEADER_e_magic, _mzHeader)) return null;

                    stream.Position = 60;
                    var IMAGE_DOS_HEADER_e_lfanew = await reader.ReadUInt32Async(cancellationToken);

                    stream.Position = IMAGE_DOS_HEADER_e_lfanew;
                    var PE_Signature = await reader.ReadBytesAsync(_peHeader.Length, cancellationToken);
                    if (!NativeMethods.MemoryEquals(PE_Signature, _peHeader)) return null;

                    stream.Position = IMAGE_DOS_HEADER_e_lfanew + 4;
                    var IMAGE_FILE_HEADER_Machine = await reader.ReadUInt16Async(cancellationToken);

                    if (IMAGE_FILE_HEADER_Machine != 0x014c &&
                        IMAGE_FILE_HEADER_Machine != 0x0200 &&
                        IMAGE_FILE_HEADER_Machine != 0x8664)
                        return null;

                    stream.Position = IMAGE_DOS_HEADER_e_lfanew + 8;
                    var IMAGE_FILE_HEADER_TimeDateStamp = await reader.ReadUInt32Async(cancellationToken);

                    stream.Position = IMAGE_DOS_HEADER_e_lfanew + 24;
                    var IMAGE_OPTIONAL_HEADER_Magic = await reader.ReadUInt16Async(cancellationToken);

                    if (IMAGE_OPTIONAL_HEADER_Magic != 0x10b &&
                        IMAGE_OPTIONAL_HEADER_Magic != 0x20b)
                        return null;

                    stream.Position = IMAGE_DOS_HEADER_e_lfanew + 80;
                    var IMAGE_OPTIONAL_HEADER_SizeOfImage = await reader.ReadUInt16Async(cancellationToken);

                    return new MZMetadata(string.Format(
                        CultureInfo.InvariantCulture,
                        "{0:X8}{1:x4}",
                        IMAGE_FILE_HEADER_TimeDateStamp,
                        IMAGE_OPTIONAL_HEADER_SizeOfImage));
                }
                catch
                {
                    return null;
                }
            }
        }