Category PS4 Guides and Tutorials       Thread starter PSXHAX       Start date Feb 6, 2018 at 9:15 AM       75,076       250            
Recently @stooged lent a hand sharing both details with source code on Backing Up and Restoring the PS4 Database, and he followed up with a handy DbBackup.bin Payload compiled for PS4 4.05 OFW users to backup their PlayStation 4 database to a USB Drive alongside one for dumping save data below. :love:

Download: DbBackup.zip / Source Code / DB_SG_Backup.zip (8.79 KB - dumps save data into a folder called GameSaves) / DB_SG_Backup_v2.zip (8.27 KB - Dumps All User Accounts) / DB_SG_Backup3.zip (8.82 KB - Adds Notification Messages from 2much4u) / DB_Backup_455.zip (Updated for 4.55) / usb_455_db_backup.zip (0.02 MB) / Cache-Install: ApplicationCache.db

To quote from his recent post with usage instructions:

just put a usb stick/drive into the usb port and run the DbBackup.bin payload

it will save the addcont.db and app.db files inside a folder called DB_Dackup on the usb drive.

if you do not use a usb stick/drive it will backup the database into the /system_data/priv/mms/ folder on the ps4 and it will be called app.db_backup.

to restore the db just ftp into the /system_data/priv/mms/ directory and upload your backup copy.

credit to @XVortex for the neat way to check which usb port has the drive in it in their ps4dumper source, I tried a few other things with no decent result but @XVortex had a simple method to do the trick :)

DbBackup.bin Payload Backup PS4 Database to USB Drive by Stooged.jpg
 

Comments

stooged

Developer
Senior Member
Contributor
I have been playing around with trying to dump the saved games and have come up with this so far

once again thanks to xvortex, i am not very fluent with c code so your source for the dumper and other things on your GitHub have been a great learning tool for me.

DB_SG_Backup.zip (8.79 KB)

the payload will dump the save data into a folder called GameSaves on the usb drive and it will retain the directory structure it was dumped from.

depending on how many saves you have it may take a while to dump so once you run the payload just wait until the message displays asking you to close the browser.

this might not work for you at all as I only have one ps4 to work with so its trial and error

to restore you can try putting the files in the following folders over ftp.

the savedata.db database is in this directory /system_data/savedata/XXXXXXXX/db/user/

the save data is in this directory /user/home/XXXXXXXX/savedata/ each game is sorted into its own folder by titleid
there is also /user/home/XXXXXXXX/savedata_meta/

this might not restore the saves inside the ps4 and they might not persist through a format as sony might have them locked to keys for each console so you cant share them I don't know to be honest.

i will keep playing around with it anyway, with any luck they are as easy to fix as the database was.
 

sabasoor

Senior Member
Contributor
OK @stooged here is my result
I used the payload and it did dump the files
but what i have noticed that it dumped files they don't exist in my user (user2)
from what i saw it dumped only the files from User1 although i run the payload from User2 and all my data is there ...

I'll try to do it again later and i hope u find a way to run old or others game saves
thanks for the payload I believe it will come up handy :D
 

stooged

Developer
Senior Member
Contributor
ok @sabasoor you were right it only did 1 user

because I was making it focus on the save data before it only dumped one user but now I have made it just dump the entire users folders including bookmarks and trophy data.

it should now dump all user accounts

DB_SG_Backup_v2.zip
 

Rashboi91

Member
Contributor
FYI all, the only time my system did a database rebuild was a kpanic while installing a pkg. As I understand, the system does a check on the filesystem and repairs the application database only when the application database is corrupted.

Most of the time, my slim only kpanics after an unstable leak by ps4hen. Sometimes is just after closing the browser, sometimes is launching the first "locked" app. These crashes go nice on the application database.
 

SigobaraIgopipa

Senior Member
Contributor
Okay, thanx a lot but can you clarify:

Does DB_SG_Backup.zip dump only user data, SGs AND database, or only the first two? If so what is the difference between DB_SG_Backup.zip and DbBackup.zip???

The 1st zippy link in the 1st post is dead. Also I cannot run the DB Backup through the User Guide browser, using Al Azif's web host. Any ideas why?

