master d1369b76789b cached
18 files
129.3 KB
31.7k tokens
146 symbols
1 requests
Download .txt
Repository: ChendoChap/Playstation-4-Save-Mounter
Branch: master
Commit: d1369b76789b
Files: 18
Total size: 129.3 KB

Directory structure:
gitextract_y_dojabp/

├── .gitignore
├── LICENSE
├── Main.Designer.cs
├── Main.cs
├── PS4Saves.csproj
├── Program.cs
├── Properties/
│   └── AssemblyInfo.cs
├── README.md
├── functions.cs
├── libdebug/
│   ├── PS4DBG.Console.cs
│   ├── PS4DBG.Debug.cs
│   ├── PS4DBG.Kernel.cs
│   ├── PS4DBG.Proc.cs
│   ├── PS4DBG.cs
│   ├── Process.cs
│   └── Registers.cs
├── offsets.cs
└── structs.cs

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/

# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# Visual Studio 2017 auto generated files
Generated\ Files/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# Benchmark Results
BenchmarkDotNet.Artifacts/

# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json

# StyleCop
StyleCopReport.xml

# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# Visual Studio Trace Files
*.e2e

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json

# Visual Studio code coverage results
*.coverage
*.coveragexml

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs

# Including strong name files can present a security risk 
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak

# SQL Server files
*.mdf
*.ldf
*.ndf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# JetBrains Rider
.idea/
*.sln.iml

# CodeRush
.cr/

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config

# Tabs Studio
*.tss

# Telerik's JustMock configuration file
*.jmconfig

# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs

# OpenCover UI analysis results
OpenCover/

# Azure Stream Analytics local run output 
ASALocalRun/

# MSBuild Binary and Structured Log
*.binlog

# NVidia Nsight GPU debugger configuration file
*.nvuser

# MFractors (Xamarin productivity tool) working folder 
.mfractor/


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2018 ChendoChap

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Main.Designer.cs
================================================
namespace PS4Saves
{
    partial class Main
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.ipTextBox = new System.Windows.Forms.TextBox();
            this.connectButton = new System.Windows.Forms.Button();
            this.setupButton = new System.Windows.Forms.Button();
            this.userComboBox = new System.Windows.Forms.ComboBox();
            this.dirsComboBox = new System.Windows.Forms.ComboBox();
            this.searchButton = new System.Windows.Forms.Button();
            this.mountButton = new System.Windows.Forms.Button();
            this.unmountButton = new System.Windows.Forms.Button();
            this.connectionGroupBox = new System.Windows.Forms.GroupBox();
            this.getGamesButton = new System.Windows.Forms.Button();
            this.gamesComboBox = new System.Windows.Forms.ComboBox();
            this.payloadButton = new System.Windows.Forms.Button();
            this.ipLabel = new System.Windows.Forms.Label();
            this.createGroupBox = new System.Windows.Forms.GroupBox();
            this.sizeLabel = new System.Windows.Forms.Label();
            this.sizeTrackBar = new System.Windows.Forms.TrackBar();
            this.nameLabel = new System.Windows.Forms.Label();
            this.nameTextBox = new System.Windows.Forms.TextBox();
            this.createButton = new System.Windows.Forms.Button();
            this.mountGroupBox = new System.Windows.Forms.GroupBox();
            this.infoGroupBox = new System.Windows.Forms.GroupBox();
            this.dateTextBox = new System.Windows.Forms.TextBox();
            this.dateLabel = new System.Windows.Forms.Label();
            this.detailsTextBox = new System.Windows.Forms.TextBox();
            this.detailsLabel = new System.Windows.Forms.Label();
            this.subtitleTextBox = new System.Windows.Forms.TextBox();
            this.subtitleLabel = new System.Windows.Forms.Label();
            this.titleTextBox = new System.Windows.Forms.TextBox();
            this.titleLabel = new System.Windows.Forms.Label();
            this.sizeToolTip = new System.Windows.Forms.ToolTip(this.components);
            this.statusLabel = new System.Windows.Forms.Label();
            this.connectionGroupBox.SuspendLayout();
            this.createGroupBox.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.sizeTrackBar)).BeginInit();
            this.mountGroupBox.SuspendLayout();
            this.infoGroupBox.SuspendLayout();
            this.SuspendLayout();
            // 
            // ipTextBox
            // 
            this.ipTextBox.Location = new System.Drawing.Point(70, 19);
            this.ipTextBox.Name = "ipTextBox";
            this.ipTextBox.Size = new System.Drawing.Size(117, 20);
            this.ipTextBox.TabIndex = 0;
            // 
            // connectButton
            // 
            this.connectButton.Location = new System.Drawing.Point(284, 19);
            this.connectButton.Name = "connectButton";
            this.connectButton.Size = new System.Drawing.Size(90, 20);
            this.connectButton.TabIndex = 2;
            this.connectButton.Text = "Connect";
            this.connectButton.UseVisualStyleBackColor = true;
            this.connectButton.Click += new System.EventHandler(this.connectButton_Click);
            // 
            // setupButton
            // 
            this.setupButton.Location = new System.Drawing.Point(7, 45);
            this.setupButton.Name = "setupButton";
            this.setupButton.Size = new System.Drawing.Size(181, 21);
            this.setupButton.TabIndex = 3;
            this.setupButton.Text = "Setup";
            this.setupButton.UseVisualStyleBackColor = true;
            this.setupButton.Click += new System.EventHandler(this.setupButton_Click);
            // 
            // userComboBox
            // 
            this.userComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.userComboBox.FormattingEnabled = true;
            this.userComboBox.Location = new System.Drawing.Point(193, 45);
            this.userComboBox.Name = "userComboBox";
            this.userComboBox.Size = new System.Drawing.Size(181, 21);
            this.userComboBox.TabIndex = 4;
            this.userComboBox.SelectedIndexChanged += new System.EventHandler(this.userComboBox_SelectedIndexChanged);
            // 
            // dirsComboBox
            // 
            this.dirsComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.dirsComboBox.FormattingEnabled = true;
            this.dirsComboBox.Location = new System.Drawing.Point(193, 19);
            this.dirsComboBox.Name = "dirsComboBox";
            this.dirsComboBox.Size = new System.Drawing.Size(180, 21);
            this.dirsComboBox.TabIndex = 1;
            this.dirsComboBox.SelectedIndexChanged += new System.EventHandler(this.dirsComboBox_SelectedIndexChanged);
            // 
            // searchButton
            // 
            this.searchButton.Location = new System.Drawing.Point(6, 19);
            this.searchButton.Name = "searchButton";
            this.searchButton.Size = new System.Drawing.Size(181, 21);
            this.searchButton.TabIndex = 0;
            this.searchButton.Text = "Search";
            this.searchButton.UseVisualStyleBackColor = true;
            this.searchButton.Click += new System.EventHandler(this.searchButton_Click);
            // 
            // mountButton
            // 
            this.mountButton.Location = new System.Drawing.Point(6, 48);
            this.mountButton.Name = "mountButton";
            this.mountButton.Size = new System.Drawing.Size(181, 23);
            this.mountButton.TabIndex = 2;
            this.mountButton.Text = "Mount";
            this.mountButton.UseVisualStyleBackColor = true;
            this.mountButton.Click += new System.EventHandler(this.mountButton_Click);
            // 
            // unmountButton
            // 
            this.unmountButton.Location = new System.Drawing.Point(192, 48);
            this.unmountButton.Name = "unmountButton";
            this.unmountButton.Size = new System.Drawing.Size(181, 23);
            this.unmountButton.TabIndex = 3;
            this.unmountButton.Text = "Unmount";
            this.unmountButton.UseVisualStyleBackColor = true;
            this.unmountButton.Click += new System.EventHandler(this.unmountButton_Click);
            // 
            // connectionGroupBox
            // 
            this.connectionGroupBox.Controls.Add(this.getGamesButton);
            this.connectionGroupBox.Controls.Add(this.gamesComboBox);
            this.connectionGroupBox.Controls.Add(this.payloadButton);
            this.connectionGroupBox.Controls.Add(this.ipLabel);
            this.connectionGroupBox.Controls.Add(this.ipTextBox);
            this.connectionGroupBox.Controls.Add(this.connectButton);
            this.connectionGroupBox.Controls.Add(this.setupButton);
            this.connectionGroupBox.Controls.Add(this.userComboBox);
            this.connectionGroupBox.Location = new System.Drawing.Point(7, 12);
            this.connectionGroupBox.Name = "connectionGroupBox";
            this.connectionGroupBox.Size = new System.Drawing.Size(379, 105);
            this.connectionGroupBox.TabIndex = 0;
            this.connectionGroupBox.TabStop = false;
            this.connectionGroupBox.Text = "Connection";
            // 
            // getGamesButton
            // 
            this.getGamesButton.Location = new System.Drawing.Point(6, 72);
            this.getGamesButton.Name = "getGamesButton";
            this.getGamesButton.Size = new System.Drawing.Size(181, 21);
            this.getGamesButton.TabIndex = 5;
            this.getGamesButton.Text = "Get Games";
            this.getGamesButton.UseVisualStyleBackColor = true;
            this.getGamesButton.Click += new System.EventHandler(this.getGamesButton_Click);
            // 
            // gamesComboBox
            // 
            this.gamesComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this.gamesComboBox.FormattingEnabled = true;
            this.gamesComboBox.Location = new System.Drawing.Point(192, 72);
            this.gamesComboBox.Name = "gamesComboBox";
            this.gamesComboBox.Size = new System.Drawing.Size(181, 21);
            this.gamesComboBox.TabIndex = 6;
            this.gamesComboBox.SelectedIndexChanged += new System.EventHandler(this.gamesComboBox_SelectedIndexChanged);
            // 
            // payloadButton
            // 
            this.payloadButton.Location = new System.Drawing.Point(192, 19);
            this.payloadButton.Name = "payloadButton";
            this.payloadButton.Size = new System.Drawing.Size(90, 20);
            this.payloadButton.TabIndex = 1;
            this.payloadButton.Text = "Send Payload";
            this.payloadButton.UseVisualStyleBackColor = true;
            this.payloadButton.Click += new System.EventHandler(this.payloadButton_Click);
            // 
            // ipLabel
            // 
            this.ipLabel.AutoSize = true;
            this.ipLabel.Location = new System.Drawing.Point(6, 22);
            this.ipLabel.Name = "ipLabel";
            this.ipLabel.Size = new System.Drawing.Size(58, 13);
            this.ipLabel.TabIndex = 6;
            this.ipLabel.Text = "ip address:";
            // 
            // createGroupBox
            // 
            this.createGroupBox.Controls.Add(this.sizeLabel);
            this.createGroupBox.Controls.Add(this.sizeTrackBar);
            this.createGroupBox.Controls.Add(this.nameLabel);
            this.createGroupBox.Controls.Add(this.nameTextBox);
            this.createGroupBox.Controls.Add(this.createButton);
            this.createGroupBox.Location = new System.Drawing.Point(7, 210);
            this.createGroupBox.Name = "createGroupBox";
            this.createGroupBox.Size = new System.Drawing.Size(379, 129);
            this.createGroupBox.TabIndex = 2;
            this.createGroupBox.TabStop = false;
            this.createGroupBox.Text = "Create New Saves";
            // 
            // sizeLabel
            // 
            this.sizeLabel.AutoSize = true;
            this.sizeLabel.Location = new System.Drawing.Point(6, 48);
            this.sizeLabel.Name = "sizeLabel";
            this.sizeLabel.Size = new System.Drawing.Size(76, 13);
            this.sizeLabel.TabIndex = 9;
            this.sizeLabel.Text = "max save size:";
            // 
            // sizeTrackBar
            // 
            this.sizeTrackBar.Location = new System.Drawing.Point(117, 48);
            this.sizeTrackBar.Maximum = 32768;
            this.sizeTrackBar.Minimum = 96;
            this.sizeTrackBar.Name = "sizeTrackBar";
            this.sizeTrackBar.Size = new System.Drawing.Size(257, 45);
            this.sizeTrackBar.TabIndex = 1;
            this.sizeTrackBar.Value = 96;
            this.sizeTrackBar.Scroll += new System.EventHandler(this.sizeTrackBar_Scroll);
            // 
            // nameLabel
            // 
            this.nameLabel.AutoSize = true;
            this.nameLabel.Location = new System.Drawing.Point(6, 25);
            this.nameLabel.Name = "nameLabel";
            this.nameLabel.Size = new System.Drawing.Size(105, 13);
            this.nameLabel.TabIndex = 7;
            this.nameLabel.Text = "save directory name:";
            // 
            // nameTextBox
            // 
            this.nameTextBox.Location = new System.Drawing.Point(117, 22);
            this.nameTextBox.MaxLength = 31;
            this.nameTextBox.Name = "nameTextBox";
            this.nameTextBox.Size = new System.Drawing.Size(256, 20);
            this.nameTextBox.TabIndex = 0;
            // 
            // createButton
            // 
            this.createButton.Location = new System.Drawing.Point(5, 99);
            this.createButton.Name = "createButton";
            this.createButton.Size = new System.Drawing.Size(367, 23);
            this.createButton.TabIndex = 2;
            this.createButton.Text = "Create Save";
            this.createButton.UseVisualStyleBackColor = true;
            this.createButton.Click += new System.EventHandler(this.createButton_Click);
            // 
            // mountGroupBox
            // 
            this.mountGroupBox.Controls.Add(this.searchButton);
            this.mountGroupBox.Controls.Add(this.dirsComboBox);
            this.mountGroupBox.Controls.Add(this.mountButton);
            this.mountGroupBox.Controls.Add(this.unmountButton);
            this.mountGroupBox.Location = new System.Drawing.Point(7, 123);
            this.mountGroupBox.Name = "mountGroupBox";
            this.mountGroupBox.Size = new System.Drawing.Size(379, 81);
            this.mountGroupBox.TabIndex = 1;
            this.mountGroupBox.TabStop = false;
            this.mountGroupBox.Text = "Mount Existing Saves";
            // 
            // infoGroupBox
            // 
            this.infoGroupBox.Controls.Add(this.dateTextBox);
            this.infoGroupBox.Controls.Add(this.dateLabel);
            this.infoGroupBox.Controls.Add(this.detailsTextBox);
            this.infoGroupBox.Controls.Add(this.detailsLabel);
            this.infoGroupBox.Controls.Add(this.subtitleTextBox);
            this.infoGroupBox.Controls.Add(this.subtitleLabel);
            this.infoGroupBox.Controls.Add(this.titleTextBox);
            this.infoGroupBox.Controls.Add(this.titleLabel);
            this.infoGroupBox.Location = new System.Drawing.Point(392, 12);
            this.infoGroupBox.Name = "infoGroupBox";
            this.infoGroupBox.Size = new System.Drawing.Size(396, 327);
            this.infoGroupBox.TabIndex = 3;
            this.infoGroupBox.TabStop = false;
            this.infoGroupBox.Text = "Save Info";
            // 
            // dateTextBox
            // 
            this.dateTextBox.Location = new System.Drawing.Point(9, 294);
            this.dateTextBox.Name = "dateTextBox";
            this.dateTextBox.ReadOnly = true;
            this.dateTextBox.Size = new System.Drawing.Size(381, 20);
            this.dateTextBox.TabIndex = 3;
            // 
            // dateLabel
            // 
            this.dateLabel.AutoSize = true;
            this.dateLabel.Location = new System.Drawing.Point(6, 278);
            this.dateLabel.Name = "dateLabel";
            this.dateLabel.Size = new System.Drawing.Size(31, 13);
            this.dateLabel.TabIndex = 6;
            this.dateLabel.Text = "date:";
            // 
            // detailsTextBox
            // 
            this.detailsTextBox.Location = new System.Drawing.Point(9, 166);
            this.detailsTextBox.Multiline = true;
            this.detailsTextBox.Name = "detailsTextBox";
            this.detailsTextBox.ReadOnly = true;
            this.detailsTextBox.Size = new System.Drawing.Size(381, 109);
            this.detailsTextBox.TabIndex = 2;
            // 
            // detailsLabel
            // 
            this.detailsLabel.AutoSize = true;
            this.detailsLabel.Location = new System.Drawing.Point(6, 150);
            this.detailsLabel.Name = "detailsLabel";
            this.detailsLabel.Size = new System.Drawing.Size(40, 13);
            this.detailsLabel.TabIndex = 4;
            this.detailsLabel.Text = "details:";
            // 
            // subtitleTextBox
            // 
            this.subtitleTextBox.Location = new System.Drawing.Point(9, 101);
            this.subtitleTextBox.Multiline = true;
            this.subtitleTextBox.Name = "subtitleTextBox";
            this.subtitleTextBox.ReadOnly = true;
            this.subtitleTextBox.Size = new System.Drawing.Size(381, 46);
            this.subtitleTextBox.TabIndex = 1;
            // 
            // subtitleLabel
            // 
            this.subtitleLabel.AutoSize = true;
            this.subtitleLabel.Location = new System.Drawing.Point(6, 85);
            this.subtitleLabel.Name = "subtitleLabel";
            this.subtitleLabel.Size = new System.Drawing.Size(43, 13);
            this.subtitleLabel.TabIndex = 2;
            this.subtitleLabel.Text = "subtitle:";
            // 
            // titleTextBox
            // 
            this.titleTextBox.Location = new System.Drawing.Point(9, 35);
            this.titleTextBox.Multiline = true;
            this.titleTextBox.Name = "titleTextBox";
            this.titleTextBox.ReadOnly = true;
            this.titleTextBox.Size = new System.Drawing.Size(381, 47);
            this.titleTextBox.TabIndex = 0;
            // 
            // titleLabel
            // 
            this.titleLabel.AutoSize = true;
            this.titleLabel.Location = new System.Drawing.Point(6, 19);
            this.titleLabel.Name = "titleLabel";
            this.titleLabel.Size = new System.Drawing.Size(26, 13);
            this.titleLabel.TabIndex = 0;
            this.titleLabel.Text = "title:";
            // 
            // statusLabel
            // 
            this.statusLabel.AutoSize = true;
            this.statusLabel.Location = new System.Drawing.Point(4, 342);
            this.statusLabel.Name = "statusLabel";
            this.statusLabel.Size = new System.Drawing.Size(40, 13);
            this.statusLabel.TabIndex = 13;
            this.statusLabel.Text = "Status:";
            // 
            // Main
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(797, 362);
            this.Controls.Add(this.statusLabel);
            this.Controls.Add(this.infoGroupBox);
            this.Controls.Add(this.mountGroupBox);
            this.Controls.Add(this.createGroupBox);
            this.Controls.Add(this.connectionGroupBox);
            this.Name = "Main";
            this.Text = "Playstation 4 Save Mounter 1.5 [ps4debug]";
            this.connectionGroupBox.ResumeLayout(false);
            this.connectionGroupBox.PerformLayout();
            this.createGroupBox.ResumeLayout(false);
            this.createGroupBox.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.sizeTrackBar)).EndInit();
            this.mountGroupBox.ResumeLayout(false);
            this.infoGroupBox.ResumeLayout(false);
            this.infoGroupBox.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.TextBox ipTextBox;
        private System.Windows.Forms.Button connectButton;
        private System.Windows.Forms.Button setupButton;
        private System.Windows.Forms.ComboBox userComboBox;
        private System.Windows.Forms.ComboBox dirsComboBox;
        private System.Windows.Forms.Button searchButton;
        private System.Windows.Forms.Button mountButton;
        private System.Windows.Forms.Button unmountButton;
        private System.Windows.Forms.GroupBox connectionGroupBox;
        private System.Windows.Forms.Label ipLabel;
        private System.Windows.Forms.GroupBox createGroupBox;
        private System.Windows.Forms.TextBox nameTextBox;
        private System.Windows.Forms.Button createButton;
        private System.Windows.Forms.GroupBox mountGroupBox;
        private System.Windows.Forms.GroupBox infoGroupBox;
        private System.Windows.Forms.Label nameLabel;
        private System.Windows.Forms.TrackBar sizeTrackBar;
        private System.Windows.Forms.Label sizeLabel;
        private System.Windows.Forms.ToolTip sizeToolTip;
        private System.Windows.Forms.Label statusLabel;
        private System.Windows.Forms.TextBox dateTextBox;
        private System.Windows.Forms.Label dateLabel;
        private System.Windows.Forms.TextBox detailsTextBox;
        private System.Windows.Forms.Label detailsLabel;
        private System.Windows.Forms.TextBox subtitleTextBox;
        private System.Windows.Forms.Label subtitleLabel;
        private System.Windows.Forms.TextBox titleTextBox;
        private System.Windows.Forms.Label titleLabel;
        private System.Windows.Forms.Button payloadButton;
        private System.Windows.Forms.Button getGamesButton;
        private System.Windows.Forms.ComboBox gamesComboBox;
    }
}



