obhq / obliteration

Experimental free and open-source PlayStation 4 kernel
https://obliteration.net
Apache License 2.0
628 stars 18 forks source link

Failed to load libSceFios2.prx #527

Closed SuchAFuriousDeath closed 6 months ago

SuchAFuriousDeath commented 10 months ago
image

Basically almost all games (if not all) fail to load this library. Some before syscall 653 and the dmem ioctl, some after.

ultimaweapon commented 10 months ago

We are missing something before this one. The game should be in chroot or jailed first so its root is not the root of FS.

SuchAFuriousDeath commented 10 months ago

Where would that change something?

SuchAFuriousDeath commented 10 months ago

More context here:

image
ultimaweapon commented 10 months ago

I really have no idea for now. Those logs are for game developer to tell them they need to copy some files to app0/sce_module, it have nothing to do with us.

SuchAFuriousDeath commented 10 months ago

https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain/issues/62#issuecomment-665845071

image
ultimaweapon commented 10 months ago

I think I figured out the first part how this thing is working. The game start in chroot to /mnt/sandbox/{id}_000, which will cause syscall 585 to return 1 because the root of the game is not root FS. Then #375 will be called to get the path of system directory within the chroot path. So the filesystem the game see is something like:

/app0/eboot.bin
/RANDOMIZED_PATH/common/lib/libkernel.sprx

The problem is, how the game is able to access /dev in this case?

ultimaweapon commented 10 months ago

@VocalFan can you check what is inside /mnt/sandbox/{id}_000 when the game is running?

VocalFan commented 10 months ago

Alright

