Example #1
0
        public Form1()
        {
            InitializeComponent();

            _settingManager         = SettingManager.GetInstance();
            _ps4RegistrationService = new PS4RegistrationService();
            _ps4DiscoveryService    = new PS4DiscoveryService();
            _ps4ConnectionService   = new PS4ConnectionService();
            _livePcapContext        = new LivePcapContext();

            _ps4RegistrationService.OnPs4RegisterSuccess += OnPs4RegisterSuccess;
            _ps4RegistrationService.OnPs4RegisterError   += OnPs4RegisterError;

            _ps4ConnectionService.OnPs4ConnectionSuccess += OnPs4ConnectionSuccess;
            _ps4ConnectionService.OnPs4Disconnected      += OnPs4Disconnected;
            _ps4ConnectionService.OnPs4ConnectionError   += OnPs4ConnectionError;
            _ps4ConnectionService.OnPs4LogInfo           += OnPs4LogInfo;

            PS4RemotePlayData remotePlayData = _settingManager.GetRemotePlayData();

            if (remotePlayData != null)
            {
                UpdateRegisterInfoTextBox(remotePlayData.RemotePlay.RegisterHeaderInfoComplete);
                EnableConnectButton();
                EnablePcapButton();
                SetUpComboBoxNetworkAdapter();
            }
            else
            {
                MessageBox.Show("Please register firts with your PS4 in order to use all features", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
Example #2
0
        public bool SavePS4RemotePlayData(PS4RemotePlayData ps4RemotePlayData)
        {
            bool result = true;

            try
            {
                if (!Directory.Exists(_ps4RemotePlayDataSettingsPath))
                {
                    Directory.CreateDirectory(_ps4RemotePlayDataSettingsPath);
                }

                var serializer = new XmlSerializer(ps4RemotePlayData.GetType());
                using (var writer = XmlWriter.Create(_ps4RemotePlayDataSettingsFullPath, new XmlWriterSettings {
                    Indent = true, NewLineHandling = NewLineHandling.Entitize
                }))
                {
                    serializer.Serialize(writer, ps4RemotePlayData);
                }

                _currentRemotePlayData = ps4RemotePlayData;
            }
            catch (Exception)
            {
                result = false;
            }

            return(result);
        }
Example #3
0
 private void button2_Click(object sender, EventArgs e)
 {
     DisableConnectButton();
     ClearLogOutput();
     _ps4DiscoveryService.DiscoverConsole(pS4DiscoveryInfo =>
     {
         if (pS4DiscoveryInfo == null)
         {
             this.button2.Invoke(new MethodInvoker(EnableConnectButton));
             MessageBox.Show("PS4 not found in network or not answering!", "Not found", MessageBoxButtons.OK, MessageBoxIcon.Error);
         }
         else
         {
             this.textBoxLogOutput.Invoke(new MethodInvoker(() => AppendLogOutput("Discovery response:" + Environment.NewLine + pS4DiscoveryInfo.RawResponseData)));
             if (pS4DiscoveryInfo.Status == 620)
             {
                 this.button2.Invoke(new MethodInvoker(EnableConnectButton));
                 MessageBox.Show("PS4 Found but status is 620, wake up is currently not implemented", "Found", MessageBoxButtons.OK, MessageBoxIcon.Information);
             }
             else
             {
                 PS4RemotePlayData remotePlayData = _settingManager.GetRemotePlayData();
                 if (remotePlayData != null)
                 {
                     _ps4ConnectionService.ConnectToPS4(pS4DiscoveryInfo.Ps4EndPoint, remotePlayData);
                 }
                 else
                 {
                     this.button2.Invoke(new MethodInvoker(EnableConnectButton));
                     MessageBox.Show("Could not connect to PS4. No register data is available.", "No PS4 Data", MessageBoxButtons.OK, MessageBoxIcon.Error);
                 }
             }
         }
     });
 }
 public void ConnectToPS4(IPEndPoint ps4Endpoint, PS4RemotePlayData ps4RemotePlayData)
 {
     Task.Factory.StartNew(() =>
     {
         lock (_lockObject)
         {
             HandleSessionRequest(ps4Endpoint, ps4RemotePlayData);
         }
     });
 }
        /***********************/
        /*** private methods ***/
        /***********************/

        /*********** Session request ***********/

        private void HandleSessionRequest(IPEndPoint ps4Endpoint, PS4RemotePlayData ps4RemotePlayData)
        {
            try
            {
                IPEndPoint ipEndPoint = new IPEndPoint(ps4Endpoint.Address, ControlPort);
                using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                {
                    socket.ReceiveTimeout = 5000;
                    socket.Connect(ipEndPoint);

                    string requestData = "GET /sce/rp/session HTTP/1.1\r\n" +
                                         $"HOST: {ps4Endpoint.Address}\r\n" +
                                         "User-Agent: remoteplay Windows\r\n" +
                                         "Connection: close\r\n" +
                                         "Content-Length: 0\r\n" +
                                         $"RP-Registkey: {ps4RemotePlayData.RemotePlay.RegistrationKey}\r\n" +
                                         "RP-Version: 8.0\r\n" +
                                         "\r\n";

                    socket.Send(Encoding.UTF8.GetBytes(requestData));

                    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)
                    {
                        OnPs4LogInfo?.Invoke(this, "\"/sce/rp/session\" response: " + Environment.NewLine + httpResponse.Trim() + Environment.NewLine);
                        Dictionary <string, string> responseHeader = HttpUtils.SplitHttpResponse(httpResponse);
                        responseHeader.TryGetValue("RP-Nonce", out var rpNonce);
                        if (rpNonce == null)
                        {
                            socket.Close();
                        }
                        else
                        {
                            socket.Close();
                            this.HandleControlRequest(rpNonce, ps4Endpoint, ps4RemotePlayData);
                        }
                    }
                    else
                    {
                        OnPs4ConnectionError?.Invoke(this, "Connecting to PS4 was not successful, result code was " + statusCode);
                    }
                }
            }
            catch (Exception e)
            {
                OnPs4ConnectionError?.Invoke(this, "Exception occured by sending /sce/rp/session" + e);
            }
        }
Example #6
0
        private void button3_Click(object sender, EventArgs e)
        {
            PS4RemotePlayData remotePlayData = _settingManager.GetRemotePlayData();

            if (remotePlayData != null)
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();
                openFileDialog.Filter = @"PCAP files|*.pcap";
                DialogResult result = openFileDialog.ShowDialog(); // Show the dialog.
                if (result == DialogResult.OK)                     // Test result.
                {
                    ClearPcapOutputLogOutput();
                    string file = openFileDialog.FileName;
                    try
                    {
                        var packets              = Pcap.ReadFile(file).TrySelect(record => PacketParser.Parse(new ArraySegment <byte>(record.Data.Skip(14).ToArray())));
                        var ipPackets            = packets as IpPacket[] ?? packets.ToArray();
                        var tcpRemotePlayPackets = ipPackets.
                                                   Where(p => p != null).
                                                   Where(p => p.ProtocolType == ProtocolType.Tcp).
                                                   Where(p =>
                        {
                            var packetData         = p.PacketData.AsByteArraySegment();
                            ushort sourcePort      = p.PacketData.Array.ReadNetOrderUShort(packetData.Offset);
                            ushort destinationPort = p.PacketData.Array.ReadNetOrderUShort(2 + packetData.Offset);
                            return(sourcePort == 9295 || destinationPort == 9295);
                        }).
                                                   ToArray();

                        var udpRemotePlayPackets = ipPackets.
                                                   Where(p => p != null).
                                                   Where(p => p.ProtocolType == ProtocolType.Udp).
                                                   Select(p => p.ToUdpDatagram()).
                                                   Where(p => p.UdpDatagramHeader.SourcePort == 9296 ||
                                                         p.UdpDatagramHeader.DestinationPort == 9296).
                                                   ToArray();

                        Session session = CheckForConnectionAesKey(tcpRemotePlayPackets);
                        CheckForBigBangPayload(udpRemotePlayPackets, session);
                    }
                    catch (IOException)
                    {
                    }
                }
            }
            else
            {
                MessageBox.Show("Could not search for AES keys. No register data is available.", "No PS4 Data", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Example #7
0
        /*********************/
        /*** event handler ***/
        /*********************/

        private void OnPs4RegisterSuccess(object sender, PS4RegisterModel ps4RegisterModel)
        {
            this.button1.Invoke(new MethodInvoker(EnableRegistryButton));
            PS4RemotePlayData ps4RemotePlayData = new PS4RemotePlayData()
            {
                RemotePlay = new PS4RemotePlayDataRemotePlay()
                {
                    ApSsid                     = ps4RegisterModel.ApSsid,
                    ApBsid                     = ps4RegisterModel.ApBsid,
                    ApKey                      = ps4RegisterModel.ApKey,
                    Name                       = ps4RegisterModel.Name,
                    Mac                        = ps4RegisterModel.Mac,
                    RegistrationKey            = ps4RegisterModel.RegistrationKey,
                    Nickname                   = ps4RegisterModel.Nickname,
                    RpKeyType                  = ps4RegisterModel.RpKeyType,
                    RpKey                      = ps4RegisterModel.RpKey,
                    RegisterHeaderInfoComplete = ps4RegisterModel.RegisterHeaderInfoComplete
                }
            };

            _settingManager.SavePS4RemotePlayData(ps4RemotePlayData);
            if (this.textBoxRegisterInfo.InvokeRequired)
            {
                this.textBoxRegisterInfo.Invoke(new MethodInvoker(() =>
                {
                    UpdateRegisterInfoTextBox(ps4RegisterModel.RegisterHeaderInfoComplete);
                    EnableConnectButton();
                    EnablePcapButton();
                    MessageBox.Show("Successfully registered with PS4", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }));
            }
            else
            {
                UpdateRegisterInfoTextBox(ps4RegisterModel.RegisterHeaderInfoComplete);
                EnableConnectButton();
                EnablePcapButton();
                MessageBox.Show("Successfully registered with PS4", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
Example #8
0
 private SettingManager()
 {
     _ps4RemotePlayDataSettingsPath     = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), CustomPs4RemotePlayFolderName);
     _ps4RemotePlayDataSettingsFullPath = Path.Combine(_ps4RemotePlayDataSettingsPath, Ps4RemotePlayDataFileName);
     _currentRemotePlayData             = ReadRemotePlayData();
 }
        /*********** Control request ***********/

        private void HandleControlRequest(string rpNonce, IPEndPoint ps4Endpoint, PS4RemotePlayData ps4RemotePlayData)
        {
            bool   connectedSuccess = false;
            Socket socket           = null;

            try
            {
                IPEndPoint ipEndPoint = new IPEndPoint(ps4Endpoint.Address, ControlPort);
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Connect(ipEndPoint);

                byte[] rpKeyBuffer    = HexUtil.Unhexlify(ps4RemotePlayData.RemotePlay.RpKey);
                byte[] rpNonceDecoded = Convert.FromBase64String(rpNonce);
                OnPs4LogInfo?.Invoke(this,
                                     "RP-Nonce from \"/sce/rp/session\" response: " + HexUtil.Hexlify(rpNonceDecoded));

                Session session = CryptoService.GetSessionForControl(rpKeyBuffer, rpNonceDecoded);

                string controlAesKey = HexUtil.Hexlify(CryptoService.GetSessionAesKeyForControl(rpKeyBuffer, rpNonceDecoded));
                string controlNonce  = HexUtil.Hexlify(CryptoService.GetSessionNonceValueForControl(rpNonceDecoded));
                OnPs4LogInfo?.Invoke(this, "!!! Control AES Key: " + controlAesKey);
                OnPs4LogInfo?.Invoke(this, "!!! Control AES Nonce: " + controlNonce + Environment.NewLine);

                byte[] registrationKeyBuffer    = HexUtil.Unhexlify(ps4RemotePlayData.RemotePlay.RegistrationKey);
                byte[] registrationKeyPadding   = { 0, 0, 0, 0, 0, 0, 0, 0 };
                byte[] encryptedRegistrationKey =
                    session.Encrypt(ByteUtil.ConcatenateArrays(registrationKeyBuffer, registrationKeyPadding));
                string encodedRegistrationKey = Convert.ToBase64String(encryptedRegistrationKey);

                byte[] randomDid    = Guid.NewGuid().ToByteArray();
                byte[] didPrefix    = { 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80 };
                byte[] didPadding   = { 48, 48, 48, 48, 48, 48, 48 };
                byte[] encryptedDid = session.Encrypt(ByteUtil.ConcatenateArrays(didPrefix, randomDid, didPadding));
                string encodedDid   = Convert.ToBase64String(encryptedDid);

                string osType          = "Win10.0.0";
                byte[] osTypeBuffer    = Encoding.UTF8.GetBytes(osType);
                byte[] osTypePadding   = { 0 };
                byte[] encryptedOsType = session.Encrypt(ByteUtil.ConcatenateArrays(osTypeBuffer, osTypePadding));
                string encodedOsType   = Convert.ToBase64String(encryptedOsType);

                string host = ps4Endpoint.Address + ":" + ControlPort;

                string requestData = "GET /sce/rp/session/ctrl HTTP/1.1\r\n" +
                                     $"HOST: {host}\r\n" +
                                     "User-Agent: remoteplay Windows\r\n" +
                                     "Connection: keep-alive\r\n" +
                                     "Content-Length: 0\r\n" +
                                     $"RP-Auth: {encodedRegistrationKey}\r\n" +
                                     "RP-Version: 8.0\r\n" +
                                     $"RP-Did: {encodedDid}\r\n" +
                                     "RP-ControllerType: 3\r\n" +
                                     "RP-ClientType: 11\r\n" +
                                     $"RP-OSType: {encodedOsType}\r\n" +
                                     "RP-ConPath: 1\r\n" +
                                     "\r\n";

                socket.Send(Encoding.UTF8.GetBytes(requestData));
                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)
                {
                    OnPs4LogInfo?.Invoke(this, "\"/sce/rp/session/ctrl\" response: " + Environment.NewLine + httpResponse.Trim() + Environment.NewLine);
                    OnPs4LogInfo?.Invoke(this, "TCP connection to PS4 established" + Environment.NewLine);
                    _clientSocket = socket;
                    _clientSocket.ReceiveTimeout = 0;
                    PingPongAsyncResult connectionStateObject = new PingPongAsyncResult {
                        RemoteSocket = _clientSocket
                    };
                    connectionStateObject.RemoteSocket.BeginReceive(connectionStateObject.Buffer, 0,
                                                                    connectionStateObject.Buffer.Length, SocketFlags.None, PingPongHandler,
                                                                    connectionStateObject);
                    OnPs4ConnectionSuccess?.Invoke(this, EventArgs.Empty);
                    connectedSuccess = true;
                    InitializeRemotePlayChannel(session, ps4Endpoint);
                }
            }
            catch (Exception e)
            {
                OnPs4ConnectionError?.Invoke(this, "Exception occured /sce/rp/session/ctrl" + e);
            }
            finally
            {
                if (!connectedSuccess)
                {
                    socket?.Close();
                }
            }
        }