================================================
FILE: Main.cs
================================================
using libdebug;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace PS4Saves
{
    public partial class Main : Form
    {
        PS4DBG ps4 = new PS4DBG();
        private int pid;
        private ulong stub;
        private ulong libSceUserServiceBase = 0x0;
        private ulong libSceSaveDataBase = 0x0;
        private ulong executableBase = 0x0;
        private ulong libSceLibcInternalBase = 0x0;
        private ulong GetSaveDirectoriesAddr = 0;
        private ulong GetUsersAddr = 0;
        private int user = 0x0;
        private string selectedGame = null;
        string mp = "";
        bool log = false;
        
        public Main()
        {
            InitializeComponent();
            string[] args = Environment.GetCommandLineArgs();
            if (args.Length == 2 && args[1] == "-log")
            {
                log = true;
            }

            if (File.Exists("ip"))
            {
                ipTextBox.Text = File.ReadAllText("ip");
            }
        }
        public static string FormatSize(double size)
        {
            const long BytesInKilobytes = 1024;
            const long BytesInMegabytes = BytesInKilobytes * 1024;
            const long BytesInGigabytes = BytesInMegabytes * 1024;
            double value;
            string str;
            if (size < BytesInGigabytes)
            {
                value = size / BytesInMegabytes;
                str = "MB";
            }
            else
            {
                value = size /BytesInGigabytes;
                str = "GB";
            }
            return String.Format("{0:0.##} {1}", value, str);
        }
        private void sizeTrackBar_Scroll(object sender, EventArgs e)
        {
            sizeToolTip.SetToolTip(sizeTrackBar, FormatSize((double)(sizeTrackBar.Value * 32768)));
        }
        private void SetStatus(string msg)
        {
            statusLabel.Text = $"Status: {msg}";
        }
        private void WriteLog(string msg)
        {
            if(log)
            {

                msg = $"|{msg}|";
                var a = msg.Length / 2;
                for (var i = 0; i < 48 - a; i++)
                {
                    msg = msg.Insert(0, " ");
                }

                for (var i = msg.Length; i < 96; i++)
                {
                    msg += " ";
                }

                var dateAndTime = DateTime.Now;
                var logStr = $"|{dateAndTime:MM/dd/yyyy} {dateAndTime:hh:mm:ss tt}| |{msg}|";

                if (File.Exists(@"log.txt"))
                {
                    File.AppendAllText(@"log.txt",
                        $"{logStr}{Environment.NewLine}");
                }
                else
                {
                    using (var sw = File.CreateText(@"log.txt"))
                    {
                        sw.WriteLine(logStr);
                    }
                }

                Console.WriteLine(logStr);
            }
        }
        private void connectButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (!checkIP(ipTextBox.Text))
                {
                    SetStatus("Invalid IP");
                    return;
                }
                ps4 = new PS4DBG(ipTextBox.Text);
                ps4.Connect();
                if (!ps4.IsConnected)
                {
                    throw new Exception();
                }
                SetStatus("Connected");
                if (!File.Exists("ip"))
                {
                    File.WriteAllText("ip", ipTextBox.Text);
                }
                else
                {
                    using (var sw = File.CreateText(@"log.txt"))
                    {
                        sw.Write(ipTextBox.Text);
                    }
                }
            }
            catch
            {
                SetStatus("Failed To Connect");
            }
        }

        private void setupButton_Click(object sender, EventArgs e)
        {
            if (!ps4.IsConnected)
            {
                SetStatus("Not connected to ps4");
                return;
            }
            var pl = ps4.GetProcessList();
            var su = pl.FindProcess("SceShellUI");
            if (su == null)
            {
                SetStatus("Couldn't find SceShellUI");
                return;
            }
            pid = su.pid;
            var pm = ps4.GetProcessMaps(pid);
            var tmp = pm.FindEntry("libSceSaveData.sprx")?.start;
            if (tmp == null)
            {
                MessageBox.Show("savedata lib not found", "Error");
                return;
            }
            libSceSaveDataBase = (ulong)tmp;

            tmp = pm.FindEntry("libSceUserService.sprx")?.start;
            if (tmp == null)
            {
                MessageBox.Show("user service lib not found", "Error");
                return;
            }
            libSceUserServiceBase = (ulong)tmp;

            tmp = pm.FindEntry("executable")?.start;
            if (tmp == null)
            {
                MessageBox.Show("executable not found", "Error");
                return;
            }
            executableBase = (ulong)tmp;

            tmp = pm.FindEntry("libSceLibcInternal.sprx")?.start;
            if (tmp == null)
            {
                MessageBox.Show("libc not found", "Error");
                return;
            }
            libSceLibcInternalBase = (ulong)tmp;
            stub = pm.FindEntry("(NoName)clienthandler") == null ? ps4.InstallRPC(pid) : pm.FindEntry("(NoName)clienthandler").start;

            

            var ret = ps4.Call(pid, stub, libSceSaveDataBase + offsets.sceSaveDataInitialize3);
            WriteLog($"sceSaveDataInitialize3 ret = 0x{ret:X}");
            
           
            //PATCHES
            //SAVEDATA LIBRARY PATCHES
            ps4.WriteMemory(pid, libSceSaveDataBase + 0x32998, (byte)0x00); // 'sce_' patch
            ps4.WriteMemory(pid, libSceSaveDataBase + 0x31699, (byte)0x00); // 'sce_sdmemory' patch
            ps4.WriteMemory(pid, libSceSaveDataBase + 0x01119, (byte)0x30); // '_' patch

            var l = ps4.GetProcessList();
            var s = l.FindProcess("SceShellCore");
            var m = ps4.GetProcessMaps(s.pid);
            var ex = m.FindEntry("executable");
            
            //SHELLCORE PATCHES
            ps4.WriteMemory(s.pid, ex.start + 0xD42843, (byte)0x00); // 'sce_sdmemory' patch
            ps4.WriteMemory(s.pid, ex.start + 0x7E4DC0, new byte[]{0x48, 0x31, 0xC0, 0xC3}); //verify keystone patch
            ps4.WriteMemory(s.pid, ex.start + 0x68BA0, new byte[] {0x31, 0xC0, 0xC3}); //transfer mount permission patch eg mount foreign saves with write permission
            ps4.WriteMemory(s.pid, ex.start + 0xC54F0, new byte[] { 0x31, 0xC0, 0xC3 });//patch psn check to load saves saves foreign to current account
            ps4.WriteMemory(s.pid, ex.start + 0x6A349, new byte[] { 0x90, 0x90 }); // ^
            ps4.WriteMemory(s.pid, ex.start + 0x686AE, new byte[] {0x90, 0x90, 0x90, 0x90, 0x90, 0x90}); // something something patches... 
            ps4.WriteMemory(s.pid, ex.start + 0x67FCA, new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); // don't even remember doing this
            ps4.WriteMemory(s.pid, ex.start + 0x67798, new byte[] { 0x90, 0x90}); //nevah jump
            ps4.WriteMemory(s.pid, ex.start + 0x679D5, new byte[] { 0x90, 0xE9 }); //always jump
            //WRITE CUSTOM FUNCTIONS
            GetSaveDirectoriesAddr = ps4.AllocateMemory(pid, 0x8000);
            ps4.WriteMemory(pid, GetSaveDirectoriesAddr, functions.GetSaveDirectories);
            ps4.WriteMemory(pid, GetSaveDirectoriesAddr + 0x12, executableBase + 0x81E800); //opendir
            ps4.WriteMemory(pid, GetSaveDirectoriesAddr + 0x20, executableBase + 0x81E810); //readdir
            ps4.WriteMemory(pid, GetSaveDirectoriesAddr + 0x2E, executableBase + 0x81E7F0);//closedir
            ps4.WriteMemory(pid, GetSaveDirectoriesAddr + 0x3C, libSceLibcInternalBase + 0x8B1A0); //strcpy

            GetUsersAddr = GetSaveDirectoriesAddr + (uint)functions.GetSaveDirectories.Length + 0x20;
            ps4.WriteMemory(pid, GetUsersAddr, functions.GetUsers);
            ps4.WriteMemory(pid, GetUsersAddr + 0x15, libSceUserServiceBase + offsets.sceUserServiceGetLoginUserIdList);
            ps4.WriteMemory(pid, GetUsersAddr + 0x23, libSceUserServiceBase + offsets.sceUserServiceGetUserName);
            ps4.WriteMemory(pid, GetUsersAddr + 0x31, libSceLibcInternalBase + 0x8B1A0); //strcpy


            var users = GetUsers();
            userComboBox.DataSource = users;

            SetStatus("Setup Done :)");
        }

        private void searchButton_Click(object sender, EventArgs e)
        {

            if (!ps4.IsConnected)
            {
                SetStatus("Not connected to ps4");
                return;
            }
            if (pid == 0)
            {
                SetStatus("dont forget to click setup");
                return;
            }
            if (selectedGame == null)
            {
                SetStatus("No game selected");
                return;
            }
            var pm = ps4.GetProcessMaps(pid);
            if (pm.FindEntry("(NoName)clienthandler") == null)
            {
                SetStatus("RPC Stub Not Found");
                return;
            }
            var dirNameAddr = ps4.AllocateMemory(pid, Marshal.SizeOf(typeof(SceSaveDataDirName)) * 1024 + 0x10 + Marshal.SizeOf(typeof(SceSaveDataParam)) * 1024);
            var titleIdAddr = dirNameAddr + (uint) Marshal.SizeOf(typeof(SceSaveDataDirName)) * 1024;
            var paramAddr = titleIdAddr + 0x10;
            SceSaveDataDirNameSearchCond searchCond = new SceSaveDataDirNameSearchCond
            {
                userId = GetUser(),
                titleId = titleIdAddr
            };
            SceSaveDataDirNameSearchResult searchResult = new SceSaveDataDirNameSearchResult
            {
                dirNames = dirNameAddr,
                dirNamesNum = 1024,
                param = paramAddr,
            };
            ps4.WriteMemory(pid, titleIdAddr, selectedGame);
            dirsComboBox.DataSource = Find(searchCond, searchResult);
            ps4.FreeMemory(pid, dirNameAddr, Marshal.SizeOf(typeof(SceSaveDataDirName)) * 1024 + 0x10 + Marshal.SizeOf(typeof(SceSaveDataParam)) * 1024);
            if (dirsComboBox.Items.Count > 0)
            {
                SetStatus($"Found {dirsComboBox.Items.Count} Save Directories :D");
            }
            else
            {
                SetStatus("Found 0 Save Directories :(");
            }
        }

        private void mountButton_Click(object sender, EventArgs e)
        {
            if (!ps4.IsConnected)
            {
                SetStatus("Not connected to ps4");
                return;
            }
            if (dirsComboBox.Items.Count == 0)
            {
                SetStatus("No save selected");
                return;
            }
            if (selectedGame == null)
            {
                SetStatus("No game selected");
                return;
            }
            var dirNameAddr = ps4.AllocateMemory(pid, Marshal.SizeOf(typeof(SceSaveDataDirName)) + 0x10 + 0x41);
            var titleIdAddr = dirNameAddr + (uint)Marshal.SizeOf(typeof(SceSaveDataDirName));
            var fingerprintAddr = titleIdAddr + 0x10;
            ps4.WriteMemory(pid, titleIdAddr, selectedGame);
            ps4.WriteMemory(pid, fingerprintAddr, "0000000000000000000000000000000000000000000000000000000000000000");
            SceSaveDataDirName dirName = new SceSaveDataDirName
            {
                data = dirsComboBox.Text
            };

            SceSaveDataMount mount = new SceSaveDataMount
            {
                userId = GetUser(),
                dirName = dirNameAddr,
                blocks = 32768,
                mountMode = 0x8 | 0x2,
                titleId = titleIdAddr,
                fingerprint = fingerprintAddr

            };
            SceSaveDataMountResult mountResult = new SceSaveDataMountResult
            {

            };
            ps4.WriteMemory(pid, dirNameAddr, dirName);
            mp = Mount(mount, mountResult);

            ps4.FreeMemory(pid, dirNameAddr, Marshal.SizeOf(typeof(SceSaveDataDirName)) + 0x10 + 0x41);
            if (mp != "")
            {
                SetStatus($"Save Mounted in {mp}");
            }
            else
            {
                SetStatus("Mounting Failed");
            }
        }

        private void unmountButton_Click(object sender, EventArgs e)
        {
            if (!ps4.IsConnected)
            {
                SetStatus("Not connected to ps4");
                return;
            }
            if (mp == "")
            {
                SetStatus("No save mounted");
                return;
            }
            SceSaveDataMountPoint mountPoint = new SceSaveDataMountPoint
            {
                data = mp,
            };

            Unmount(mountPoint);
            mp = null;
            SetStatus("Save Unmounted");
        }

        private void createButton_Click(object sender, EventArgs e)
        {
            if (!ps4.IsConnected)
            {
                SetStatus("Not connected to ps4");
                return;
            }
            if (pid == 0)
            {
                SetStatus("Don't forget to setup");
                return;
            }
            if (nameTextBox.Text == "")
            {
                SetStatus("No Save Name");
                return;
            }
            if (selectedGame == null)
            {
                SetStatus("No game selected");
                return;
            }
            var pm = ps4.GetProcessMaps(pid);
            if (pm.FindEntry("(NoName)clienthandler") == null)
            {
                SetStatus("RPC Stub Not Found");
                return;
            }

            var dirNameAddr = ps4.AllocateMemory(pid, Marshal.SizeOf(typeof(SceSaveDataDirName)) + 0x10 + 0x41);
            var titleIdAddr = dirNameAddr + (uint)Marshal.SizeOf(typeof(SceSaveDataDirName));
            var fingerprintAddr = titleIdAddr + 0x10;
            ps4.WriteMemory(pid, fingerprintAddr, "0000000000000000000000000000000000000000000000000000000000000000");
            ps4.WriteMemory(pid, titleIdAddr, selectedGame);
            SceSaveDataDirName dirName = new SceSaveDataDirName
            {
                data = nameTextBox.Text
            };

            SceSaveDataMount mount = new SceSaveDataMount
            {
                userId = GetUser(),
                dirName = dirNameAddr,
                blocks = (ulong) sizeTrackBar.Value,
                mountMode = 4 | 2 | 8,
                titleId = titleIdAddr,
                fingerprint = fingerprintAddr

            };
            SceSaveDataMountResult mountResult = new SceSaveDataMountResult
            {

            };
            ps4.WriteMemory(pid, dirNameAddr, dirName);
            var mp = Mount(mount, mountResult);
            ps4.FreeMemory(pid, dirNameAddr, Marshal.SizeOf(typeof(SceSaveDataDirName)) + 0x10 + 0x41);
            if (mp != "")
            {
                SetStatus("Save Created");
                SceSaveDataMountPoint mountPoint = new SceSaveDataMountPoint
                {
                    data = mp,
                };
                Unmount(mountPoint);
            }
            else
            {
                SetStatus("Save Creation Failed");
            }
        }

        private int GetUser()
        {
            if(user != 0)
            {
                return user;
            }
            return InitialUser();          
        }

        private int InitialUser()
        {
            var bufferAddr = ps4.AllocateMemory(pid, sizeof(int));

            ps4.Call(pid, stub, libSceUserServiceBase + offsets.sceUserServiceGetInitialUser, bufferAddr);

            var id = ps4.ReadMemory<int>(pid, bufferAddr);

            ps4.FreeMemory(pid, bufferAddr, sizeof(int));

            return id;
        }

        private SearchEntry[] Find(SceSaveDataDirNameSearchCond searchCond, SceSaveDataDirNameSearchResult searchResult)
        {
            var searchCondAddr = ps4.AllocateMemory(pid, Marshal.SizeOf(typeof(SceSaveDataDirNameSearchCond)) + Marshal.SizeOf(typeof(SceSaveDataDirNameSearchResult)));
            var searchResultAddr = searchCondAddr + (uint)Marshal.SizeOf(typeof(SceSaveDataDirNameSearchCond));

            ps4.WriteMemory(pid, searchCondAddr, searchCond);
            ps4.WriteMemory(pid, searchResultAddr, searchResult);
            var ret = ps4.Call(pid, stub, libSceSaveDataBase + offsets.sceSaveDataDirNameSearch, searchCondAddr, searchResultAddr);
            WriteLog($"sceSaveDataDirNameSearch ret = 0x{ret:X}");
            if ( ret == 0)
            {
                searchResult = ps4.ReadMemory<SceSaveDataDirNameSearchResult>(pid, searchResultAddr);
                SearchEntry[] sEntries = new SearchEntry[searchResult.hitNum];
                var paramMemory = ps4.ReadMemory(pid, searchResult.param, (int)searchResult.hitNum * Marshal.SizeOf(typeof(SceSaveDataParam)));
                var dirNamesMemory = ps4.ReadMemory(pid, searchResult.dirNames, (int)searchResult.hitNum * 32);
                for (int i = 0; i < searchResult.hitNum; i++)
                {
                    SceSaveDataParam tmp = (SceSaveDataParam)PS4DBG.GetObjectFromBytes(PS4DBG.SubArray(paramMemory, i * Marshal.SizeOf(typeof(SceSaveDataParam)), Marshal.SizeOf(typeof(SceSaveDataParam))), typeof(SceSaveDataParam));
                    sEntries[i] = new SearchEntry
                    {
                        dirName = System.Text.Encoding.UTF8.GetString(PS4DBG.SubArray(dirNamesMemory, i * 32, 32)),
                        title = System.Text.Encoding.UTF8.GetString(tmp.title),
                        subtitle = System.Text.Encoding.UTF8.GetString(tmp.subTitle),
                        detail = System.Text.Encoding.UTF8.GetString(tmp.detail),
                        time = new DateTime(1970, 1, 1).ToLocalTime().AddSeconds(tmp.mtime).ToString(),
                    };
                }
                ps4.FreeMemory(pid, searchCondAddr, Marshal.SizeOf(typeof(SceSaveDataDirNameSearchCond)) + Marshal.SizeOf(typeof(SceSaveDataDirNameSearchResult)));
                return sEntries;
            }

            ps4.FreeMemory(pid, searchCondAddr, Marshal.SizeOf(typeof(SceSaveDataDirNameSearchCond)) + Marshal.SizeOf(typeof(SceSaveDataDirNameSearchResult)));

            return new SearchEntry[0];

        }

        private void Unmount(SceSaveDataMountPoint mountPoint)
        {
            var mountPointAddr = ps4.AllocateMemory(pid, Marshal.SizeOf(typeof(SceSaveDataMountPoint)));

            ps4.WriteMemory(pid, mountPointAddr, mountPoint);
            var ret = ps4.Call(pid, stub, libSceSaveDataBase + offsets.sceSaveDataUmount, mountPointAddr);
            WriteLog($"sceSaveDataUmount ret = 0x{ret:X}");
            ps4.FreeMemory(pid, mountPointAddr, Marshal.SizeOf(typeof(SceSaveDataMountPoint)));
            mp = null;
        }

        private string Mount(SceSaveDataMount mount, SceSaveDataMountResult mountResult)
        {
            var mountAddr = ps4.AllocateMemory(pid, Marshal.SizeOf(typeof(SceSaveDataMount)) + Marshal.SizeOf(typeof(SceSaveDataMountResult)));
            var mountResultAddr = mountAddr + (uint)Marshal.SizeOf(typeof(SceSaveDataMount));
            ps4.WriteMemory(pid, mountAddr, mount);
            ps4.WriteMemory(pid, mountResultAddr, mountResult);

            var ret = ps4.Call(pid, stub, libSceSaveDataBase + offsets.sceSaveDataMount, mountAddr, mountResultAddr);
            WriteLog($"sceSaveDataMount ret = 0x{ret:X}");
            if (ret == 0)
            {
                mountResult = ps4.ReadMemory<SceSaveDataMountResult>(pid, mountResultAddr);

                ps4.FreeMemory(pid, mountAddr, Marshal.SizeOf(typeof(SceSaveDataMount)) + Marshal.SizeOf(typeof(SceSaveDataMountResult)));

                return mountResult.mountPoint.data;
            }

            ps4.FreeMemory(pid, mountAddr, Marshal.SizeOf(typeof(SceSaveDataMount)) + Marshal.SizeOf(typeof(SceSaveDataMountResult)));

            return "";
        }

        class SearchEntry
        {
            public string dirName;
            public string title;
            public string subtitle;
            public string detail;
            public string time;
            public override string ToString()
            {
                return dirName;
            }
        }

        private void dirsComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            titleTextBox.Text = ((SearchEntry)dirsComboBox.SelectedItem).title;
            subtitleTextBox.Text = ((SearchEntry)dirsComboBox.SelectedItem).subtitle;
            detailsTextBox.Text = ((SearchEntry)dirsComboBox.SelectedItem).detail;
            dateTextBox.Text = ((SearchEntry)dirsComboBox.SelectedItem).time;
        }
        
        private void userComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            user = ((User)userComboBox.SelectedItem).id;
        }

        class User
        {
            public int id;
            public string name;

            public override string ToString()
            {
                return name;
            }
        }
        private string[] GetSaveDirectories()
        {
            var dirs = new List<string>();
            var mem = ps4.AllocateMemory(pid, 0x8000);
            var path = mem;
            var buffer = mem + 0x101;

            ps4.WriteMemory(pid, path, $"/user/home/{GetUser():x}/savedata/");
            var ret = (int)ps4.Call(pid, stub, GetSaveDirectoriesAddr, path, buffer);
            if (ret != -1 && ret != 0)
            {
                var bDirs = ps4.ReadMemory(pid, buffer, ret * 0x10);
                for (var i = 0; i < ret; i++)
                {
                    var sDir = System.Text.Encoding.UTF8.GetString(PS4DBG.SubArray(bDirs, i * 10, 9));
                    dirs.Add(sDir);
                }
            }
            ps4.FreeMemory(pid, mem, 0x8000);
            return dirs.ToArray();
        }

        private User[] GetUsers()
        {
            List<User> users = new List<User>();
            var mem = ps4.AllocateMemory(pid, 0x1);
            var ret = (int)ps4.Call(pid, stub, GetUsersAddr, mem);
            
            if (ret != -1 && ret != 0)
            {
                var buffer = ps4.ReadMemory(pid, mem, (21) * 4);
                for (int i = 0; i < 4; i++)
                {
                    var id = BitConverter.ToInt32(buffer, 21 * i);
                    if (id == 0)
                    {
                        continue;
                    }
                    var name = System.Text.Encoding.UTF8.GetString(PS4DBG.SubArray(buffer, i * 21 + 4, 16));
                    users.Add(new User { id = id, name = name });
                }
            }
            ps4.FreeMemory(pid, mem, 0x1);
            return users.ToArray();

        }
        public static bool checkIP(string IP)
        {
            return !string.IsNullOrEmpty(IP) && IPAddress.TryParse(IP, out _);
        }
        private void payloadButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (!checkIP(ipTextBox.Text))
                {
                    SetStatus("Invalid IP");
                    return;
                }

                var assembly = System.Reflection.Assembly.GetExecutingAssembly();
                using (var stream = assembly.GetManifestResourceStream("PS4Saves.ps4debug.bin"))
                {
                    var buffer = new byte[stream.Length];
                    stream.Read(buffer, 0, buffer.Length);
                    var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    IAsyncResult result = socket.BeginConnect(new IPEndPoint(IPAddress.Parse(ipTextBox.Text), 9020), null, null);
                    var connected = result.AsyncWaitHandle.WaitOne(3000);
                    if (connected)
                    {
                        socket.Send(buffer, buffer.Length, SocketFlags.None);
                    }

                    SetStatus(connected ? "Payload sent" : "Failed to connect");
                    socket.Close();
                }
            }
            catch
            {
                SetStatus("Sending payload failed");
            }
        }

        private void getGamesButton_Click(object sender, EventArgs e)
        {
            if (!ps4.IsConnected)
            {
                SetStatus("Not connected to ps4");
                return;
            }
            if (pid == 0)
            {
                SetStatus("Don't forget to press setup");
                return;
            }
            var pm = ps4.GetProcessMaps(pid);
            if (pm.FindEntry("(NoName)clienthandler") == null)
            {
                SetStatus("RPC Stub Not Found");
                return;
            }
            var dirs = GetSaveDirectories();
            gamesComboBox.DataSource = dirs;
        }

        private void gamesComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            selectedGame = (string)gamesComboBox.SelectedItem;
        }
    }
}