VocalFan commented 10 months ago
/app0 = Game contents (eboot, sce_sys, sce_module, game-data)
/av_contents = Symlink to root of disk's /user/av_contents folder
/c45DSN6z4l = System files, name is randomly generated (symlink to /system/common, common_temp (Which is just voice and agent TTS_cache, sqlite)
/data = Symlink to root of disk's /data folder
/dev = Response: 451 Requested action aborted. Local error in processing. | Error: Failed to retrieve directory listing
/host = Symlink to root of disk's /host folder.
/hostapp = Symlink to root of disk's /hostapp folder.
/system_tmp = Symlink to root of disk's /system_tmp folder.

So, the folder for system files in CUSA_000 IS randomized:

First launch: c45DSN6z4I Second launch: QXuNNl0Zhn

VocalFan commented 10 months ago

@ultimaweapon Just to make sure this pings ya ^

Also, upgraded my PS4 from an HDD to an SSD, feels way better :P

ultimaweapon commented 10 months ago

Strange. Normally the symbolic link does not work if the destination file is outside the chroot.

ultimaweapon commented 10 months ago

Another problem is the filesystem is exFAT, which does not support a symbolic link.

VocalFan commented 10 months ago

If its not a symlink, then idk what, as when I double click those folders in the CUSA_app0, I get a duplicate of what that folder would be on root.

ultimaweapon commented 10 months ago

I guess we need to check SceSysCore to see how this thing is working.

VocalFan commented 10 months ago

I guess we need to check SceSysCore to see how this thing is working.

I however do think the dev folder in CUSA_app0 is different than the dev folder on the root of the drive, seeing as I can access the root drive's Dev folder, but the game's Dev folder returns that error. Response: 451 Requested action aborted. Local error in processing. | Error: Failed to retrieve directory listing

SuchAFuriousDeath commented 10 months ago

@ultimaweapon Could devfs be initially mounted on the game's directory?

ultimaweapon commented 10 months ago

If you mean we just do that without understanding how those directors end up there then we should do that as a last resort. We should try to understand how the PS4 works as much as possible while we are reimplementing it. All of the information we gathered will come in handy later on when we hit any obstacles.

SuchAFuriousDeath commented 10 months ago

No, I was just throwing around ideas about how the PS4 does it, I wasn't suggesting that we just blindly 'guess'. Obviously, this is something we should get right,if we can.

SuchAFuriousDeath commented 10 months ago

By the way the Ghidra Orbis loader is absolutely amazing.

red-prig commented 10 months ago

Yes, these are not symbolic links, they are mounting folders, I assume that nullfs is used for mirroring folders

ultimaweapon commented 10 months ago

Seems like those folders are mounted by the other process then it send a command to SceSysCore to start the program.

ultimaweapon commented 10 months ago

Let's check mount list when the game is running to see if those folders are one of them.

ultimaweapon commented 10 months ago

@VocalFan can you run this payload when the game is running? It will create mount-list.txt on the root of USB drive, which contains a mount list.

dump-mntlist.zip

VocalFan commented 10 months ago

Better not break-

SuchAFuriousDeath commented 10 months ago

@ultimaweapon Have you found the vfs_mountroot function? Maybe you already have.

SuchAFuriousDeath commented 10 months ago

The start_init function also has some interesting things in it. Once you find vfs_mountroot, you can find it using function call trees.

SuchAFuriousDeath commented 10 months ago

Of course: vfs_mountroot can be found using the strings vfs_mountroot_conf0, because the function is inlined.

image
VocalFan commented 10 months ago

@VocalFan can you run this payload when the game is running? It will create mount-list.txt on the root of USB drive, which contains a mount list.

dump-mntlist.zip

Back from Christmas, will doooo

VocalFan commented 10 months ago

Better not break-

I can't believe you.

*The payload runner notifies me it ran the payload, but there is no error msg or output file.

SuchAFuriousDeath commented 10 months ago

By the way I tried rpcsx and after this, we'll most likely reach socketex, shm_open, evf_open, kqueue, /dev/rng, /dev/gc, evf_create and osem_create. Not necessarily in this order and not necessarily for all games.

SuchAFuriousDeath commented 10 months ago

Also, kern.fsst_param and thr_new.

ultimaweapon commented 10 months ago

Beware that some parts of RPCSX are licensed under GPL, which means we can't incorporate those codes.

SuchAFuriousDeath commented 10 months ago

I haven't looked at the code, I just looked at the output logs :D

VocalFan commented 9 months ago

Better not break-

I can't believe you.

*The payload runner notifies me it ran the payload, but there is no error msg or output file.

Uh, lmk if you find a fix or something @ultimaweapon

ultimaweapon commented 9 months ago

Better not break-

I can't believe you. *The payload runner notifies me it ran the payload, but there is no error msg or output file.

Uh, lmk if you find a fix or something @ultimaweapon

Try this one: dump-mntlist.zip

VocalFan commented 9 months ago

Same as before. "Payload received from 127.0.0.1" notif, then nothing.

ultimaweapon commented 9 months ago

No idea what wrong here. Here is the code is someone want to try:

#include <ps4.h>

struct fsid {
    int val[2];
};

struct statfs {
    unsigned f_version;
    unsigned f_type;
    long field2_0x8;
    long field3_0x10;
    long field4_0x18;
    long field5_0x20;
    long field6_0x28;
    long field7_0x30;
    long field8_0x38;
    long field9_0x40;
    long field10_0x48;
    long field11_0x50;
    long field12_0x58;
    long field13_0x60;
    long field14_0x68;
    long field15_0x70;
    long field16_0x78;
    long field17_0x80;
    long field18_0x88;
    long field19_0x90;
    long field20_0x98;
    long field21_0xa0;
    long field22_0xa8;
    long field23_0xb0;
    char field24_0xb8;
    char field25_0xb9;
    char field26_0xba;
    char field27_0xbb;
    int f_owner;
    struct fsid f_fsid;
    long field30_0xc8;
    long field31_0xd0;
    long field32_0xd8;
    long field33_0xe0;
    long field34_0xe8;
    long field35_0xf0;
    long field36_0xf8;
    long field37_0x100;
    long field38_0x108;
    long field39_0x110;
    char f_fstypename[16];
    char f_mntfromname[88];
    char f_mntonname[88];
};

_Static_assert(sizeof(struct statfs) == 0x1d8, "assert1");

int getfsstat(struct statfs *, size_t, int);

int _main(struct thread *td) {
    size_t len;
    struct statfs *buf;
    int res, i;
    FILE *fp;

    initKernel();
    initLibc();
    jailbreak();
    initSysUtil();

    // allocate buffer
    len = sizeof(*buf) * 128;
    buf = malloc(len);

    if (!buf) {
        printf_notification("Failed to allocate %u bytes of memory.", len);
        return 0;
    }

    // get mount list
    res = getfsstat(buf, len, 1);

    if (res < 0) {
        free(buf);
        printf_notification("Failed to get mount list.");
        return 0;
    }

    // write to usb drive
    fp = fopen("/mnt/usb0/mount-list.txt", "w");

    if (!fp) {
        free(buf);
        printf_notification("Failed to create /mnt/usb0/mount-list.txt.");
        return 0;
    }

    for (i = 0; i < res; i++) {
        struct statfs *s = buf + i;

        fprintf(fp, "%s\t%s\t%s\r\n", s->f_fstypename, s->f_mntfromname, s->f_mntonname);
    }

    fclose(fp);
    free(buf);

    printf_notification("Mount list dump complete!");

    return 0;
}

SYSCALL(getfsstat, 395);
ultimaweapon commented 9 months ago

@VocalFan try again with this version: dump-mntlist.zip

VocalFan commented 9 months ago

Once again, nothing.

ultimaweapon commented 9 months ago

This is... Weird.

VocalFan commented 9 months ago

Yeah, just...

'Payload received from 127.0.0.1'

Nothing. No notification or blinking from my USB's activity LED, and plugging my USB into my PC gives nothing.

ultimaweapon commented 9 months ago

@gandalfthewhite19890404 does your firmware is also 9.0? If yes can you try the above payload?

red-prig commented 9 months ago

I tried it, same thing

ultimaweapon commented 9 months ago

Thanks! Seems like there are something weird there...

VocalFan commented 9 months ago

Either that or we need to find a way to magically make payloads in Rust.

SuchAFuriousDeath commented 9 months ago

@VocalFan Can you try and add a print statements before the malloc and run it?

SuchAFuriousDeath commented 9 months ago

And also... shouldn't it be sizeof(struct statfs)? I don't have much experience in C.

SuchAFuriousDeath commented 9 months ago

Maybe ... do a binary search to find out when it stops working.

ultimaweapon commented 9 months ago

I don't think Rust will solve the problem and the problem should not be malloc.

ultimaweapon commented 9 months ago

@VocalFan try this one: dump-mntlist.zip