I ran the xvortex HEN on my PS4, then on my PC in the command prompt window I selected the db_backup payload to be send, and my PS4 is not stuck to a blue screen and is stuck restarting for 15 minutes. Help please.

Update: I pulled the power cord and luckily the console is working fine again. I will not use this payload until it gets an update.
 

stooged

Developer
Senior Member
Contributor
the [U]DbBackup.zip[/U] just backs up the app.db

the DB_SG_Backup.zip is broken and should be removed and not used.

the [U]DB_SG_Backup_v2.zip[/U] dumps the app.db and the save games data.

you don't run hen to run the backup payload you just run the backup payload.

all you do is put a usb drive into the ps4 > load idc exploit > select backup payload and wait until the ps4 shows message asking to close browser.


Update: added the notification messages from 2much4u.

this will show a message when the backup is done so you can hide the browser window while backup is being executed.

DB_SG_Backup_v3

https://pastebin.com/q5BRKeTF
Code:
#include "ps4.h"


unsigned int long long __readmsr(unsigned long __register) {
   unsigned long __edx;
   unsigned long __eax;
   __asm__ ("rdmsr" : "=d"(__edx), "=a"(__eax) : "c"(__register));
   return (((unsigned int long long)__edx) << 32) | (unsigned int long long)__eax;
}

#define X86_CR0_WP (1 << 16)

static inline __attribute__((always_inline)) uint64_t readCr0(void) {
   uint64_t cr0;
  
   asm volatile (
       "movq %0, %%cr0"
       : "=r" (cr0)
       : : "memory"
    );
  
   return cr0;
}

static inline __attribute__((always_inline)) void writeCr0(uint64_t cr0) {
   asm volatile (
       "movq %%cr0, %0"
       : : "r" (cr0)
       : "memory"
   );
}

struct auditinfo_addr {
   char useless[184];
};

struct ucred {
   uint32_t useless1;
   uint32_t cr_uid;     // effective user id
   uint32_t cr_ruid;    // real user id
    uint32_t useless2;
       uint32_t useless3;
       uint32_t cr_rgid;    // real group id
       uint32_t useless4;
       void *useless5;
       void *useless6;
       void *cr_prison;     // jail(2)
       void *useless7;
       uint32_t useless8;
       void *useless9[2];
       void *useless10;
       struct auditinfo_addr useless11;
       uint32_t *cr_groups; // groups
       uint32_t useless12;
};

struct filedesc {
   void *useless1[3];
       void *fd_rdir;
       void *fd_jdir;
};

struct proc {
       char useless[64];
       struct ucred *p_ucred;
       struct filedesc *p_fd;
};

struct thread {
       void *useless;
       struct proc *td_proc;
};


int kpayload(struct thread *td){

   struct ucred* cred;
   struct filedesc* fd;

   fd = td->td_proc->p_fd;
   cred = td->td_proc->p_ucred;

   void* kernel_base = &((uint8_t*)__readmsr(0xC0000082))[-0x30EB30];
   uint8_t* kernel_ptr = (uint8_t*)kernel_base;
   void** got_prison0 =   (void**)&kernel_ptr[0xF26010];
   void** got_rootvnode = (void**)&kernel_ptr[0x206D250];

   cred->cr_uid = 0;
   cred->cr_ruid = 0;
   cred->cr_rgid = 0;
   cred->cr_groups[0] = 0;

   cred->cr_prison = *got_prison0;
   fd->fd_rdir = fd->fd_jdir = *got_rootvnode;

   // escalate ucred privs, needed for access to the filesystem ie* mounting & decrypting files
   void *td_ucred = *(void **)(((char *)td) + 304); // p_ucred == td_ucred
  
   // sceSblACMgrIsSystemUcred
   uint64_t *sonyCred = (uint64_t *)(((char *)td_ucred) + 96);
   *sonyCred = 0xffffffffffffffff;
  
   // sceSblACMgrGetDeviceAccessType
   uint64_t *sceProcType = (uint64_t *)(((char *)td_ucred) + 88);
   *sceProcType = 0x3801000000000013; // Max access
  
   // sceSblACMgrHasSceProcessCapability
   uint64_t *sceProcCap = (uint64_t *)(((char *)td_ucred) + 104);
   *sceProcCap = 0xffffffffffffffff; // Sce Process

   // Disable write protection
   uint64_t cr0 = readCr0();
   writeCr0(cr0 & ~X86_CR0_WP);

   // specters debug settings patchs
   *(char *)(kernel_base + 0x2001516) |= 0x14;
   *(char *)(kernel_base + 0x2001539) |= 3;
   *(char *)(kernel_base + 0x200153A) |= 1;
   *(char *)(kernel_base + 0x2001558) |= 1;  

   // debug menu full patches thanks to sealab
   *(uint32_t *)(kernel_base + 0x4CECB7) = 0;
   *(uint32_t *)(kernel_base + 0x4CFB9B) = 0;

   // Target ID Patches :)
   *(uint16_t *)(kernel_base + 0x1FE59E4) = 0x8101;
   *(uint16_t *)(kernel_base + 0X1FE5A2C) = 0x8101;
   *(uint16_t *)(kernel_base + 0x200151C) = 0x8101;

   // enable mmap of all SELF ???
   *(uint8_t*)(kernel_base + 0x31EE40) = 0x90;
   *(uint8_t*)(kernel_base + 0x31EE41) = 0xE9;
   *(uint8_t*)(kernel_base + 0x31EF98) = 0x90;
   *(uint8_t*)(kernel_base + 0x31EF99) = 0x90;

   // Restore write protection
   writeCr0(cr0);

   return 0;
}