================================================
FILE: PS4Saves.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{8F8D661C-CCD4-4360-962D-60207A3828BF}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <RootNamespace>PS4Saves</RootNamespace>
    <AssemblyName>Playstation 4 Save Mounter</AssemblyName>
    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <LangVersion>7.1</LangVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>none</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <LangVersion>7.1</LangVersion>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Deployment" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="functions.cs" />
    <Compile Include="Main.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="Main.Designer.cs">
      <DependentUpon>Main.cs</DependentUpon>
    </Compile>
    <Compile Include="libdebug\Process.cs" />
    <Compile Include="libdebug\PS4DBG.Console.cs" />
    <Compile Include="libdebug\PS4DBG.cs" />
    <Compile Include="libdebug\PS4DBG.Debug.cs" />
    <Compile Include="libdebug\PS4DBG.Kernel.cs" />
    <Compile Include="libdebug\PS4DBG.Proc.cs" />
    <Compile Include="libdebug\Registers.cs" />
    <Compile Include="offsets.cs" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="structs.cs" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="ps4debug.bin" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

================================================
FILE: Program.cs
================================================
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace PS4Saves
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Main());
        }
    }
}


================================================
FILE: Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Playstation 4 Save Mounter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PS4Saves")]
[assembly: AssemblyCopyright("Copyright ©  2018 Aida & ChendoChap")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components.  If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("8f8d661c-ccd4-4360-962d-60207a3828bf")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.5.0.0")]
[assembly: AssemblyFileVersion("1.5.0.0")]


================================================
FILE: README.md
================================================
# Playstation 4 Save Mounter 1.5

## Summary
This program allows you to mount save data with RW permission and a lot more shit, just read this damn thing
### You can
* Make decrypted copies of any save (as long as it's encrypted with keys <= 5.05)
* Replace saves with modified ones
* Replace save files with someone else's save files (share saves)
* Create new saves
* Export saves to 5.05+ consoles

### You can't
* Replace save files with an encrypted save (if it's encrypted with keys > 5.05)
* Use this on unexploited consoles

### You need
* To make sure you're using a recent ps4debug version, bin of the latest ps4debug (as of 11/14) is included in the download
* To be able to run .net framework 2.0 executables (even windows 98 can run this)
## Prerequisites
* PS4 5.05
* FTP Client (eg filezilla, ...)
## Instructions

### Mounting saves
1) Load [ps4debug](https://github.com/xemio/ps4debug)
2) Load [FTP](https://github.com/xvortex/ps4-ftp-vtx)
3) Open the tool
4) Enter the ip of your ps4 and click 'Connect'
5) Click 'Setup' & select the user you want to use in the combobox
6) Click 'Get Games' & select the game you want to use in the combobox
7) Click 'Search' & select the save you want to mount
8) Click 'Mount'
9) Your save is now mounted and accessible from ftp in /mnt/pfs/ & in /mnt/sandbox/NPXS20001_000/savedataX (it's the same just a different dir)
10) After you're done copying/replacing files click 'Unmount'
### Creating saves
1) Load [ps4debug](https://github.com/xemio/ps4debug)
2) Load [FTP](https://github.com/xvortex/ps4-ftp-vtx)
3) Open the tool
4) Enter the ip of your ps4 and click 'Connect'
5) Click 'Setup' & select the user you want to use in the combobox
6) Click 'Get Games' & select the game you want to use in the combobox
7) Enter the desired save directory name in the textbox
8) Use the slider to choose the save's size
9) Click 'Create Save'
10) Click 'Search' to refresh the save list
### Exporting Saves to 5.05+ consoles
1)  mount the save you want to export.
2)  get the param.sfo file from the sce_sys directory
3)  open it in a hex editor or a ps4 compatible sfo editor
4)  change the psn id to the target's psn id (8 bytes, you get that by copying a save using settings, you'll need to change it to little endian) it's at 0x15C for hex editing... see video for sfo editor
5)  save the param.sfo & replace the one in the mounted dir
6)  unmount the save and copy the 2 save files sdimg & the .bin to your usb /PS4/SAVEDATA/{psn id}/{titleid}/
7)  remove the sdimg_ prefix from the filename
8)  now you should be able to copy the save to the account linked to the psn id (5.05+ console) using system settings
## Important

