Пример #1
0
        /***********************/
        /*** private methods ***/
        /***********************/


        private Session CheckForConnectionAesKey(IpPacket[] tcpRemotePlayPackets)
        {
            int ipProtocolHeaderSize = 20;

            for (int i = 0; i < tcpRemotePlayPackets.Length; i++)
            {
                var tcpRemotePlayPacket = tcpRemotePlayPackets[i];
                if (tcpRemotePlayPacket.PacketData.Array != null && tcpRemotePlayPacket.PacketData.Array.Length > 0)
                {
                    int    length  = tcpRemotePlayPacket.PacketData.Count - ipProtocolHeaderSize;
                    byte[] payload = new byte[length];
                    Buffer.BlockCopy(tcpRemotePlayPacket.PacketData.Array, tcpRemotePlayPacket.PacketData.Offset + ipProtocolHeaderSize, payload, 0, payload.Length);

                    string encodedPayload = Encoding.ASCII.GetString(payload);
                    if (encodedPayload.StartsWith("GET /sce/rp/session HTTP/1.1\r\n"))
                    {
                        Dictionary <string, string> httpHeaders = ByteUtil.ByteArrayToHttpHeader(payload);
                        httpHeaders.TryGetValue("RP-Registkey", out var rpRegistKey);
                        AppendLogOutputToPcapLogTextBox("RP-Registkey: " + rpRegistKey);
                        if (i < tcpRemotePlayPackets.Length - 1)
                        {
                            var sessionResponse = tcpRemotePlayPackets[i + 1];
                            if (sessionResponse.PacketData.Array == null ||
                                sessionResponse.PacketData.Array.Length < 1)
                            {
                                return(null);
                            }

                            length  = sessionResponse.PacketData.Count - ipProtocolHeaderSize;
                            payload = new byte[length];
                            Buffer.BlockCopy(sessionResponse.PacketData.Array, sessionResponse.PacketData.Offset + ipProtocolHeaderSize, payload, 0, payload.Length);

                            encodedPayload = Encoding.ASCII.GetString(payload);
                            if (encodedPayload.StartsWith("HTTP/1.1 200 OK\r\n"))
                            {
                                httpHeaders = ByteUtil.ByteArrayToHttpHeader(payload);
                                httpHeaders.TryGetValue("RP-Nonce", out var rpNonce);
                                if (rpNonce == null)
                                {
                                    return(null);
                                }

                                byte[] rpKeyBuffer    = HexUtil.Unhexlify(_settingManager.GetRemotePlayData().RemotePlay.RpKey);
                                byte[] rpNonceDecoded = Convert.FromBase64String(rpNonce);

                                AppendLogOutputToPcapLogTextBox("RP-Nonce from \"/sce/rp/session\" response: " + HexUtil.Hexlify(rpNonceDecoded));

                                string controlAesKey = HexUtil.Hexlify(CryptoService.GetSessionAesKeyForControl(rpKeyBuffer, rpNonceDecoded));
                                string controlNonce  = HexUtil.Hexlify(CryptoService.GetSessionNonceValueForControl(rpNonceDecoded));
                                AppendLogOutputToPcapLogTextBox("!!! Control AES Key: " + controlAesKey);
                                AppendLogOutputToPcapLogTextBox("!!! Control AES Nonce: " + controlNonce + Environment.NewLine);
                                return(CryptoService.GetSessionForControl(rpKeyBuffer, rpNonceDecoded));
                            }
                        }
                    }
                }
            }

            return(null);
        }
        public void PairConsole(string psnId, int pin)
        {
            Task.Factory.StartNew(() =>
            {
                lock (_lockObject)
                {
                    try
                    {
                        IPEndPoint ps4EndPoint = FindConsole();
                        if (ps4EndPoint == null)
                        {
                            OnPs4RegisterError?.Invoke(this,
                                                       "Could not connect to PS4. PS4 not found or not answering");
                            return;
                        }

                        Session session = CryptoService.GetSessionForPin(pin);

                        Dictionary <string, string> registrationHeaders = new Dictionary <string, string>();
                        registrationHeaders.Add("Client-Type", "Windows");
                        registrationHeaders.Add("Np-Online-Id", psnId);
                        byte[] payload = session.Encrypt(ByteUtil.HttpHeadersToByteArray(registrationHeaders));

                        SecureRandom random = new SecureRandom();
                        byte[] buffer       = new byte[480];
                        random.NextBytes(buffer);

                        byte[] paddedPayload   = ByteUtil.ConcatenateArrays(buffer, payload);
                        byte[] nonceDerivative = session.GetNonceDerivative();
                        byte[] finalPaddedPayload;
                        using (var ms = new MemoryStream())
                        {
                            ms.SetLength(paddedPayload.Length);
                            ms.Write(paddedPayload, 0, paddedPayload.Length);
                            ms.Seek(284, SeekOrigin.Begin);
                            ms.Write(nonceDerivative, 0, nonceDerivative.Length);
                            finalPaddedPayload = ms.ToArray();
                        }

                        IPEndPoint ipEndPoint = new IPEndPoint(ps4EndPoint.Address, RpControlPort);
                        Socket socket         = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                        socket.Connect(ipEndPoint);

                        string requestData = "POST /sce/rp/regist HTTP/1.1\r\n" +
                                             $"HOST: {ps4EndPoint.Address}\r\n" +
                                             "User-Agent: remoteplay Windows\r\n" +
                                             "Connection: close\r\n" +
                                             $"Content-Length: {finalPaddedPayload.Length}\r\n" +
                                             "\r\n";

                        socket.Send(ByteUtil.ConcatenateArrays(Encoding.UTF8.GetBytes(requestData),
                                                               finalPaddedPayload));

                        byte[] receiveBuffer = new byte[8192];
                        int readBytes        = socket.Receive(receiveBuffer);
                        byte[] response      = new byte[readBytes];
                        Buffer.BlockCopy(receiveBuffer, 0, response, 0, response.Length);
                        string httpResponse = Encoding.ASCII.GetString(receiveBuffer, 0, readBytes);

                        HttpStatusCode statusCode = HttpUtils.GetStatusCode(httpResponse);
                        if (statusCode == HttpStatusCode.OK)
                        {
                            byte[] responseData  = HttpUtils.GetBodyPayload(response);
                            byte[] decryptedData = session.Decrypt(responseData);
                            string registerHeaderInfoComplete       = Encoding.UTF8.GetString(decryptedData);
                            Dictionary <string, string> httpHeaders = ByteUtil.ByteArrayToHttpHeader(decryptedData);
                            httpHeaders.TryGetValue("AP-Ssid", out var apSsid);
                            httpHeaders.TryGetValue("AP-Bssid", out var apBssid);
                            httpHeaders.TryGetValue("AP-Key", out var apKey);
                            httpHeaders.TryGetValue("AP-Name", out var name);
                            httpHeaders.TryGetValue("PS4-Mac", out var mac);
                            httpHeaders.TryGetValue("PS4-RegistKey", out var registrationKey);
                            httpHeaders.TryGetValue("PS4-Nickname", out var nickname);
                            httpHeaders.TryGetValue("RP-KeyType", out var rpKeyType);
                            httpHeaders.TryGetValue("RP-Key", out var rpKey);

                            OnPs4RegisterSuccess?.Invoke(this, new PS4RegisterModel(apSsid, apBssid, apKey, name, mac, registrationKey, nickname, rpKeyType, rpKey, registerHeaderInfoComplete));
                        }
                        else
                        {
                            OnPs4RegisterError?.Invoke(this, "sce/rp/regist was not successful, return code was: " + statusCode);
                        }
                    }
                    catch (Exception e)
                    {
                        OnPs4RegisterError?.Invoke(this, "Could not connect to PS4. Exception: " + e);
                    }
                }
            });
        }