double(*ceil)(double x);
int(*sceSysUtilSendSystemNotificationWithText)(int messageType, char* message);

void systemMessage(char* msg) {
   sceSysUtilSendSystemNotificationWithText(222, msg);
}


void copyFile(char *sourcefile, char* destfile)
{
   FILE *src = fopen(sourcefile, "rb");
   if (src)
   {
       FILE *out = fopen(destfile,"wb");
       if (out)
       {
           size_t bytes;
           char *buffer = malloc(65536);
           if (buffer != NULL)
           {
               while (0 < (bytes = fread(buffer, 1, 65536, src)))
                   fwrite(buffer, 1, bytes, out);
                   free(buffer);
           }
           fclose(out);
       }
       else {
       }
       fclose(src);
   }
   else {
   }
}



void copyDir(char *sourcedir, char* destdir)
{
   DIR *dir;
   struct dirent *dp;
   struct stat info;
   char src_path[1024], dst_path[1024];

   dir = opendir(sourcedir);
   if (!dir)
       return;
       mkdir(destdir, 0777);
   while ((dp = readdir(dir)) != NULL)
   {
       if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
       {}
       else
       {
           sprintf(src_path, "%s/%s", sourcedir, dp->d_name);
           sprintf(dst_path, "%s/%s", destdir  , dp->d_name);

           if (!stat(src_path, &info))
           {
               if (S_ISDIR(info.st_mode))
               {
                 copyDir(src_path, dst_path);
               }
               else
               if (S_ISREG(info.st_mode))
               {
                 copyFile(src_path, dst_path);
               }
           }
       }
   }
   closedir(dir);
}