**- you don't need to start a game to modify its saves, it's actually better not to have one open because some games like gow 4 may overwrite parts of a save while you're busy modifying it resulting in a corrupted save.**

**- don't replace files in sce_sys directory, it is unnecessary and will probably corrupt your save**  

**- the workaround method is obsolete since update 1.4**  

**- some games require you to create your own save data with the appropriate name & size, fallout 4 is such a game. This problem was discussed in [issue #5](https://github.com/ChendoChap/Playstation-4-Save-Mounter/issues/5)**

**- Don't forget to regularly make backups of your saves and the savedata database, the ps4 deletes all your saves if the database gets corrupted while this mostly only happens when you actively mess with it, it's always better to be prepared**

**- It's possible to mount someone else's encrypted saves but there's currently no 'clean' way to do it. you need to temporarily replace the sdimg_xxx and the xxx.bin files with the ones you downloaded in your user's savedata directory. Be sure to restore the original files after you extracted the save because the ps4 could throw a fit if you reboot while those files are still there. (I'll make this process easier later on)**

## Resources
### Do note that not all of these were made using the latest save mounter version so slight differences are to be expected.

### Videos
  * exporting saves to 5.05+ consoles (latest version 1.5): [how to resign PS4 saves for different PS4 and profile, fw 5 05 and higher by 'Old Gamer'](https://www.youtube.com/watch?v=OpZ9C-MciZM)

  * mounting saves, transferring saves to other (regions/title ids) (old version): [PS4 Save Mounter Tutorial (Swap Saves Between Consoles & Games) by 'MODDED WARFARE'](https://www.youtube.com/watch?v=m_h4MsAaXdY)

  * mounting saves, using other people's decrypted saves (old version): [Playstation 4 Save Mounter Demonstration by 'Sc0rpion'](https://www.youtube.com/watch?v=Atw6480SX5I)


================================================
FILE: functions.cs
================================================
namespace PS4Saves
{
    internal static class functions
    {
        internal static byte[] GetSaveDirectories =
        {
            0x55, 0x48, 0x89, 0xE5, 0x48, 0x83, 0xEC, 0x50, 0x48, 0x89, 0x7D, 0xB8, 0x48, 0x89, 0x75, 0xB0, 0x48,
            0xB8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x48, 0x89, 0x45, 0xE8, 0x48, 0xB8, 0xBB, 0xBB,
            0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x48, 0x89, 0x45, 0xE0, 0x48, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
            0xCC, 0xCC, 0xCC, 0x48, 0x89, 0x45, 0xD8, 0x48, 0xB8, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
            0x48, 0x89, 0x45, 0xD0, 0x48, 0x8B, 0x55, 0xB8, 0x48, 0x8B, 0x45, 0xE8, 0x48, 0x89, 0xD7, 0xFF, 0xD0,
            0x48, 0x89, 0x45, 0xC8, 0x48, 0x83, 0x7D, 0xC8, 0x00, 0x75, 0x0A, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9,
            0x88, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x55, 0xC8, 0x48, 0x8B, 0x45, 0xE0, 0x48, 0x89, 0xD7, 0xFF, 0xD0,
            0x48, 0x89, 0x45, 0xF8, 0xC7, 0x45, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0x7D, 0xF8, 0x00, 0x74,
            0x59, 0x48, 0x8B, 0x45, 0xF8, 0x0F, 0xB6, 0x40, 0x06, 0x3C, 0x04, 0x75, 0x3A, 0x48, 0x8B, 0x45, 0xF8,
            0x0F, 0xB6, 0x40, 0x07, 0x3C, 0x09, 0x75, 0x2E, 0x48, 0x8B, 0x45, 0xF8, 0x48, 0x8D, 0x48, 0x08, 0x8B,
            0x55, 0xF4, 0x89, 0xD0, 0xC1, 0xE0, 0x02, 0x01, 0xD0, 0x01, 0xC0, 0x48, 0x63, 0xD0, 0x48, 0x8B, 0x45,
            0xB0, 0x48, 0x01, 0xC2, 0x48, 0x8B, 0x45, 0xD0, 0x48, 0x89, 0xCE, 0x48, 0x89, 0xD7, 0xFF, 0xD0, 0x83,
            0x45, 0xF4, 0x01, 0x48, 0x8B, 0x55, 0xC8, 0x48, 0x8B, 0x45, 0xE0, 0x48, 0x89, 0xD7, 0xFF, 0xD0, 0x48,
            0x89, 0x45, 0xF8, 0xEB, 0xA0, 0x48, 0x8B, 0x55, 0xC8, 0x48, 0x8B, 0x45, 0xD8, 0x48, 0x89, 0xD7, 0xFF,
            0xD0, 0x8B, 0x45, 0xF4, 0xC9, 0xC3
        };

        internal static byte[] GetUsers =
        {
            0x55, 0x48, 0x89, 0xE5, 0x48, 0x83, 0xEC, 0x70, 0x48, 0x89, 0x7D, 0x98, 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00,
            0x00, 0x48, 0xB8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x48, 0x89, 0x45, 0xF0, 0x48, 0xB8, 0xBB,
            0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x48, 0x89, 0x45, 0xE8, 0x48, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
            0xCC, 0xCC, 0xCC, 0x48, 0x89, 0x45, 0xE0, 0x48, 0x8D, 0x55, 0xC0, 0x48, 0x8B, 0x45, 0xF0, 0x48, 0x89, 0xD7,
            0xFF, 0xD0, 0x89, 0x45, 0xDC, 0x83, 0x7D, 0xDC, 0x00, 0x74, 0x0A, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xB4,
            0x00, 0x00, 0x00, 0xC7, 0x45, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x83, 0x7D, 0xF8, 0x03, 0x0F, 0x8F, 0xA0, 0x00,
            0x00, 0x00, 0x8B, 0x45, 0xF8, 0x48, 0x98, 0x8B, 0x44, 0x85, 0xC0, 0x85, 0xC0, 0x0F, 0x8E, 0x86, 0x00, 0x00,
            0x00, 0x8B, 0x45, 0xF8, 0x48, 0x98, 0x8B, 0x4C, 0x85, 0xC0, 0x48, 0x8D, 0x75, 0xA0, 0x48, 0x8B, 0x45, 0xE8,
            0xBA, 0x11, 0x00, 0x00, 0x00, 0x89, 0xCF, 0xFF, 0xD0, 0x89, 0x45, 0xDC, 0x83, 0x7D, 0xDC, 0x00, 0x74, 0x07,
            0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x68, 0x8B, 0x55, 0xF8, 0x89, 0xD0, 0xC1, 0xE0, 0x02, 0x01, 0xD0, 0xC1,
            0xE0, 0x02, 0x01, 0xD0, 0x48, 0x98, 0x48, 0x8D, 0x14, 0x85, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x45, 0x98,
            0x48, 0x01, 0xC2, 0x8B, 0x45, 0xF8, 0x48, 0x98, 0x8B, 0x44, 0x85, 0xC0, 0x89, 0x02, 0x8B, 0x55, 0xF8, 0x89,
            0xD0, 0xC1, 0xE0, 0x02, 0x01, 0xD0, 0xC1, 0xE0, 0x02, 0x01, 0xD0, 0x48, 0x98, 0x48, 0x8D, 0x50, 0x04, 0x48,
            0x8B, 0x45, 0x98, 0x48, 0x8D, 0x0C, 0x02, 0x48, 0x8D, 0x55, 0xA0, 0x48, 0x8B, 0x45, 0xE0, 0x48, 0x89, 0xD6,
            0x48, 0x89, 0xCF, 0xFF, 0xD0, 0x83, 0x45, 0xFC, 0x01, 0x83, 0x45, 0xF8, 0x01, 0xE9, 0x56, 0xFF, 0xFF, 0xFF,
            0x8B, 0x45, 0xFC, 0xC9, 0xC3
        };
    }
}


================================================
FILE: libdebug/PS4DBG.Console.cs
================================================
using System.Text;

namespace libdebug
{
    public partial class PS4DBG
    {   
        //console
        // packet sizes
        // send size
        private const int CMD_CONSOLE_PRINT_PACKET_SIZE = 4;
        private const int CMD_CONSOLE_NOTIFY_PACKET_SIZE = 8;


        // console
        // note: the disconnect command actually uses the console api to end the connection
        /// <summary>
        /// Reboot console
        /// </summary>
        public void Reboot()
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_CONSOLE_REBOOT, 0);
            IsConnected = false;
        }

        /// <summary>
        /// Print to serial port
        /// </summary>
        public void Print(string str)
        {
            CheckConnected();

            string raw = str + "\0";

            SendCMDPacket(CMDS.CMD_CONSOLE_PRINT, CMD_CONSOLE_PRINT_PACKET_SIZE, raw.Length);
            SendData(Encoding.ASCII.GetBytes(raw), raw.Length);
            CheckStatus();
        }

        /// <summary>
        /// Notify console
        /// </summary>
        public void Notify(int messageType, string message)
        {
            CheckConnected();

            string raw = message + "\0";

            SendCMDPacket(CMDS.CMD_CONSOLE_NOTIFY, CMD_CONSOLE_NOTIFY_PACKET_SIZE, messageType, raw.Length);
            SendData(Encoding.ASCII.GetBytes(raw), raw.Length);
            CheckStatus();
        }

        /// <summary>
        /// Console information
        /// </summary>
        public void GetConsoleInformation()
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_CONSOLE_INFO, 0);
            CheckStatus();

            // TODO return the data
        }
    }
}

================================================
FILE: libdebug/PS4DBG.Debug.cs
================================================
using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;

namespace libdebug
{
    public partial class PS4DBG
    {
        //debug
        // packet sizes
        //send size
        private const int CMD_DEBUG_ATTACH_PACKET_SIZE = 4;
        private const int CMD_DEBUG_BREAKPT_PACKET_SIZE = 16;
        private const int CMD_DEBUG_WATCHPT_PACKET_SIZE = 24;
        private const int CMD_DEBUG_STOPTHR_PACKET_SIZE = 4;
        private const int CMD_DEBUG_RESUMETHR_PACKET_SIZE = 4;
        private const int CMD_DEBUG_GETREGS_PACKET_SIZE = 4;
        private const int CMD_DEBUG_SETREGS_PACKET_SIZE = 8;
        private const int CMD_DEBUG_STOPGO_PACKET_SIZE = 4;
        private const int CMD_DEBUG_THRINFO_PACKET_SIZE = 4;
        //receive size
        private const int DEBUG_INTERRUPT_SIZE = 0x4A0;
        private const int DEBUG_THRINFO_SIZE = 40;
        private const int DEBUG_REGS_SIZE = 0xB0;
        private const int DEBUG_FPREGS_SIZE = 0x340;
        private const int DEBUG_DBGREGS_SIZE = 0x80;

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct DebuggerInterruptPacket
        {
            public uint lwpid;
            public uint status;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
            public string tdname;
            public regs reg64;
            public fpregs savefpu;
            public dbregs dbreg64;
        }
        /// <summary>
        /// Debugger interrupt callback
        /// </summary>
        /// <param name="lwpid">Thread identifier</param>
        /// <param name="status">status</param>
        /// <param name="tdname">Thread name</param>
        /// <param name="regs">Registers</param>
        /// <param name="fpregs">Floating point registers</param>
        /// <param name="dbregs">Debug registers</param>
        public delegate void DebuggerInterruptCallback(uint lwpid, uint status, string tdname, regs regs, fpregs fpregs, dbregs dbregs);
        private void DebuggerThread(object obj)
        {
            DebuggerInterruptCallback callback = (DebuggerInterruptCallback)obj;

            IPAddress ip = IPAddress.Parse("0.0.0.0");
            IPEndPoint endpoint = new IPEndPoint(ip, PS4DBG_DEBUG_PORT);

            Socket server = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            server.Bind(endpoint);
            server.Listen(0);

            IsDebugging = true;

            Socket cl = server.Accept();

            cl.NoDelay = true;
            cl.Blocking = false;

            while (IsDebugging)
            {
                if (cl.Available == DEBUG_INTERRUPT_SIZE)
                {
                    byte[] data = new byte[DEBUG_INTERRUPT_SIZE];
                    int bytes = cl.Receive(data, DEBUG_INTERRUPT_SIZE, SocketFlags.None);
                    if (bytes == DEBUG_INTERRUPT_SIZE)
                    {
                        DebuggerInterruptPacket packet = (DebuggerInterruptPacket)GetObjectFromBytes(data, typeof(DebuggerInterruptPacket));
                        callback(packet.lwpid, packet.status, packet.tdname, packet.reg64, packet.savefpu, packet.dbreg64);
                    }
                }

                Thread.Sleep(100);
            }

            server.Close();
        }
        /// <summary>
        /// Attach the debugger
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <param name="callback">DebuggerInterruptCallback implementation</param>
        /// <returns></returns>
        public void AttachDebugger(int pid, DebuggerInterruptCallback callback)
        {
            CheckConnected();

            if (IsDebugging || debugThread != null)
            {
                throw new Exception("libdbg: debugger already running?");
            }

            IsDebugging = false;

            debugThread = new Thread(DebuggerThread);
            debugThread.Start(callback);

            // wait until server is started
            while (!IsDebugging)
            {
                Thread.Sleep(100);
            }

            SendCMDPacket(CMDS.CMD_DEBUG_ATTACH, CMD_DEBUG_ATTACH_PACKET_SIZE, pid);
            CheckStatus();
        }

        /// <summary>
        /// Detach the debugger
        /// </summary>
        /// <returns></returns>
        public void DetachDebugger()
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_DEBUG_DETACH, 0);
            CheckStatus();

