Fire30 / PS4-3.55-Code-Execution-PoC

161 stars 44 forks source link

find libkernel #9

Closed Zer0xFF closed 8 years ago

Zer0xFF commented 8 years ago

I've disabled the code by default to avoid cluttering the project, if you like otherwise do let me know.

maxton commented 8 years ago

You could also just change the original module loop to look something like this, it is much cleaner than your code:

for (var i = 0; i < 0x2002; i++) {
  if(i == 0x100) i = 0x2001;
  ...

This will work because libkernel is loaded at index 0x2001 (see this psdevwiki page)

Zer0xFF commented 8 years ago

I'm not home to check the fd for my FW(3.15), but assuming it's different on each FW, that wont work for me, but this code will still work on newer (& lower) FWs.

why is it cleaner? its the same at the original loop but changed to specifically find and stop at libkernel, (using a different syscall that is). my only issue with this is code is name.indexOf("libkernel") !== -1 for some reasons == just doesn't work correctly, but even that could have been due to segfault before finding libkernel.

maxton commented 8 years ago

It's cleaner in the sense that you aren't repeating nearly the same code in two loops. Maybe you could just replace the original loop with your new code and the different syscall? In fact it might even be better since you are finding the module size in addition to the base address

But if you are segfaulting often, well maybe that is not such a good idea. I have checked on 3.50 and 3.55 and both versions have libkernel.sprx at index 0x2001, so it might be the same on 3.15 as well

Zer0xFF commented 8 years ago

I wasnt initially interested in anything other than finding libkernel, but as per your suggestion(to replace the main loop), I'll look into the reason I was segfaulting, I think that was before i set the base search address tp 0x800000000, as such the code didnt always find libkernel and ends up in an infinite loop.

I dont think I'll be able to fire up the PS4 tonight, but i will report on the fd once I get the chance.

ghost commented 8 years ago

I use this code for find all module loaded in 3.55 (i have updated the wiki)

` var ret = storage.alloc(0x4); var count = storage.alloc(0x8); var modules = storage.alloc(0x1024);

    var r = new RopChain();
    r.syscall(592, modules, 256, count);
    r.add('pop rdi')
    r.add(ret)
    r.add('mov qword ptr [rdi], rax')
    r.execute();

    for (var i = 0; i<256; i++)
    {
        var id = read32(modules.add(i*4)).toString(16);

        if (id != 0)
        {
            var retInfo = storage.alloc(0x4);
            var info = storage.alloc(0x1A8);
            write32(info, 0x1A8)

            var rInfo = new RopChain();
            rInfo.syscall(608, read32(modules.add(i*4)), 0, info);
            rInfo.add('pop rdi')
            rInfo.add(ret)
            rInfo.add('mov qword ptr [rdi], rax')
            rInfo.execute();

            var name = read_str(info.add(0x8));
            var base = read64(info.add(0x44 * 4));

            alert("Module ID: 0x" + id + "\nModule Name: " + name + "\nModule Base Address: " + base.toString(16));

            storage.free(0x1AC);
        }
    }

    storage.free(0x1008);`

If you have find other module in 3.15, update the wiki please ^^

Fire30 commented 8 years ago

Sorry I have been away, but @Thunder07 if you can get it to replace the main loop that would be really useful. If not we can still probably figure something out.

Zer0xFF commented 8 years ago

@maxton ya seems the fd on 3.15 matches 3.50&3.55

@Fire30 no worries, I probably can, but before I do, please read this post.

alright, if you remove the break from my commit, this is the kind of output you'd get.

//needs 3 syscalls to get this info
Module name: libkernel.sprx Module size: 0x44000 Module Base: 0x83d724000
Module name: libkernel.sprx Module size: 0x4000 Module Base: 0x83d768000
Module name: libkernel.sprx Module size: 0x38000 Module Base: 0x83d76c000

I prefer @theorywrong method but it doesn’t generate any size info, so I tweaked in a little bit, thanks to the info from @Cturt's article (tweaked code below at the end)

//needs 1 syscalls to get this is info
Module ID: 0x2001 Module Name: libkernel.sprx
Module Base Address: 0x83d724000 Module Size: 0x44000
Module  Unknown Data Base Address: 0x83d768000 Module Unknown Data Size: 0x4000
Module Data Base Address: 0x0x83d76c000 Module Data Size: 0x38000

I can dump 0x60000 of libkernel, but trying to dump the full module (0x44000+0x4000+0x38000) causes a segfault, as matter of a fact, trying to dump just the last memory section causes segfaults. (I'm going AFK now, but ill test other modules for this later)

the issue now is, i dont know much about memory layout and whats in the data section, and if that should be considered as part of module memory section, for example during a dump (since we cant dump it anyway).

the reason I'm making a deal out of this, is that I want to add a comment telling people to perhaps avoid that last memory segment, instead of having them spend time trying to dump it, and failing not knowing what they've been doing wrong.

        debug_log('Printing module information...')
        var ret = storage.alloc(0x4);
        var count = storage.alloc(0x8);
        var modules = storage.alloc(0x1024);

        var r = new RopChain();
        r.syscall(592, modules, 256, count);
        r.add('pop rdi')
        r.add(ret)
        r.add('mov qword ptr [rdi], rax')
        r.execute();

        for (var i = 0; i<256; i++)
        {
            var id = read32(modules.add(i*4)).toString(16);

            if (id != 0)
            {
                var retInfo = storage.alloc(0x4);
                var info = storage.alloc(0x160);
                write32(info, 0x160)

                var rInfo = new RopChain();
                rInfo.syscall(593, read32(modules.add(i*4)), info);
                rInfo.add('pop rdi')
                rInfo.add(retInfo)
                rInfo.add('mov qword ptr [rdi], rax')
                rInfo.execute();

                var name = read_str(info.add(0x8));
                var base = read64(info.add(0x42 * 4));
                var size = read32(info.add(0x44 * 4));

                var data_base = read64(info.add(0x46 * 4));
                var data_size = read32(info.add(0x48 * 4));

                var something_base = read64(info.add(0x4A * 4));
                var something_size = read32(info.add(0x4C * 4));

                //alert("Module ID: 0x" + id + "\nModule Name: " + name + "\nModule Base Address: " + base.toString(16));
                document.write("Module ID: 0x" + id + "\nModule Name: " + name + "\nModule Base Address: 0x" + base.toString(16) + "\nModule Size: 0x" + size.toString(16)  + "\nModule Data Base Address: 0x" + data_base.toString(16) + "\nModule Data Size: 0x" + data_size.toString(16) + "\nModule Unknown Data Base Address: 0x" + something_base.toString(16) + "\nModule unknown Data Size: 0x" + something_size.toString(16) + "</br>");

                if (name == "libkernel.sprx") {
                    debug_bin(read_data(base.add(0x44000+0x4000), 0x38000-0x2), "libkernel_0x" + base.add(0x44000+0x4000).toString(16) + ".bin")
                    document.write("Dumped</br>")
                }

                storage.free(0x160);
            }
        }

        storage.free(0x1008);`
Zer0xFF commented 8 years ago

Hi @Fire30, Sorry I've still didnt get to updating this PR, I've been really busy this past week and I didnt get the chance to test anything, while I doubt I'll have the time to do the dump test, I'll try update this pull to replace the main loop, sometime tomorrow.

Fire30 commented 8 years ago

That works. Thanks for the work!

Zer0xFF commented 8 years ago

Alright, updated there. I suppose the next thing is, to store all the bases into an array, so they can all be used later on, instead of just libSceSysmodule.

I can see to adding that sometime this week, so I'd leave it with you, if you're happy with this and want to merge it know, or wait until i get around to doing it, its also simple enough, so I'd imagine anyone would be able to.

Fire30 commented 8 years ago

I can merge this now, and if you make more changes you can create another pull request. Thanks for all the work!