int _main(struct thread *td) {
   initKernel();
   initLibc();

   DIR *dir;
   dir = opendir("/system_data/savedata");
   if (!dir)
   {
      syscall(11,kpayload,td);
   }
   else
   {
      closedir(dir);
   }

       int sysUtil = sceKernelLoadStartModule("/system/common/lib/libSceSysUtil.sprx", 0, NULL, 0, 0, 0);
       RESOLVE(sysUtil, sceSysUtilSendSystemNotificationWithText);

       FILE *usbdir = fopen("/mnt/usb0/.dirtest", "wb");
  
        if (!usbdir)
           {
               usbdir = fopen("/mnt/usb1/.dirtest", "wb");
               if (!usbdir)
               {
                          copyFile("/system_data/priv/mms/app.db", "/system_data/priv/mms/app.db_backup");
                       copyFile("/system_data/priv/mms/addcont.db", "/system_data/priv/mms/addcont.db_backup");
                       systemMessage("Internal backup complete.\nThis was only a database backup use a usb drive for full backup.");
                       return 0;
               }
               else
               {
                       fclose(usbdir);
                       systemMessage("Backing up to USB1");
                       unlink("/mnt/usb1/.dirtest");
                       mkdir("/mnt/usb1/DB_Dackup/", 0777);
                       copyFile("/system_data/priv/mms/app.db", "/mnt/usb1/DB_Dackup/app.db");
                       copyFile("/system_data/priv/mms/addcont.db", "/mnt/usb1/DB_Dackup/addcont.db");
                       mkdir("/mnt/usb1/GameSaves/", 0777);
                       mkdir("/mnt/usb1/GameSaves/system_data/", 0777);
                       mkdir("/mnt/usb1/GameSaves/system_data/savedata", 0777);
                       mkdir("/mnt/usb1/GameSaves/user/", 0777);
                       mkdir("/mnt/usb1/GameSaves/user/home/", 0777);
                       copyDir("/system_data/savedata","/mnt/usb1/GameSaves/system_data/savedata");
                       copyDir("/user/home", "/mnt/usb1/GameSaves/user/home");
                       systemMessage("USB Backup Complete.");

               }
           }
           else
           {
                       fclose(usbdir);
                       systemMessage("Backing up to USB0");
                       unlink("/mnt/usb0/.dirtest");
                       mkdir("/mnt/usb0/DB_Dackup/", 0777);
                       copyFile("/system_data/priv/mms/app.db", "/mnt/usb0/DB_Dackup/app.db");
                       copyFile("/system_data/priv/mms/addcont.db", "/mnt/usb0/DB_Dackup/addcont.db");
                       mkdir("/mnt/usb0/GameSaves/", 0777);
                       mkdir("/mnt/usb0/GameSaves/system_data/", 0777);
                       mkdir("/mnt/usb0/GameSaves/system_data/savedata", 0777);
                       mkdir("/mnt/usb0/GameSaves/user/", 0777);
                       mkdir("/mnt/usb0/GameSaves/user/home/", 0777);
                       copyDir("/system_data/savedata","/mnt/usb0/GameSaves/system_data/savedata");
                       copyDir("/user/home", "/mnt/usb0/GameSaves/user/home");
                       systemMessage("USB Backup Complete.");
           }

   return 0;
}
 

wa7ly

Member
Contributor
has anyone tried to manually add games to the database? I had a moment of stupid and didnt back up my database and performed a rebuild.....so I lost all my games on the system menu but I do see them under /users/app/ and wanted to add them back without going through the process of reinstalling the packages. Has anyone tried a manual sql edit and added games manually?
 

sabasoor

Senior Member
Contributor
@stooged
1- I have a game on an original disk i played it for 30 minutes saved the game
2- I used your tool DB_SG_Backup to dump all the files
3- deleted the original disk of the game and the saves date from my ps4
4- Used the dumped version of the same game i was playing( i dumped it just to test the save game ) and installed it 5- restored the files that i dumped using your ftp but it showed me that the game save is corrupted

so what i did after that i created a new user to get clear and new data from my ps4, i played the game again with the hacked (dumped) version for 30 minutes ,too. on the new user., after that i dumped the save gain from the new user

I tried my best to see what has changed between the save game data from original disk and the save game data from the hacked one.but nothing im no dev maybe u can come up with something
 
Recent Articles
Sony Confirms PS5 Will Support PlayStation Now, New Controller Patent
In a recent interview with Famitsu Magazine, Sony's Yasuhiro Osaki confirmed that PlayStation 5 will support their digital streaming and downloading video game subscription service PlayStation...
PS4 Patch Builder for Building Modded Update PKGs by MODDED WARFARE
Since his YouTube Issues PlayStation 4 homebrew developer @MODDEDWARFARE returns releasing on Twitter a PS4 Patch Builder application used for building modded Update Packages (PKGs) alongside a...
PS Vita System Software / Firmware 3.73 is Live, Don't Update!
Trick or treat?! šŸŽƒ Since their previous PS Vita OFW revision, today Sony pushed live a PlayStation Vita System Software / Firmware 3.73 Update leaving many curious if they patched the H-Encore 2...
PlayStation Store Halloween Sale Now Live, PSN Game Deals Up to Half Off
The month is already half over and Halloween 2019 is quickly approaching as Sony unleashes their latest PlayStation Store Halloween Sale featuring PSN game deals at up to 50% off on select titles...
Top