            if (IsDebugging && debugThread != null)
            {
                IsDebugging = false;

                debugThread.Join();
                debugThread = null;
            }
        }

        /// <summary>
        /// Stop the current process
        /// </summary>
        /// <returns></returns>
        public void ProcessStop()
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_STOPGO, CMD_DEBUG_STOPGO_PACKET_SIZE, 1);
            CheckStatus();
        }

        /// <summary>
        /// Kill the current process, it will detach before doing so
        /// </summary>
        /// <returns></returns>
        public void ProcessKill()
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_STOPGO, CMD_DEBUG_STOPGO_PACKET_SIZE, 2);
            CheckStatus();
        }

        /// <summary>
        /// Resume the current process
        /// </summary>
        /// <returns></returns>
        public void ProcessResume()
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_STOPGO, CMD_DEBUG_STOPGO_PACKET_SIZE, 0);
            CheckStatus();
        }

        /// <summary>
        /// Change breakpoint, to remove said breakpoint send the same index but disable it (address is ignored)
        /// </summary>
        /// <param name="index">Index</param>
        /// <param name="enabled">Enabled</param>
        /// <param name="address">Address</param>
        /// <returns></returns>
        public void ChangeBreakpoint(int index, bool enabled, ulong address)
        {
            CheckConnected();
            CheckDebugging();

            if (index >= MAX_BREAKPOINTS)
            {
                throw new Exception("libdbg: breakpoint index out of range");
            }

            SendCMDPacket(CMDS.CMD_DEBUG_BREAKPT, CMD_DEBUG_BREAKPT_PACKET_SIZE, index, Convert.ToInt32(enabled), address);
            CheckStatus();
        }

        /// <summary>
        /// Change watchpoint
        /// </summary>
        /// <param name="index">Index</param>
        /// <param name="enabled">Enabled</param>
        /// <param name="length">Length</param>
        /// <param name="breaktype">Break type</param>
        /// <param name="address">Address</param>
        /// <returns></returns>
        public void ChangeWatchpoint(int index, bool enabled, WATCHPT_LENGTH length, WATCHPT_BREAKTYPE breaktype, ulong address)
        {
            CheckConnected();
            CheckDebugging();

            if (index >= MAX_WATCHPOINTS)
            {
                throw new Exception("libdbg: watchpoint index out of range");
            }

            SendCMDPacket(CMDS.CMD_DEBUG_WATCHPT, CMD_DEBUG_WATCHPT_PACKET_SIZE, index, Convert.ToInt32(enabled), (uint)length, (uint)breaktype, address);
            CheckStatus();
        }

        /// <summary>
        /// Get a list of threads from the current process
        /// </summary>
        /// <returns></returns>
        public uint[] GetThreadList()
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_THREADS, 0);
            CheckStatus();

            byte[] data = new byte[sizeof(int)];
            sock.Receive(data, sizeof(int), SocketFlags.None);
            int number = BitConverter.ToInt32(data, 0);

            byte[] threads = ReceiveData(number * sizeof(uint));
            uint[] thrlist = new uint[number];
            for (int i = 0; i < number; i++)
            {
                thrlist[i] = BitConverter.ToUInt32(threads, i * sizeof(uint));
            }

            return thrlist;
        }

        /// <summary>
        /// Get thread information
        /// </summary>
        /// <returns></returns>
        /// <param name="lwpid">Thread identifier</param>
        public ThreadInfo GetThreadInfo(uint lwpid)
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_THRINFO, CMD_DEBUG_THRINFO_PACKET_SIZE, lwpid);
            CheckStatus();

            return (ThreadInfo)GetObjectFromBytes(ReceiveData(DEBUG_THRINFO_SIZE), typeof(ThreadInfo));
        }

        /// <summary>
        /// Stop a thread from running
        /// </summary>
        /// <param name="lwpid">Thread id</param>
        /// <returns></returns>
        public void StopThread(uint lwpid)
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_STOPTHR, CMD_DEBUG_STOPTHR_PACKET_SIZE, lwpid);
            CheckStatus();
        }

        /// <summary>
        /// Resume a thread from being stopped
        /// </summary>
        /// <param name="lwpid">Thread id</param>
        /// <returns></returns>
        public void ResumeThread(uint lwpid)
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_RESUMETHR, CMD_DEBUG_RESUMETHR_PACKET_SIZE, lwpid);
            CheckStatus();
        }

        /// <summary>
        /// Get registers from thread
        /// </summary>
        /// <param name="lwpid">Thread id</param>
        /// <returns></returns>
        public regs GetRegisters(uint lwpid)
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_GETREGS, CMD_DEBUG_GETREGS_PACKET_SIZE, lwpid);
            CheckStatus();

            return (regs)GetObjectFromBytes(ReceiveData(DEBUG_REGS_SIZE), typeof(regs));
        }

        /// <summary>
        /// Set thread registers
        /// </summary>
        /// <param name="lwpid">Thread id</param>
        /// <param name="regs">Register data</param>
        /// <returns></returns>
        public void SetRegisters(uint lwpid, regs regs)
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_SETREGS, CMD_DEBUG_SETREGS_PACKET_SIZE, lwpid, DEBUG_REGS_SIZE);
            CheckStatus();
            SendData(GetBytesFromObject(regs), DEBUG_REGS_SIZE);
            CheckStatus();
        }

        /// <summary>
        /// Get floating point registers from thread
        /// </summary>
        /// <param name="lwpid">Thread id</param>
        /// <returns></returns>
        public fpregs GetFloatRegisters(uint lwpid)
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_GETFPREGS, CMD_DEBUG_GETREGS_PACKET_SIZE, lwpid);
            CheckStatus();

            return (fpregs)GetObjectFromBytes(ReceiveData(DEBUG_FPREGS_SIZE), typeof(fpregs));
        }

        /// <summary>
        /// Set floating point thread registers
        /// </summary>
        /// <param name="lwpid">Thread id</param>
        /// <param name="fpregs">Floating point register data</param>
        /// <returns></returns>
        public void SetFloatRegisters(uint lwpid, fpregs fpregs)
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_SETFPREGS, CMD_DEBUG_SETREGS_PACKET_SIZE, lwpid, DEBUG_FPREGS_SIZE);
            CheckStatus();
            SendData(GetBytesFromObject(fpregs), DEBUG_FPREGS_SIZE);
            CheckStatus();
        }

        /// <summary>
        /// Get debug registers from thread
        /// </summary>
        /// <param name="lwpid">Thread id</param>
        /// <returns></returns>
        public dbregs GetDebugRegisters(uint lwpid)
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_GETDBGREGS, CMD_DEBUG_GETREGS_PACKET_SIZE, lwpid);
            CheckStatus();

            return (dbregs)GetObjectFromBytes(ReceiveData(DEBUG_DBGREGS_SIZE), typeof(dbregs));
        }

        /// <summary>
        /// Set debug thread registers
        /// </summary>
        /// <param name="lwpid">Thread id</param>
        /// <param name="dbregs">debug register data</param>
        /// <returns></returns>
        public void SetDebugRegisters(uint lwpid, dbregs dbregs)
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_SETDBGREGS, CMD_DEBUG_SETREGS_PACKET_SIZE, lwpid, DEBUG_DBGREGS_SIZE);
            CheckStatus();
            SendData(GetBytesFromObject(dbregs), DEBUG_DBGREGS_SIZE);
            CheckStatus();
        }

        /// <summary>
        /// Executes a single instruction
        /// </summary>
        public void SingleStep()
        {
            CheckConnected();
            CheckDebugging();

            SendCMDPacket(CMDS.CMD_DEBUG_SINGLESTEP, 0);
            CheckStatus();
        }
    }
}

================================================
FILE: libdebug/PS4DBG.Kernel.cs
================================================
using System;

namespace libdebug
{
    public partial class PS4DBG
    {
        // kernel
        //packet sizes
        //send size
        private const int CMD_KERN_READ_PACKET_SIZE = 12;
        private const int CMD_KERN_WRITE_PACKET_SIZE = 12;
        //receive size
        private const int KERN_BASE_SIZE = 8;


        /// <summary>
        /// Get kernel base address
        /// </summary>
        /// <returns></returns>
        public ulong KernelBase()
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_KERN_BASE, 0);
            CheckStatus();
            return BitConverter.ToUInt64(ReceiveData(KERN_BASE_SIZE), 0);
        }

        /// <summary>
        /// Read memory from kernel
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <param name="length">Data length</param>
        /// <returns></returns>
        public byte[] KernelReadMemory(ulong address, int length)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_KERN_READ, CMD_KERN_READ_PACKET_SIZE, address, length);
            CheckStatus();
            return ReceiveData(length);
        }

        /// <summary>
        /// Write memory in kernel
        /// </summary>
        /// <param name="address">Memory address</param>
        /// <param name="data">Data</param>
        public void KernelWriteMemory(ulong address, byte[] data)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_KERN_WRITE, CMD_KERN_WRITE_PACKET_SIZE, address, data.Length);
            CheckStatus();
            SendData(data, data.Length);
            CheckStatus();
        }
    }
}

================================================
FILE: libdebug/PS4DBG.Proc.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;

namespace libdebug
{
    public partial class PS4DBG
    {
        //proc
        // packet sizes
        // send size
        private const int CMD_PROC_READ_PACKET_SIZE = 16;
        private const int CMD_PROC_WRITE_PACKET_SIZE = 16;
        private const int CMD_PROC_MAPS_PACKET_SIZE = 4;
        private const int CMD_PROC_INSTALL_PACKET_SIZE = 4;
        private const int CMD_PROC_CALL_PACKET_SIZE = 68;
        private const int CMD_PROC_ELF_PACKET_SIZE = 8;
        private const int CMD_PROC_PROTECT_PACKET_SIZE = 20;
        private const int CMD_PROC_SCAN_PACKET_SIZE = 10;
        private const int CMD_PROC_INFO_PACKET_SIZE = 4;
        private const int CMD_PROC_ALLOC_PACKET_SIZE = 8;
        private const int CMD_PROC_FREE_PACKET_SIZE = 16;
        // receive size
        private const int PROC_LIST_ENTRY_SIZE = 36;
        private const int PROC_MAP_ENTRY_SIZE = 58;
        private const int PROC_INSTALL_SIZE = 8;
        private const int PROC_CALL_SIZE = 12;
        private const int PROC_PROC_INFO_SIZE = 188;
        private const int PROC_ALLOC_SIZE = 8;
    

        /// <summary>
        /// Get current process list
        /// </summary>
        /// <returns></returns>
        public ProcessList GetProcessList()
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_PROC_LIST, 0);
            CheckStatus();

            // recv count
            byte[] bytes = new byte[4];
            sock.Receive(bytes, 4, SocketFlags.None);
            int number = BitConverter.ToInt32(bytes, 0);

            // recv data
            byte[] data = ReceiveData(number * PROC_LIST_ENTRY_SIZE);

            // parse data
            string[] names = new string[number];
            int[] pids = new int[number];
            for (int i = 0; i < number; i++)
            {
                int offset = i * PROC_LIST_ENTRY_SIZE;
                names[i] = ConvertASCII(data, offset);
                pids[i] = BitConverter.ToInt32(data, offset + 32);
            }

