Join Us and become a Member for a Verified Badge to access private areas with the latest PS4 PKGs.
PS4 Jailbreaking       Thread starter PSXHAX       Start date Jan 16, 2018 at 9:55 PM       93      
Status
Not open for further replies.
Recently we saw the release of a PS4 4.05 Kernel Exploit, which lit up the scene bringing cool stuff like 4.05 PS4 Linux followed by Flat_z's Writeup, IDC's PS4Fake405, a Fake PKG Generator and now confirmation that homebrew on PlayStation 4 v4.05 Firmware is a thing now! <3

To kick off the 4.05 PS4 homebrew scene PlayStation 4 developer @zecoxao shared some handy payloads and a "Hello World, PS4!" Test Application (testapp.pkg) on Twitter, which some including @GritNGrind already took for a test drive! ;)

Download: fake_installer.bin (1.0 MB - kernel_hooks Payload) / hostapp_launch_patcher.bin (1.0 MB - ShellCore Patches IP is 192.168.0.4) / testapp.pkg (7.1 MB) / PS4HEN.bin (1.00 MB)

There are still some hoops to jump through before a user-friendly method to make PS4 backup games playable on 4.05 OFW is available which we'll discuss below, and these patches can also be added to the 4.05 PS4 Exploit so end-users will then be able to just run the exploit after each reboot to apply them.

Here's a summary of what's known thus far with the related Tweets, as follows:

ok, to start, shellcore patches from flatz write up need to be implemented here:
Code:
#include "ps4.h"

#include <assert.h>

#define DEBUG_SOCKET
#include "defines.h"

int find_process(const char* target)
{
  int pid;
  int mib[3] = {1, 14, 0};
  size_t size, count;
  char* data;
  char* proc;

  if (sysctl(mib, 3, NULL, &size, NULL, 0) < 0)
  {
   return -1;
  }

  if (size == 0)
  {
   return -2;
  }

  data = (char*)malloc(size);
  if (data == NULL)
  {
   return -3;
  }

  if (sysctl(mib, 3, data, &size, NULL, 0) < 0)
  {
   free(data);
   return -4;
  }

  count = size / 0x448;
  proc = data;
  pid = -1;
  while (count != 0)
  {
   char* name = &proc[0x1BF];
   if (strncmp(name, target, strlen(target)) == 0)
   {
     pid = *(int*)(&proc[0x48]);
     break;
   }
   proc += 0x448;
   count--;
  }

  free(data);
  return pid;
}

int get_code_info(int pid, uint64_t* paddress, uint64_t* psize, uint64_t known_size)
{
  int mib[4] = {1, 14, 32, pid};
  size_t size, count;
  char* data;
  char* entry;

  if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0)
  {
   return -1;
  }

  if (size == 0)
  {
   return -2;
  }

  data = (char*)malloc(size);
  if (data == NULL)
  {
   return -3;
  }

  if (sysctl(mib, 4, data, &size, NULL, 0) < 0)
  {
   free(data);
   return -4;
  }

  int struct_size = *(int*)data;
  count = size / struct_size;
  entry = data;

  int found = 0;
  while (count != 0)
  {
   int type = *(int*)(&entry[0x4]);
   uint64_t start_addr = *(uint64_t*)(&entry[0x8]);
   uint64_t end_addr = *(uint64_t*)(&entry[0x10]);
   uint64_t code_size = end_addr - start_addr;
   uint32_t prot = *(uint32_t*)(&entry[0x38]);

   printfsocket("%d %llx %llx (%llu) %x\n", type, start_addr, end_addr, code_size, prot);

   if (type == 255 && prot == 5 && code_size == known_size)
   {
     *paddress = start_addr;
     *psize = (end_addr - start_addr);
     found = 1;
     break;
   }

   entry += struct_size;
   count--;
  }

  free(data);
  return !found ? -5 : 0;
}

typedef struct _patch_info
{
  const char* name;
  uint32_t address;
  const char* data;
  uint32_t size;
}
patch_info;

int apply_patches(int pid, uint64_t known_size, patch_info* patches)
{
  uint64_t code_address, code_size;
  int result = get_code_info(pid, &code_address, &code_size, known_size);
  if (result < 0)
  {
   printfsocket("Failed to get code info for %d: %d\n", pid, result);
   return -1;
  }

  char proc_path[64];
  sprintf(proc_path, "/mnt/proc/%d/mem", pid);

  int fd = open(proc_path, O_RDWR, 0);
  if (fd < 0)
  {
   printfsocket("Failed to open %s!\n", proc_path);
   return -2;
  }

  printfsocket("Opened process memory...\n");
  for (int i = 0; patches[i].name != NULL; i++)
  {
   lseek(fd, code_address + patches[i].address, SEEK_SET);
   result = write(fd, patches[i].data, patches[i].size);
   printfsocket("patch %s: %d %d\n", patches[i].name, result, result < 0 ? errno : 0);
  }

  close(fd);
  return 0;
}

int mount_procfs()
{
  int result = mkdir("/mnt/proc", 0777);
  if (result < 0 && (*__error()) != 17)
  {
   printfsocket("Failed to create /mnt/proc\n");
   return -1;
  }

  result = mount("procfs", "/mnt/proc", 0, NULL);
  if (result < 0)
  {
   printfsocket("Failed to mount procfs: %d\n", result, *__error());
   return -2;
  }

  return 0;
}