            return new ProcessList(number, names, pids);
        }

        /// <summary>
        /// Read memory
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <param name="address">Memory address</param>
        /// <param name="length">Data length</param>
        /// <returns></returns>
        public byte[] ReadMemory(int pid, ulong address, int length)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_PROC_READ, CMD_PROC_READ_PACKET_SIZE, pid, address, length);
            CheckStatus();
            return ReceiveData(length);
        }

        /// <summary>
        /// Write memory
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <param name="address">Memory address</param>
        /// <param name="data">Data</param>
        public void WriteMemory(int pid, ulong address, byte[] data)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_PROC_WRITE, CMD_PROC_WRITE_PACKET_SIZE, pid, address, data.Length);
            CheckStatus();
            SendData(data, data.Length);
            CheckStatus();
        }

        /// <summary>
        /// Get process memory maps
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <returns></returns>
        public ProcessMap GetProcessMaps(int pid)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_PROC_MAPS, CMD_PROC_MAPS_PACKET_SIZE, pid);
            CheckStatus();

            // recv count
            byte[] bnumber = new byte[4];
            sock.Receive(bnumber, 4, SocketFlags.None);
            int number = BitConverter.ToInt32(bnumber, 0);

            // recv data
            byte[] data = ReceiveData(number * PROC_MAP_ENTRY_SIZE);

            // parse data
            MemoryEntry[] entries = new MemoryEntry[number];
            for (int i = 0; i < number; i++)
            {
                int offset = i * PROC_MAP_ENTRY_SIZE;
                entries[i] = new MemoryEntry
                {
                    name = ConvertASCII(data, offset),
                    start = BitConverter.ToUInt64(data, offset + 32),
                    end = BitConverter.ToUInt64(data, offset + 40),
                    offset = BitConverter.ToUInt64(data, offset + 48),
                    prot = BitConverter.ToUInt16(data, offset + 56)
                };

            }

            return new ProcessMap(pid, entries);
        }

        /// <summary>
        /// Install RPC into a process, this returns a stub address that you should pass into call functions
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <returns></returns>
        public ulong InstallRPC(int pid)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_PROC_INTALL, CMD_PROC_INSTALL_PACKET_SIZE, pid);
            CheckStatus();

            return BitConverter.ToUInt64(ReceiveData(PROC_INSTALL_SIZE), 0);
        }

        /// <summary>
        /// Call function (returns rax)
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <param name="rpcstub">Stub address from InstallRPC</param>
        /// <param name="address">Address to call</param>
        /// <param name="args">Arguments array</param>
        /// <returns></returns>
        public ulong Call(int pid, ulong rpcstub, ulong address, params object[] args)
        {
            CheckConnected();

            // need to do this in a custom format
            CMDPacket packet = new CMDPacket
            {
                magic = CMD_PACKET_MAGIC,
                cmd = (uint) CMDS.CMD_PROC_CALL,
                datalen = (uint) CMD_PROC_CALL_PACKET_SIZE
            };
            SendData(GetBytesFromObject(packet), CMD_PACKET_SIZE);

            MemoryStream rs = new MemoryStream();
            rs.Write(BitConverter.GetBytes(pid), 0, sizeof(int));
            rs.Write(BitConverter.GetBytes(rpcstub), 0, sizeof(ulong));
            rs.Write(BitConverter.GetBytes(address), 0, sizeof(ulong));

            int num = 0;
            foreach (object arg in args)
            {
                byte[] bytes = new byte[8];

                switch (arg)
                {
                    case char c:
                        {
                            byte[] tmp = BitConverter.GetBytes(c);
                            Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(char));

                            byte[] pad = new byte[sizeof(ulong) - sizeof(char)];
                            Buffer.BlockCopy(pad, 0, bytes, sizeof(char), pad.Length);
                            break;
                        }
                    case byte b:
                        {
                            byte[] tmp = BitConverter.GetBytes(b);
                            Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(byte));

                            byte[] pad = new byte[sizeof(ulong) - sizeof(byte)];
                            Buffer.BlockCopy(pad, 0, bytes, sizeof(byte), pad.Length);
                            break;
                        }
                    case short s:
                        {
                            byte[] tmp = BitConverter.GetBytes(s);
                            Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(short));

                            byte[] pad = new byte[sizeof(ulong) - sizeof(short)];
                            Buffer.BlockCopy(pad, 0, bytes, sizeof(short), pad.Length);
                            break;
                        }
                    case ushort us:
                        {
                            byte[] tmp = BitConverter.GetBytes(us);
                            Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(ushort));

                            byte[] pad = new byte[sizeof(ulong) - sizeof(ushort)];
                            Buffer.BlockCopy(pad, 0, bytes, sizeof(ushort), pad.Length);
                            break;
                        }
                    case int i:
                        {
                            byte[] tmp = BitConverter.GetBytes(i);
                            Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(int));

                            byte[] pad = new byte[sizeof(ulong) - sizeof(int)];
                            Buffer.BlockCopy(pad, 0, bytes, sizeof(int), pad.Length);
                            break;
                        }
                    case uint ui:
                        {
                            byte[] tmp = BitConverter.GetBytes(ui);
                            Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(uint));

                            byte[] pad = new byte[sizeof(ulong) - sizeof(uint)];
                            Buffer.BlockCopy(pad, 0, bytes, sizeof(uint), pad.Length);
                            break;
                        }
                    case long l:
                        {
                            byte[] tmp = BitConverter.GetBytes(l);
                            Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(long));
                            break;
                        }
                    case ulong ul:
                        {
                            byte[] tmp = BitConverter.GetBytes(ul);
                            Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(ulong));
                            break;
                        }
                }

                rs.Write(bytes, 0, bytes.Length);
                num++;
            }

            if (num > 6)
            {
                throw new Exception("libdbg: too many arguments");
            }

            if (num < 6)
            {
                for (int i = 0; i < (6 - num); i++)
                {
                    rs.Write(BitConverter.GetBytes((ulong)0), 0, sizeof(ulong));
                }
            }

            SendData(rs.ToArray(), CMD_PROC_CALL_PACKET_SIZE);
            rs.Dispose();

            CheckStatus();

            byte[] data = ReceiveData(PROC_CALL_SIZE);
            return BitConverter.ToUInt64(data, 4);
        }

        /// <summary>
        /// Load elf
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <param name="elf">Elf</param>
        public void LoadElf(int pid, byte[] elf)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_PROC_ELF, CMD_PROC_ELF_PACKET_SIZE, pid, (uint)elf.Length);
            CheckStatus();
            SendData(elf, elf.Length);
            CheckStatus();
        }

        /// <summary>
        /// Load elf
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <param name="filename">Elf filename</param>
        public void LoadElf(int pid, string filename)
        {
            LoadElf(pid, File.ReadAllBytes(filename));
        }

        public enum ScanValueType : byte
        {
            valTypeUInt8 = 0,
            valTypeInt8,
            valTypeUInt16,
            valTypeInt16,
            valTypeUInt32,
            valTypeInt32,
            valTypeUInt64,
            valTypeInt64,
            valTypeFloat,
            valTypeDouble,
            valTypeArrBytes,
            valTypeString
        }

        public enum ScanCompareType : byte
        {
            ExactValue = 0,
            FuzzyValue,
            BiggerThan,
            SmallerThan,
            ValueBetween,
            IncreasedValue,
            IncreasedValueBy,
            DecreasedValue,
            DecreasedValueBy,
            ChangedValue,
            UnchangedValue,
            UnknownInitialValue
        }

        public List<ulong> ScanProcess<T>(int pid, ScanCompareType compareType, T value, T extraValue = default)
        {
            CheckConnected();

            int typeLength = 0;
            ScanValueType valueType;
            byte[] valueBuffer, extraValueBuffer = null;

            // fill in variables
            switch (value)
            {
                case bool b:
                    valueType = ScanValueType.valTypeUInt8;
                    typeLength = 1;
                    valueBuffer = BitConverter.GetBytes(b);
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((bool)(object)extraValue);
                    break;
                case sbyte sb:
                    valueType = ScanValueType.valTypeInt8;
                    valueBuffer = BitConverter.GetBytes(sb);
                    typeLength = 1;
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((sbyte)(object)extraValue);
                    break;
                case byte b:
                    valueType = ScanValueType.valTypeUInt8;
                    valueBuffer = BitConverter.GetBytes(b);
                    typeLength = 1;
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((byte)(object)extraValue);
                    break;
                case short s:
                    valueType = ScanValueType.valTypeInt16;
                    valueBuffer = BitConverter.GetBytes(s);
                    typeLength = 2;
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((short)(object)extraValue);
                    break;
                case ushort us:
                    valueType = ScanValueType.valTypeUInt16;
                    valueBuffer = BitConverter.GetBytes(us);
                    typeLength = 2;
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((ushort)(object)extraValue);
                    break;
                case int i:
                    valueType = ScanValueType.valTypeInt32;
                    valueBuffer = BitConverter.GetBytes(i);
                    typeLength = 4;
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((int)(object)extraValue);
                    break;
                case uint ui:
                    valueType = ScanValueType.valTypeUInt32;
                    valueBuffer = BitConverter.GetBytes(ui);
                    typeLength = 4;
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((uint)(object)extraValue);
                    break;
                case long l:
                    valueType = ScanValueType.valTypeInt64;
                    valueBuffer = BitConverter.GetBytes(l);
                    typeLength = 8;
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((long)(object)extraValue);
                    break;
                case ulong ul:
                    valueType = ScanValueType.valTypeUInt64;
                    valueBuffer = BitConverter.GetBytes(ul);
                    typeLength = 8;
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((ulong)(object)extraValue);
                    break;
                case float f:
                    valueType = ScanValueType.valTypeFloat;
                    valueBuffer = BitConverter.GetBytes(f);
                    typeLength = 4;
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((float)(object)extraValue);
                    break;
                case double d:
                    valueType = ScanValueType.valTypeDouble;
                    valueBuffer = BitConverter.GetBytes(d);
                    typeLength = 8;
                    if (extraValue != null)
                        extraValueBuffer = BitConverter.GetBytes((double)(object)extraValue);
                    break;
                case string s:
                    valueType = ScanValueType.valTypeString;
                    valueBuffer = Encoding.ASCII.GetBytes(s);
                    typeLength = valueBuffer.Length;
                    break;
                case byte[] ba:
                    valueType = ScanValueType.valTypeArrBytes;
                    valueBuffer = ba;
                    typeLength = valueBuffer.Length;
                    break;
                default:
                    throw new NotSupportedException("Requested scan value type is not supported! (Feed in Byte[] instead.)");
                    
            }
            // send packet
            SendCMDPacket(CMDS.CMD_PROC_SCAN, CMD_PROC_SCAN_PACKET_SIZE, pid, (byte)valueType, (byte)compareType, (int)(extraValue == null ? typeLength : typeLength * 2));
            CheckStatus();

            SendData(valueBuffer, typeLength);
            if (extraValueBuffer != null)
            {
                SendData(extraValueBuffer, typeLength);
            }

            CheckStatus();

            // receive results
            int save = sock.ReceiveTimeout;
            sock.ReceiveTimeout = Int32.MaxValue;
            List<ulong> results = new List<ulong>();
            while(true)
            {
                ulong result = BitConverter.ToUInt64(ReceiveData(sizeof(ulong)), 0);
                if(result == 0xFFFFFFFFFFFFFFFF)
                {
                    break;
                }

                results.Add(result);
            }

            sock.ReceiveTimeout = save;

            return results;
        }

        /// <summary>
        /// Changes protection on pages in range
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <param name="address">Address</param>
        /// <param name="length">Length</param>
        /// <param name="newprot">New protection</param>
        /// <returns></returns>
        public void ChangeProtection(int pid, ulong address, uint length, VM_PROTECTIONS newProt)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_PROC_PROTECT, CMD_PROC_PROTECT_PACKET_SIZE, pid, address, length, (uint)newProt);
            CheckStatus();
        }

        /// <summary>
        /// Get process information
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <returns></returns>
        public ProcessInfo GetProcessInfo(int pid)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_PROC_INFO, CMD_PROC_INFO_PACKET_SIZE, pid);
            CheckStatus();

            byte[] data = ReceiveData(PROC_PROC_INFO_SIZE);
            return (ProcessInfo)GetObjectFromBytes(data, typeof(ProcessInfo));
        }

        /// <summary>
        /// Allocate RWX memory in the process space
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <param name="length">Size of memory allocation</param>
        /// <returns></returns>
        public ulong AllocateMemory(int pid, int length)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_PROC_ALLOC, CMD_PROC_ALLOC_PACKET_SIZE, pid, length);
            CheckStatus();
            return BitConverter.ToUInt64(ReceiveData(PROC_ALLOC_SIZE), 0);
        }

        /// <summary>
        /// Free memory in the process space
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <param name="address">Address of the memory allocation</param>
        /// <param name="length">Size of memory allocation</param>
        /// <returns></returns>
        public void FreeMemory(int pid, ulong address, int length)
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_PROC_FREE, CMD_PROC_FREE_PACKET_SIZE, pid, address, length);
            CheckStatus();
        }

        public T ReadMemory<T>(int pid, ulong address)
        {
            if (typeof(T) == typeof(string))
            {
                string str = "";
                ulong i = 0;

                while (true)
                {
                    byte value = ReadMemory(pid, address + i, sizeof(byte))[0];
                    if (value == 0)
                    {
                        break;
                    }
                    str += Convert.ToChar(value);
                    i++;
                }

                return (T)(object)str;
            }
            
            if (typeof(T) == typeof(byte[]))
            {
                throw new NotSupportedException("byte arrays are not supported, use ReadMemory(int pid, ulong address, int size)");
            }

            return (T)GetObjectFromBytes(ReadMemory(pid, address, Marshal.SizeOf(typeof(T))), typeof(T));
        }

        public void WriteMemory<T>(int pid, ulong address, T value)
        {
            if (typeof(T) == typeof(string))
            {
                WriteMemory(pid, address, Encoding.ASCII.GetBytes((string)(object)value + (char)0x0));
                return;
            }

            if (typeof(T) == typeof(byte[]))
            {
                WriteMemory(pid, address, (byte[])(object)value);
                return;
            }
            
            WriteMemory(pid, address, GetBytesFromObject(value));
        }
    }
}

================================================
FILE: libdebug/PS4DBG.cs
================================================
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace libdebug
{
    public partial class PS4DBG
    {
        private Socket sock = null;
        private IPEndPoint enp = null;

        public bool IsConnected { get; private set; } = false;

        public bool IsDebugging { get; private set; } = false;

        private Thread debugThread = null;

        // some global values
        private const string LIBRARY_VERSION = "1.2";
        private const int PS4DBG_PORT = 744;
        private const int PS4DBG_DEBUG_PORT = 755;
        private const int NET_MAX_LENGTH = 8192;

        private const int BROADCAST_PORT = 1010;
        private const uint BROADCAST_MAGIC = 0xFFFFAAAA;

        // from protocol.h
        // each packet starts with the magic
        // each C# base type can translate into a packet field
        // some packets, such as write take an additional data whose length will be specified in the cmd packet data field structure specific to that cmd type
        // ushort - 2 bytes | uint - 4 bytes | ulong - 8 bytes
        private const uint CMD_PACKET_MAGIC = 0xFFAABBCC;

        // from debug.h
        //struct debug_breakpoint {
        //    uint32_t valid;
        //    uint64_t address;
        //    uint8_t original;
        //};
        public static uint MAX_BREAKPOINTS = 10;
        public static uint MAX_WATCHPOINTS = 4;

        //  struct cmd_packet {
        //    uint32_t magic;
        //    uint32_t cmd;
        //    uint32_t datalen;
        //    // (field not actually part of packet, comes after)
        //    uint8_t* data;
        //  }
        //  __attribute__((packed));
        //  #define CMD_PACKET_SIZE 12
        private const int CMD_PACKET_SIZE = 12;
        public enum CMDS : uint
        {
            CMD_VERSION = 0xBD000001,

            CMD_PROC_LIST = 0xBDAA0001,
            CMD_PROC_READ = 0xBDAA0002,
            CMD_PROC_WRITE = 0xBDAA0003,
            CMD_PROC_MAPS = 0xBDAA0004,
            CMD_PROC_INTALL = 0xBDAA0005,
            CMD_PROC_CALL = 0xBDAA0006,
            CMD_PROC_ELF = 0xBDAA0007,
            CMD_PROC_PROTECT = 0xBDAA0008,
            CMD_PROC_SCAN = 0xBDAA0009,
            CMD_PROC_INFO = 0xBDAA000A,
            CMD_PROC_ALLOC = 0xBDAA000B,
            CMD_PROC_FREE = 0xBDAA000C,

            CMD_DEBUG_ATTACH = 0xBDBB0001,
            CMD_DEBUG_DETACH = 0xBDBB0002,
            CMD_DEBUG_BREAKPT = 0xBDBB0003,
            CMD_DEBUG_WATCHPT = 0xBDBB0004,
            CMD_DEBUG_THREADS = 0xBDBB0005,
            CMD_DEBUG_STOPTHR = 0xBDBB0006,
            CMD_DEBUG_RESUMETHR = 0xBDBB0007,
            CMD_DEBUG_GETREGS = 0xBDBB0008,
            CMD_DEBUG_SETREGS = 0xBDBB0009,
            CMD_DEBUG_GETFPREGS = 0xBDBB000A,
            CMD_DEBUG_SETFPREGS = 0xBDBB000B,
            CMD_DEBUG_GETDBGREGS = 0xBDBB000C,
            CMD_DEBUG_SETDBGREGS = 0xBDBB000D,
            CMD_DEBUG_STOPGO = 0xBDBB0010,
            CMD_DEBUG_THRINFO = 0xBDBB0011,
            CMD_DEBUG_SINGLESTEP = 0xBDBB0012,

            CMD_KERN_BASE = 0xBDCC0001,
            CMD_KERN_READ = 0xBDCC0002,
            CMD_KERN_WRITE = 0xBDCC0003,

            CMD_CONSOLE_REBOOT = 0xBDDD0001,
            CMD_CONSOLE_END = 0xBDDD0002,
            CMD_CONSOLE_PRINT = 0xBDDD0003,
            CMD_CONSOLE_NOTIFY = 0xBDDD0004,
            CMD_CONSOLE_INFO = 0xBDDD0005,
        };

        public enum CMD_STATUS : uint
        {
            CMD_SUCCESS = 0x80000000,
            CMD_ERROR = 0xF0000001,
            CMD_TOO_MUCH_DATA = 0xF0000002,
            CMD_DATA_NULL = 0xF0000003,
            CMD_ALREADY_DEBUG = 0xF0000004,
            CMD_INVALID_INDEX = 0xF0000005
        };

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct CMDPacket
        {
            public uint magic;
            public uint cmd;
            public uint datalen;
        }

        // enums
        public enum VM_PROTECTIONS : uint
        {
            VM_PROT_NONE = 0x00,
            VM_PROT_READ = 0x01,
            VM_PROT_WRITE = 0x02,
            VM_PROT_EXECUTE = 0x04,
            VM_PROT_DEFAULT = (VM_PROT_READ | VM_PROT_WRITE),
            VM_PROT_ALL = (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE),
            VM_PROT_NO_CHANGE = 0x08,
            VM_PROT_COPY = 0x10,
            VM_PROT_WANTS_COPY = 0x10
        };
        public enum WATCHPT_LENGTH : uint
        {
            DBREG_DR7_LEN_1 = 0x00,	/* 1 byte length */
            DBREG_DR7_LEN_2 = 0x01,
            DBREG_DR7_LEN_4 = 0x03,
            DBREG_DR7_LEN_8 = 0x02,
        };
        public enum WATCHPT_BREAKTYPE : uint
        {
            DBREG_DR7_EXEC = 0x00,	/* break on execute       */
            DBREG_DR7_WRONLY = 0x01,	/* break on write         */
            DBREG_DR7_RDWR = 0x03,	/* break on read or write */
        };

        // General helper functions, make code cleaner
        private static string ConvertASCII(byte[] data, int offset)
        {
            int length = Array.IndexOf<byte>(data, 0, offset) - offset;
            if (length < 0)
            {
                length = data.Length - offset;
            }

            return Encoding.ASCII.GetString(data, offset, length);
        }
        public static byte[] SubArray(byte[] data, int offset, int length)
        {
            byte[] bytes = new byte[length];
            Buffer.BlockCopy(data, offset, bytes, 0, length);
            return bytes;
        }
        public static object GetObjectFromBytes(byte[] buffer, Type type)
        {
            int size = Marshal.SizeOf(type);

            IntPtr ptr = Marshal.AllocHGlobal(size);

            Marshal.Copy(buffer, 0, ptr, size);
            object r = Marshal.PtrToStructure(ptr, type);

            Marshal.FreeHGlobal(ptr);

            return r;
        }
        private static byte[] GetBytesFromObject(object obj)
        {
            int size = Marshal.SizeOf(obj);

            byte[] bytes = new byte[size];
            IntPtr ptr = Marshal.AllocHGlobal(size);

            Marshal.StructureToPtr(obj, ptr, false);
            Marshal.Copy(ptr, bytes, 0, size);

            Marshal.FreeHGlobal(ptr);

            return bytes;
        }

        // General networking functions
        private static IPAddress GetBroadcastAddress(IPAddress address, IPAddress subnetMask)
        {
            byte[] ipAdressBytes = address.GetAddressBytes();
            byte[] subnetMaskBytes = subnetMask.GetAddressBytes();

            byte[] broadcastAddress = new byte[ipAdressBytes.Length];
            for (int i = 0; i < broadcastAddress.Length; i++)
            {
                broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255));
            }

            return new IPAddress(broadcastAddress);
        }
        private void SendCMDPacket(CMDS cmd, int length, params object[] fields)
        {
            CMDPacket packet = new CMDPacket
            {
                magic = CMD_PACKET_MAGIC,
                cmd = (uint) cmd,
                datalen = (uint) length
            };

            byte[] data = null;

            if (length > 0)
            {
                MemoryStream rs = new MemoryStream();
                foreach (object field in fields)
                {
                    byte[] bytes = null;

                    switch (field)
                    {
                        case char c:
                            bytes = BitConverter.GetBytes(c);
                            break;
                        case byte b:
                            bytes = BitConverter.GetBytes(b);
                            break;
                        case short s:
                            bytes = BitConverter.GetBytes(s);
                            break;
                        case ushort us:
                            bytes = BitConverter.GetBytes(us);
                            break;
                        case int i:
                            bytes = BitConverter.GetBytes(i);
                            break;
                        case uint u:
                            bytes = BitConverter.GetBytes(u);
                            break;
                        case long l:
                            bytes = BitConverter.GetBytes(l);
                            break;
                        case ulong ul:
                            bytes = BitConverter.GetBytes(ul);
                            break;
                        case byte[] ba:
                            bytes = ba;
                            break;
                    }

                    if (bytes != null) rs.Write(bytes, 0, bytes.Length);
                }

                data = rs.ToArray();
                rs.Dispose();
            }

            SendData(GetBytesFromObject(packet), CMD_PACKET_SIZE);

            if (data != null)
            {
                SendData(data, length);
            }
        }
        private void SendData(byte[] data, int length)
        {
            int left = length;
            int offset = 0;
            int sent = 0;

            while (left > 0)
            {
                if (left > NET_MAX_LENGTH)
                {
                    byte[] bytes = SubArray(data, offset, NET_MAX_LENGTH);
                    sent = sock.Send(bytes, NET_MAX_LENGTH, SocketFlags.None);
                }
                else
                {
                    byte[] bytes = SubArray(data, offset, left);
                    sent = sock.Send(bytes, left, SocketFlags.None);
                }

                offset += sent;
                left -= sent;
            }
        }
        private byte[] ReceiveData(int length)
        {
            MemoryStream s = new MemoryStream();

            int left = length;
            int recv = 0;
            while (left > 0)
            {
                byte[] b = new byte[NET_MAX_LENGTH];
                recv = sock.Receive(b, NET_MAX_LENGTH, SocketFlags.None);
                s.Write(b, 0, recv);
                left -= recv;
            }

            byte[] data = s.ToArray();

            s.Dispose();
            GC.Collect();

            return data;
        }
        private CMD_STATUS ReceiveStatus()
        {
            byte[] status = new byte[4];
            sock.Receive(status, 4, SocketFlags.None);
            return (CMD_STATUS)BitConverter.ToUInt32(status, 0);
        }
        private void CheckStatus()
        {
            CMD_STATUS status = ReceiveStatus();
            if (status != CMD_STATUS.CMD_SUCCESS)
            {
                throw new Exception("libdbg status " + ((uint)status).ToString("X"));
            }
        }

        private void CheckConnected()
        {
            if (!IsConnected)
            {
                throw new Exception("libdbg: not connected");
            }
        }
        private void CheckDebugging()
        {
            if (!IsDebugging)
            {
                throw new Exception("libdbg: not debugging");
            }
        }


        public PS4DBG()
        {
            enp = null;
            sock = null;
        }

        /// <summary>
        /// Initializes PS4DBG class
        /// </summary>
        /// <param name="addr">PlayStation 4 address</param>
        public PS4DBG(IPAddress addr)
        {
            enp = new IPEndPoint(addr, PS4DBG_PORT);
            sock = new Socket(enp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        }

        /// <summary>
        /// Initializes PS4DBG class
        /// </summary>
        /// <param name="ip">PlayStation 4 ip address</param>
        public PS4DBG(string ip)
        {
            IPAddress addr = null;
            try
            {
                addr = IPAddress.Parse(ip);
            }
            catch (FormatException ex)
            {
                throw ex;
            }

            enp = new IPEndPoint(addr, PS4DBG_PORT);
            sock = new Socket(enp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        }

        /// <summary>
        /// Find the playstation ip
        /// </summary>
        public static string FindPlayStation()
        {
            UdpClient uc = new UdpClient();
            IPEndPoint server = new IPEndPoint(IPAddress.Any, 0);
            uc.EnableBroadcast = true;
            uc.Client.ReceiveTimeout = 4000;

            byte[] magic = BitConverter.GetBytes(BROADCAST_MAGIC);

            IPAddress addr = null;
            IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    addr = ip;
                }
            }

            if (addr == null)
            {
                throw new Exception("libdbg broadcast error: could not get host ip");
            }

            uc.Send(magic, magic.Length, new IPEndPoint(GetBroadcastAddress(addr, IPAddress.Parse("255.255.255.0")), BROADCAST_PORT));

            byte[] resp = uc.Receive(ref server);
            if (BitConverter.ToUInt32(resp, 0) != BROADCAST_MAGIC)
            {
                throw new Exception("libdbg broadcast error: wrong magic on udp server");
            }

            return server.Address.ToString();
        }

        /// <summary>
        /// Connects to PlayStation 4
        /// </summary>
        public void Connect()
        {
            if (!IsConnected)
            {
                sock.NoDelay = true;
                sock.ReceiveBufferSize = NET_MAX_LENGTH;
                sock.SendBufferSize = NET_MAX_LENGTH;

                sock.ReceiveTimeout = -1;
                IAsyncResult result = sock.BeginConnect(enp, null, null);
                result.AsyncWaitHandle.WaitOne(3000);
                IsConnected = sock.Connected;
            }
        }

        /// <summary>
        /// Disconnects from PlayStation 4
        /// </summary>
        public void Disconnect()
        {
            SendCMDPacket(CMDS.CMD_CONSOLE_END, 0);
            sock.Shutdown(SocketShutdown.Both);
            sock.Close();
            IsConnected = false;
        }

        /// <summary>
        /// Get current ps4debug version from library
        /// </summary>
        public string GetLibraryDebugVersion()
        {
            return LIBRARY_VERSION;
        }

        /// <summary>
        /// Get the current ps4debug version from console
        /// </summary>
        public string GetConsoleDebugVersion()
        {
            CheckConnected();

            SendCMDPacket(CMDS.CMD_VERSION, 0);

            byte[] ldata = new byte[4];
            sock.Receive(ldata, 4, SocketFlags.None);

            int length = BitConverter.ToInt32(ldata, 0);

            byte[] data = new byte[length];
            sock.Receive(data, length, SocketFlags.None);

            return ConvertASCII(data, 0);
        }
    }
}

================================================
FILE: libdebug/Process.cs
================================================
using System.Runtime.InteropServices;

namespace libdebug
{
    public class Process
    {
        public string name;
        public int pid;

        /// <summary>
        /// Initializes Process class
        /// </summary>
        /// <param name="name">Process name</param>
        /// <param name="pid">Process ID</param>
        /// <returns></returns>
        public Process(string name, int pid)
        {
            this.name = name;
            this.pid = pid;
        }
        public override string ToString()
        {
            return $"[{pid:X}] {name}";
        }
    }

    public class ProcessList
    {
        public Process[] processes;

        /// <summary>
        /// Initializes ProcessList class
        /// </summary>
        /// <param name="number">Number of processes</param>
        /// <param name="names">Process names</param>
        /// <param name="pids">Process IDs</param>
        /// <returns></returns>
        public ProcessList(int number, string[] names, int[] pids)
        {
            processes = new Process[number];
            for (int i = 0; i < number; i++)
            {
                processes[i] = new Process(names[i], pids[i]);
            }
        }

        /// <summary>
        /// Finds a process based off name
        /// </summary>
        /// <param name="name">Process name</param>
        /// <param name="contains">Condition to check if process name contains name</param>
        /// <returns></returns>
        public Process FindProcess(string name, bool contains = false)
        {
            foreach (Process p in processes)
            {
                if (contains)
                {
                    if (p.name.Contains(name))
                    {
                        return p;
                    }
                }
                else
                {
                    if (p.name == name)
                    {
                        return p;
                    }
                }
            }

            return null;
        }
    }

    public class MemoryEntry
    {
        public string name;
        public ulong start;
        public ulong end;
        public ulong offset;
        public uint prot;

        public override string ToString()
        {
            return $"{name} 0x{start:X}";
        }
    }

    public class ProcessMap
    {
        public int pid;
        public MemoryEntry[] entries;

        /// <summary>
        /// Initializes ProcessMap class with memory entries and process ID
        /// </summary>
        /// <param name="pid">Process ID</param>
        /// <param name="entries">Process memory entries</param>
        /// <returns></returns>
        public ProcessMap(int pid, MemoryEntry[] entries)
        {
            this.pid = pid;
            this.entries = entries;
        }

        /// <summary>
        /// Finds a virtual memory entry based off name
        /// </summary>
        /// <param name="name">Virtual memory entry name</param>
        /// <param name="contains">Condition to check if entry name contains name</param>
        /// <returns></returns>
        public MemoryEntry FindEntry(string name, bool contains = false)
        {
            foreach (MemoryEntry entry in entries)
            {
                if (contains)
                {
                    if (entry.name.Contains(name))
                    {
                        return entry;
                    }
                }
                else
                {
                    if (entry.name == name)
                    {
                        return entry;
                    }
                }
            }

            return null;
        }

        /// <summary>
        /// Finds a virtual memory entry based off size
        /// </summary>
        /// <param name="size">Virtual memory entry size</param>
        /// <returns></returns>
        public MemoryEntry FindEntry(ulong size)
        {
            foreach (MemoryEntry entry in entries)
            {
                if ((entry.start - entry.end) == size)
                {
                    return entry;
                }
            }

            return null;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct ProcessInfo
    {
        public int pid;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
        public string name;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string path;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string titleid;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string contentid;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct ThreadInfo
    {
        public int pid;
        public int priority;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string name;
    }
}

================================================
FILE: libdebug/Registers.cs
================================================
using System.Runtime.InteropServices;

namespace libdebug
{
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct regs
    {
        public ulong r_r15;
        public ulong r_r14;
        public ulong r_r13;
        public ulong r_r12;
        public ulong r_r11;
        public ulong r_r10;
        public ulong r_r9;
        public ulong r_r8;
        public ulong r_rdi;
        public ulong r_rsi;
        public ulong r_rbp;
        public ulong r_rbx;
        public ulong r_rdx;
        public ulong r_rcx;
        public ulong r_rax;
        public uint r_trapno;
        public ushort r_fs;
        public ushort r_gs;
        public uint r_err;
        public ushort r_es;
        public ushort r_ds;
        public ulong r_rip;
        public ulong r_cs;
        public ulong r_rflags;
        public ulong r_rsp;
        public ulong r_ss;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct envxmm
    {
        public ushort en_cw; /* control word (16bits) */
        public ushort en_sw; /* status word (16bits) */
        public byte en_tw; /* tag word (8bits) */
        public byte en_zero;
        public ushort en_opcode; /* opcode last executed (11 bits ) */
        public ulong en_rip; /* floating point instruction pointer */
        public ulong en_rdp; /* floating operand pointer */
        public uint en_mxcsr; /* SSE sontorol/status register */
        public uint en_mxcsr_mask; /* valid bits in mxcsr */
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct acc
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        public byte[] fp_bytes;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        private byte[] fp_pad;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct xmmacc
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public byte[] xmm_bytes;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct ymmacc
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public byte[] ymm_bytes;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct xstate_hdr
    {
        public ulong xstate_bv;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        private byte[] xstate_rsrv0;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
        private byte[] xstate_rsrv;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct savefpu_xstate
    {
        public xstate_hdr sx_hd;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public ymmacc[] sx_ymm;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 64)]
    public struct fpregs
    {
        public envxmm svn_env;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public acc[] sv_fp;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public xmmacc[] sv_xmm;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
        private byte[] sv_pad;
        public savefpu_xstate sv_xstate;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct dbregs
    {
        public ulong dr0;
        public ulong dr1;
        public ulong dr2;
        public ulong dr3;
        public ulong dr4;
        public ulong dr5;
        public ulong dr6;
        public ulong dr7;
        public ulong dr8;
        public ulong dr9;
        public ulong dr10;
        public ulong dr11;
        public ulong dr12;
        public ulong dr13;
        public ulong dr14;
        public ulong dr15;
    }
}

================================================
FILE: offsets.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;

namespace PS4Saves
{
    class offsets
    {
        public const int sceUserServiceGetInitialUser = 0x33B0;
        public const int sceUserServiceGetLoginUserIdList = 0x2B40;
        public const int sceUserServiceGetUserName = 0x3F20;

        public const int sceSaveDataMount = 0x248D0;
        public const int sceSaveDataUmount = 0x250C0;
        public const int sceSaveDataDirNameSearch = 0x25CA0;
        public const int sceSaveDataInitialize3 = 0x24740;
    }
}


================================================
FILE: structs.cs
================================================
using System.Runtime.InteropServices;

namespace PS4Saves
{
    [StructLayout(LayoutKind.Explicit, Size = 80)]
    public struct SceSaveDataMount
    {
        [FieldOffset(0x0)] public int userId;
        [FieldOffset(0x8)] public ulong titleId;
        [FieldOffset(0x10)] public ulong dirName;
        [FieldOffset(0x18)] public ulong fingerprint;
        [FieldOffset(0x20)] public ulong blocks;
        [FieldOffset(0x28)] public uint mountMode;
    }

    [StructLayout(LayoutKind.Explicit, Size = 64)]
    public struct SceSaveDataMount2
    {
        [FieldOffset(0x0)] public int userId;
        [FieldOffset(0x8)] public ulong dirName;
        [FieldOffset(0x10)] public ulong blocks;
        [FieldOffset(0x18)] public uint mountMode;
    }
    [StructLayout(LayoutKind.Explicit, Size = 64)]
    public struct SceSaveDataMountResult
    {
        [FieldOffset(0x0)] public SceSaveDataMountPoint mountPoint;
        [FieldOffset(0x20)] public ulong requiredBlocks;
        [FieldOffset(0x28)] public uint mountStatus;

    }

    [StructLayout(LayoutKind.Sequential, Size = 16)]
    public struct SceSaveDataMountPoint
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string data;
    }

    [StructLayout(LayoutKind.Sequential, Size = 64)]
    public struct SceSaveDataTransferringMount
    {
        public int userId;
        public ulong titleId;
        public ulong dirName;
        public ulong fingerprint;
    }

    [StructLayout(LayoutKind.Sequential, Size = 16)]
    public struct SceSaveDataTitleId
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
        public string data;
    }
    [StructLayout(LayoutKind.Sequential, Size = 32)]
    public struct SceSaveDataDirName
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string data;
    }
    [StructLayout(LayoutKind.Sequential, Size = 80)]
    public struct SceSaveDataFingerprint
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)]
        public string data;
    }
    [StructLayout(LayoutKind.Explicit, Size = 64)]
    public struct SceSaveDataDirNameSearchCond
    {
        [FieldOffset(0x0)] public int userId;
        [FieldOffset(0x8)] public ulong titleId;
        [FieldOffset(0x10)] public ulong dirName;
        [FieldOffset(0x18)] public uint key;
        [FieldOffset(0x1C)] public uint order;
    }
    [StructLayout(LayoutKind.Explicit, Size = 56)]
    public struct SceSaveDataDirNameSearchResult
    {
        [FieldOffset(0x0)] public uint hitNum;
        [FieldOffset(0x8)] public ulong dirNames;
        [FieldOffset(0x10)] public uint dirNamesNum;
        [FieldOffset(0x14)] public uint setNum;
        [FieldOffset(0x18)] public ulong param;
        [FieldOffset(0x20)] public ulong infos;
    }
    [StructLayout(LayoutKind.Explicit, Size = 1328)]
    public struct SceSaveDataParam
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
        [FieldOffset(0x0)] public byte[] title;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
        [FieldOffset(0x80)] public byte[] subTitle;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
        [FieldOffset(0x100)] public byte[] detail;
        [FieldOffset(0x500)] public uint userParam;
        [FieldOffset(0x508)] public long mtime;
    }
    [StructLayout(LayoutKind.Sequential, Size = 48)]
    public struct SceSaveDataSearchInfo
    {
        public ulong blocks;
        public ulong freeBlocks;
    }
}
Download .txt
gitextract_y_dojabp/