patch_info shellcore_patches[32] =
{
  //{ "Enable Logging",                               0xF9664E, "\x00", 1 },
  //{ "Enable Logging",                               0xF9664E, "\x01", 1 },

  { "Allow WebProcess LaunchApp #1",                0x28CE09, "\x90\xE9", 2 },
  { "Allow WebProcess LaunchApp #2",                0x28D02A, "\x90\xE9", 2 },
  { "Allow WebProcess LaunchApp #3",                0x28D0E0, "\xEB", 1 },

  { "Enable Development Mounts",                    0x276A83, "\xEB", 1 },

  { NULL, 0, NULL, 0 },
};

/*
patch_info syscore_patches[32] =
{
  { "Enable printf",                  0x161A5, "\x90\x90", 2 },
  { "Change printf argument",         0x161CA, "\x8B\x73\x64", 3 },
  { "Change printf format",           0x936A7, "\nexecve error = %x\n", 19 },
  { NULL, 0, NULL, 0 },
};
*/

void do_patch()
{
  int result;

  int shell_pid = find_process("SceShellCore");
  if (shell_pid < 0)
  {
   printfsocket("Failed to find SceShellCore: %d\n", shell_pid);
   return;
  }
  printfsocket("Found SceShellCore at pid %d!\n", shell_pid);

  /*
  int sys_pid = find_process("SceSysCore");
  if (sys_pid < 0)
  {
   printfsocket("Failed to find SceSysCore: %d\n", sys_pid);
   return;
  }
  printfsocket("Found SceSysCore at pid %d!\n", sys_pid);
  */

  result = mount_procfs();
  if (result)
  {
   return;
  }

  printfsocket("Patching SceShellCore...\n");
  apply_patches(shell_pid, 0xF18000, shellcore_patches);
  //printfsocket("Patching SceSysCore...\n");
  //apply_patches(sys_pid, 0xC4000, syscore_patches);
}
payload needs to be compiled and patches will be applied after that. as for the kernel_hooks payload, here it is (linked above)
reminder that you need both this payload and the shellcore patches payload in order to install a pkg with homebrew on it
also, please test if everything is working with this pkg (linked above)
if everything is working properly, you should see font sample onscreen
If you see a screen that looks like this, recheck (or recompile) the ShellCore Patches payload:
Hello World, PS4! Homebrew on 4.05 Firmware & Test Application PKG 2.jpg

to your pc's ip yes.
it's inside the payload. starts with c0 a8 which is hex for 192 168

So in summary, if you use both payloads and set your IP properly in the payload then run the testapp.pkg you should see a PS4 4.05 homebrew font screen that looks like this:

Hello World, PS4! Homebrew on 4.05 Firmware & Test Application PKG 4.jpg

Which differs slightly from VVildCard777's example earlier on as he added the "Hello world, PS4!" text:

Hello World, PS4! Homebrew on 4.05 Firmware & Test Application PKG 3.jpg

:arrow: Update: @mschumacher69 confirmed HERE first the blue screen is displayed and then the black screen (with the added font) for those curious about the two different screen pictures above with a guide HERE for those interested.
latest code so far. still needs to separate fpkg from fself, add debug settings and add shellcore patches
updated with shellcore patches and kernel patches. please report if it works.
if you see Test Application on blue bg it means that patches are not done correctly, it's just a png from sce_sys/, so called overlay that is shown until app started execution, white text on black bg should be if everything is okay
Regarding running PS4 game backups on 4.05 OFW, @Progamerxx in the PSXHAX Shoutbox reminded us of the following points:
  • Just straight forward installing a PKG and running it won't work.
  • You still need to dump the game, make a fake self and fpkg.
  • After that inject payload and then you can install and run the game.
  • So it might take a while for it to become userfriendly.
:arrow: Update #2: PS4HEN.bin (1.00 MB) is now available via VVildCard777 with a link to the PS4HEN Github now live... and PlayStation 4 game backups are playable on 4.05 Firmware, see the link below for the first Game Dump PKG that has surfaced alongside a guide! :D
Running Homebrew & Fake PKGs On 4.05 (PS4 Jailbreak)
Download: helloworld.pkg (5.88 MB)

Thanks to @LightningMods (for the background pic), @Plankton, @prreis and @SSShowmik for the initial news tips in the PSXHAX Shoutbox tonight as the 4.05 scene continues to get lit af!!! :fire:
Hello World, PS4! Homebrew on 4.05 Firmware & Test Application PKG.jpg
 

Comments

Thanks for the nice overview @PSXHAX , the thread on twitter could not be viewed as nice as this. ;)

Aside from that, it's very nice how the PS4 scene has developed in the past months. This actually motivated me to start learning some C. Waiting for an updated *** now while still improving my skills :) Someday (may as far as the PS5 Jailbreak) I'd like to contribute some senseful homebrew.

And the devs sharing so much knowledge is incredible! Those many write ups by f0f, flat_z and Specter are so well written and detailed.

This method obviously isn't user-friendly, but I could think of a script (some devs with more Python(/scripting) knowledge please correct me) to make the process of creating fself + fpkg user-friendlier, with already given code.

The future of the PS4 Jailbreaking scene just have to be bright! :bananaman:
 
Status
Not open for further replies.
Back
Top