├── .gitignore
├── LICENSE
├── Main.Designer.cs
├── Main.cs
├── PS4Saves.csproj
├── Program.cs
├── Properties/
│   └── AssemblyInfo.cs
├── README.md
├── functions.cs
├── libdebug/
│   ├── PS4DBG.Console.cs
│   ├── PS4DBG.Debug.cs
│   ├── PS4DBG.Kernel.cs
│   ├── PS4DBG.Proc.cs
│   ├── PS4DBG.cs
│   ├── Process.cs
│   └── Registers.cs
├── offsets.cs
└── structs.cs
Download .txt
SYMBOL INDEX (146 symbols across 13 files)

FILE: Main.Designer.cs
  class Main (line 3) | partial class Main
    method Dispose (line 14) | protected override void Dispose(bool disposing)
    method InitializeComponent (line 29) | private void InitializeComponent()

FILE: Main.cs
  class Main (line 14) | public partial class Main : Form
    method Main (line 30) | public Main()
    method FormatSize (line 44) | public static string FormatSize(double size)
    method sizeTrackBar_Scroll (line 63) | private void sizeTrackBar_Scroll(object sender, EventArgs e)
    method SetStatus (line 67) | private void SetStatus(string msg)
    method WriteLog (line 71) | private void WriteLog(string msg)
    method connectButton_Click (line 107) | private void connectButton_Click(object sender, EventArgs e)
    method setupButton_Click (line 141) | private void setupButton_Click(object sender, EventArgs e)
    method searchButton_Click (line 238) | private void searchButton_Click(object sender, EventArgs e)
    method mountButton_Click (line 289) | private void mountButton_Click(object sender, EventArgs e)
    method unmountButton_Click (line 344) | private void unmountButton_Click(object sender, EventArgs e)
    method createButton_Click (line 366) | private void createButton_Click(object sender, EventArgs e)
    method GetUser (line 437) | private int GetUser()
    method InitialUser (line 446) | private int InitialUser()
    method Find (line 459) | private SearchEntry[] Find(SceSaveDataDirNameSearchCond searchCond, Sc...
    method Unmount (line 496) | private void Unmount(SceSaveDataMountPoint mountPoint)
    method Mount (line 507) | private string Mount(SceSaveDataMount mount, SceSaveDataMountResult mo...
    class SearchEntry (line 530) | class SearchEntry
      method ToString (line 537) | public override string ToString()
    method dirsComboBox_SelectedIndexChanged (line 543) | private void dirsComboBox_SelectedIndexChanged(object sender, EventArg...
    method userComboBox_SelectedIndexChanged (line 551) | private void userComboBox_SelectedIndexChanged(object sender, EventArg...
    class User (line 556) | class User
      method ToString (line 561) | public override string ToString()
    method GetSaveDirectories (line 566) | private string[] GetSaveDirectories()
    method GetUsers (line 588) | private User[] GetUsers()
    method checkIP (line 612) | public static bool checkIP(string IP)
    method payloadButton_Click (line 616) | private void payloadButton_Click(object sender, EventArgs e)
    method getGamesButton_Click (line 649) | private void getGamesButton_Click(object sender, EventArgs e)
    method gamesComboBox_SelectedIndexChanged (line 671) | private void gamesComboBox_SelectedIndexChanged(object sender, EventAr...

FILE: Program.cs
  class Program (line 7) | static class Program
    method Main (line 12) | [STAThread]

FILE: functions.cs
  class functions (line 3) | internal static class functions

FILE: libdebug/PS4DBG.Console.cs
  class PS4DBG (line 5) | public partial class PS4DBG
    method Reboot (line 19) | public void Reboot()
    method Print (line 30) | public void Print(string str)
    method Notify (line 44) | public void Notify(int messageType, string message)
    method GetConsoleInformation (line 58) | public void GetConsoleInformation()

FILE: libdebug/PS4DBG.Debug.cs
  class PS4DBG (line 9) | public partial class PS4DBG
    type DebuggerInterruptPacket (line 30) | [StructLayout(LayoutKind.Sequential, Pack = 1)]
    method DebuggerThread (line 51) | private void DebuggerThread(object obj)
    method AttachDebugger (line 94) | public void AttachDebugger(int pid, DebuggerInterruptCallback callback)
    method DetachDebugger (line 122) | public void DetachDebugger()
    method ProcessStop (line 142) | public void ProcessStop()
    method ProcessKill (line 155) | public void ProcessKill()
    method ProcessResume (line 168) | public void ProcessResume()
    method ChangeBreakpoint (line 184) | public void ChangeBreakpoint(int index, bool enabled, ulong address)
    method ChangeWatchpoint (line 207) | public void ChangeWatchpoint(int index, bool enabled, WATCHPT_LENGTH l...
    method GetThreadList (line 225) | public uint[] GetThreadList()
    method GetThreadInfo (line 252) | public ThreadInfo GetThreadInfo(uint lwpid)
    method StopThread (line 268) | public void StopThread(uint lwpid)
    method ResumeThread (line 282) | public void ResumeThread(uint lwpid)
    method GetRegisters (line 296) | public regs GetRegisters(uint lwpid)
    method SetRegisters (line 313) | public void SetRegisters(uint lwpid, regs regs)
    method GetFloatRegisters (line 329) | public fpregs GetFloatRegisters(uint lwpid)
    method SetFloatRegisters (line 346) | public void SetFloatRegisters(uint lwpid, fpregs fpregs)
    method GetDebugRegisters (line 362) | public dbregs GetDebugRegisters(uint lwpid)
    method SetDebugRegisters (line 379) | public void SetDebugRegisters(uint lwpid, dbregs dbregs)
    method SingleStep (line 393) | public void SingleStep()

FILE: libdebug/PS4DBG.Kernel.cs
  class PS4DBG (line 5) | public partial class PS4DBG
    method KernelBase (line 20) | public ulong KernelBase()
    method KernelReadMemory (line 35) | public byte[] KernelReadMemory(ulong address, int length)
    method KernelWriteMemory (line 49) | public void KernelWriteMemory(ulong address, byte[] data)

FILE: libdebug/PS4DBG.Proc.cs
  class PS4DBG (line 10) | public partial class PS4DBG
    method GetProcessList (line 39) | public ProcessList GetProcessList()
    method ReadMemory (line 74) | public byte[] ReadMemory(int pid, ulong address, int length)
    method WriteMemory (line 89) | public void WriteMemory(int pid, ulong address, byte[] data)
    method GetProcessMaps (line 104) | public ProcessMap GetProcessMaps(int pid)
    method InstallRPC (line 143) | public ulong InstallRPC(int pid)
    method Call (line 161) | public ulong Call(int pid, ulong rpcstub, ulong address, params object...
    method LoadElf (line 285) | public void LoadElf(int pid, byte[] elf)
    method LoadElf (line 300) | public void LoadElf(int pid, string filename)
    type ScanValueType (line 305) | public enum ScanValueType : byte
    type ScanCompareType (line 321) | public enum ScanCompareType : byte
    method ScanProcess (line 337) | public List<ulong> ScanProcess<T>(int pid, ScanCompareType compareType...
    method ChangeProtection (line 479) | public void ChangeProtection(int pid, ulong address, uint length, VM_P...
    method GetProcessInfo (line 492) | public ProcessInfo GetProcessInfo(int pid)
    method AllocateMemory (line 509) | public ulong AllocateMemory(int pid, int length)
    method FreeMemory (line 525) | public void FreeMemory(int pid, ulong address, int length)
    method ReadMemory (line 533) | public T ReadMemory<T>(int pid, ulong address)
    method WriteMemory (line 562) | public void WriteMemory<T>(int pid, ulong address, T value)

FILE: libdebug/PS4DBG.cs
  class PS4DBG (line 11) | public partial class PS4DBG
    type CMDS (line 57) | public enum CMDS : uint
    type CMD_STATUS (line 102) | public enum CMD_STATUS : uint
    type CMDPacket (line 112) | [StructLayout(LayoutKind.Sequential, Pack = 1)]
    type VM_PROTECTIONS (line 121) | public enum VM_PROTECTIONS : uint
    type WATCHPT_LENGTH (line 133) | public enum WATCHPT_LENGTH : uint
    type WATCHPT_BREAKTYPE (line 140) | public enum WATCHPT_BREAKTYPE : uint
    method ConvertASCII (line 148) | private static string ConvertASCII(byte[] data, int offset)
    method SubArray (line 158) | public static byte[] SubArray(byte[] data, int offset, int length)
    method GetObjectFromBytes (line 164) | public static object GetObjectFromBytes(byte[] buffer, Type type)
    method GetBytesFromObject (line 177) | private static byte[] GetBytesFromObject(object obj)
    method GetBroadcastAddress (line 193) | private static IPAddress GetBroadcastAddress(IPAddress address, IPAddr...
    method SendCMDPacket (line 206) | private void SendCMDPacket(CMDS cmd, int length, params object[] fields)
    method SendData (line 269) | private void SendData(byte[] data, int length)
    method ReceiveData (line 292) | private byte[] ReceiveData(int length)
    method ReceiveStatus (line 313) | private CMD_STATUS ReceiveStatus()
    method CheckStatus (line 319) | private void CheckStatus()
    method CheckConnected (line 328) | private void CheckConnected()
    method CheckDebugging (line 335) | private void CheckDebugging()
    method PS4DBG (line 344) | public PS4DBG()
    method PS4DBG (line 354) | public PS4DBG(IPAddress addr)
    method PS4DBG (line 364) | public PS4DBG(string ip)
    method FindPlayStation (line 383) | public static string FindPlayStation()
    method Connect (line 421) | public void Connect()
    method Disconnect (line 439) | public void Disconnect()
    method GetLibraryDebugVersion (line 450) | public string GetLibraryDebugVersion()
    method GetConsoleDebugVersion (line 458) | public string GetConsoleDebugVersion()

FILE: libdebug/Process.cs
  class Process (line 5) | public class Process
    method Process (line 16) | public Process(string name, int pid)
    method ToString (line 21) | public override string ToString()
  class ProcessList (line 27) | public class ProcessList
    method ProcessList (line 38) | public ProcessList(int number, string[] names, int[] pids)
    method FindProcess (line 53) | public Process FindProcess(string name, bool contains = false)
  class MemoryEntry (line 77) | public class MemoryEntry
    method ToString (line 85) | public override string ToString()
  class ProcessMap (line 91) | public class ProcessMap
    method ProcessMap (line 102) | public ProcessMap(int pid, MemoryEntry[] entries)
    method FindEntry (line 114) | public MemoryEntry FindEntry(string name, bool contains = false)
    method FindEntry (line 142) | public MemoryEntry FindEntry(ulong size)
  type ProcessInfo (line 156) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
  type ThreadInfo (line 174) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]

FILE: libdebug/Registers.cs
  type regs (line 5) | [StructLayout(LayoutKind.Sequential, Pack = 1)]
  type envxmm (line 36) | [StructLayout(LayoutKind.Sequential)]
  type acc (line 50) | [StructLayout(LayoutKind.Sequential)]
  type xmmacc (line 60) | [StructLayout(LayoutKind.Sequential)]
  type ymmacc (line 67) | [StructLayout(LayoutKind.Sequential)]
  type xstate_hdr (line 74) | [StructLayout(LayoutKind.Sequential)]
  type savefpu_xstate (line 84) | [StructLayout(LayoutKind.Sequential)]
  type fpregs (line 92) | [StructLayout(LayoutKind.Sequential, Pack = 64)]
  type dbregs (line 105) | [StructLayout(LayoutKind.Sequential, Pack = 1)]

FILE: offsets.cs
  class offsets (line 7) | class offsets

FILE: structs.cs
  type SceSaveDataMount (line 5) | [StructLayout(LayoutKind.Explicit, Size = 80)]
  type SceSaveDataMount2 (line 16) | [StructLayout(LayoutKind.Explicit, Size = 64)]
  type SceSaveDataMountResult (line 24) | [StructLayout(LayoutKind.Explicit, Size = 64)]
  type SceSaveDataMountPoint (line 33) | [StructLayout(LayoutKind.Sequential, Size = 16)]
  type SceSaveDataTransferringMount (line 40) | [StructLayout(LayoutKind.Sequential, Size = 64)]
  type SceSaveDataTitleId (line 49) | [StructLayout(LayoutKind.Sequential, Size = 16)]
  type SceSaveDataDirName (line 55) | [StructLayout(LayoutKind.Sequential, Size = 32)]
  type SceSaveDataFingerprint (line 61) | [StructLayout(LayoutKind.Sequential, Size = 80)]
  type SceSaveDataDirNameSearchCond (line 67) | [StructLayout(LayoutKind.Explicit, Size = 64)]
  type SceSaveDataDirNameSearchResult (line 76) | [StructLayout(LayoutKind.Explicit, Size = 56)]
  type SceSaveDataParam (line 86) | [StructLayout(LayoutKind.Explicit, Size = 1328)]
  type SceSaveDataSearchInfo (line 98) | [StructLayout(LayoutKind.Sequential, Size = 48)]
Condensed preview — 18 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (138K chars).
[
  {
    "path": ".gitignore",
    "chars": 5582,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## G"
  },
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2018 ChendoChap\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "Main.Designer.cs",
    "chars": 21304,
    "preview": "namespace PS4Saves\n{\n    partial class Main\n    {\n        /// <summary>\n        /// Required designer variable.\n       "
  },
  {
    "path": "Main.cs",
    "chars": 25739,
    "preview": "using libdebug;\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO;\nusing Syst"
  },
  {
    "path": "PS4Saves.csproj",
    "chars": 2885,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "Program.cs",
    "chars": 457,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Windows.Forms;\n\nnamespace PS4Saves\n{\n    static class Prog"
  },
  {
    "path": "Properties/AssemblyInfo.cs",
    "chars": 1420,
    "preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
  },
  {
    "path": "README.md",
    "chars": 4703,
    "preview": "# Playstation 4 Save Mounter 1.5\n\n## Summary\nThis program allows you to mount save data with RW permission and a lot mor"
  },
  {
    "path": "functions.cs",
    "chars": 3693,
    "preview": "namespace PS4Saves\n{\n    internal static class functions\n    {\n        internal static byte[] GetSaveDirectories =\n    "
  },
  {
    "path": "libdebug/PS4DBG.Console.cs",
    "chars": 1735,
    "preview": "using System.Text;\n\nnamespace libdebug\n{\n    public partial class PS4DBG\n    {   \n        //console\n        // packet si"
  },
  {
    "path": "libdebug/PS4DBG.Debug.cs",
    "chars": 13269,
    "preview": "using System;\nusing System.Net;\nusing System.Net.Sockets;\nusing System.Runtime.InteropServices;\nusing System.Threading;\n"
  },
  {
    "path": "libdebug/PS4DBG.Kernel.cs",
    "chars": 1670,
    "preview": "using System;\n\nnamespace libdebug\n{\n    public partial class PS4DBG\n    {\n        // kernel\n        //packet sizes\n     "
  },
  {
    "path": "libdebug/PS4DBG.Proc.cs",
    "chars": 21266,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Net.Sockets;\nusing System.Runtime.InteropS"
  },
  {
    "path": "libdebug/PS4DBG.cs",
    "chars": 15036,
    "preview": "using System;\nusing System.IO;\nusing System.Net;\nusing System.Net.Sockets;\nusing System.Runtime.InteropServices;\nusing S"
  },
  {
    "path": "libdebug/Process.cs",
    "chars": 4981,
    "preview": "using System.Runtime.InteropServices;\n\nnamespace libdebug\n{\n    public class Process\n    {\n        public string name;\n "
  },
  {
    "path": "libdebug/Registers.cs",
    "chars": 3568,
    "preview": "using System.Runtime.InteropServices;\n\nnamespace libdebug\n{\n    [StructLayout(LayoutKind.Sequential, Pack = 1)]\n    publ"
  },
  {
    "path": "offsets.cs",
    "chars": 543,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace PS4Saves\n{\n    class offsets\n    {\n      "
  },
  {
    "path": "structs.cs",
    "chars": 3506,
    "preview": "using System.Runtime.InteropServices;\n\nnamespace PS4Saves\n{\n    [StructLayout(LayoutKind.Explicit, Size = 80)]\n    publ"
  }
]

About this extraction

This page contains the full source code of the ChendoChap/Playstation-4-Save-Mounter GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 18 files (129.3 KB), approximately 31.7k tokens, and a symbol index with 146 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!