OSDriver kernel exploit - a technical description

Discussion in 'Wii U - Hacking & Backup Loaders' started by Marionumber1, Aug 20, 2015.

  1. Marionumber1
    OP

    Marionumber1 GBAtemp Maniac

    Member
    14
    Nov 7, 2010
    United States
    Then it's possible that there may be tables for the loader, foreground apps, and background apps. Thanks for pointing that out.
     
    VinsCool and CosmoCortney like this.
  2. loco365

    loco365 GBAtemp Guru

    Member
    11
    Sep 1, 2010
  3. CosmoCortney

    CosmoCortney Chemtrail Pilot

    Member
    11
    Apr 18, 2013
    New Zealand
    on the cool side of the pillow
    So.. range 01 can be mapped as read/write and executable?
     
  4. Marionumber1
    OP

    Marionumber1 GBAtemp Maniac

    Member
    14
    Nov 7, 2010
    United States
    The kern_read() and kern_write() syscalls access memory with kernel permissions, but that doesn't let you write read-only memory. What they do is let you bypass the kernel-only flag and write kernel data. You can use this to modify the address table and map the 0x01000000 range as writable, provided you find the writable flag (probably in PPC manuals).
     
    VinsCool and CosmoCortney like this.
  5. golden45

    golden45 GBAtemp Regular

    Member
    4
    Jun 23, 2015
    France
    We could also map the third entry of the kernel address table (default virtual address : 0x02000000), which seams to be where the application code is put.
    This third entry is modified for each application/game, here is what I found so far :

    (virt_addr, range_len, phys_addr, flags)
    in browser : 0x0D800000, 0x02800000, 0x4D800000, 0x2ff09400
    MarioKart8 : 0x0E280000, 0x01D80000, 0x8E280000, 0x2ff09400
    Splatoon : 0x0E000000, 0x02000000, 0x8E000000, 0x2ff09400
    WindWaker : 0x0E000000, 0x02000000, 0x8E000000, 0x2ff09400
    Bayon2demo : 0x0D400000, 0x02C00000, 0x8D400000, 0x2ff09400
    SonicLWdemo: 0x0A600000, 0x05A00000, 0x8A600000, 0x2ff09400
    WiiuParams : 0x0E000000, 0x02000000, 0x8E000000, 0x2ff09400
     
    Adr990, Marionumber1 and CosmoCortney like this.
  6. CosmoCortney

    CosmoCortney Chemtrail Pilot

    Member
    11
    Apr 18, 2013
    New Zealand
    on the cool side of the pillow
    Oh, I see. It first sounded like it would refer to making the 01 range writable to me :)

    So, this is where the .rpx is loaded?
     
  7. shinyquagsire23

    shinyquagsire23 SALT/Sm4sh Leak Guy

    Member
    13
    Nov 18, 2012
    United States
    Las Vegas
    Yeah, that's where it is for certain, I only just found out yesterday that it wasn't even readable for some reason so I assumed it was a per-process mapping, but it's not.

    EDIT: I made a derp.
     
    Last edited by shinyquagsire23, Aug 30, 2015
  8. CosmoCortney

    CosmoCortney Chemtrail Pilot

    Member
    11
    Apr 18, 2013
    New Zealand
    on the cool side of the pillow
    Hmm.. I assume it's not writable, too. Am I right?
     
  9. shinyquagsire23

    shinyquagsire23 SALT/Sm4sh Leak Guy

    Member
    13
    Nov 18, 2012
    United States
    Las Vegas
    Highly doubtful of that yeah. I know for certain it's not under the 0x01xxxxxx or 0x0exxxxxx areas which are RX.

    Edit: If the kernel table entry can be remapped as RWX I'm pretty sure you'd be able to start using the area from Gecko, I'm personally trying to get at the area for some .text mods myself.
     
    CosmoCortney and VinsCool like this.
  10. Marionumber1
    OP

    Marionumber1 GBAtemp Maniac

    Member
    14
    Nov 7, 2010
    United States
    Interesting, I had done some experiments to see where app code ended up, but never checked to see that the address table got modified too. This seems to confirm my hypothesis that the application code address is designed to make it end at 0x10000000. I noticed it with the browser and Mii Maker, but it's nice to have more solid proof. It also verifies my other hypothesis, which is that they throw app code at the end of the app data area in physical memory.

    The base, length, and physical address are modified, but flags are still unchanged from their default. This implies that you're right, and we can also remap it as writable.
     
  11. shinyquagsire23

    shinyquagsire23 SALT/Sm4sh Leak Guy

    Member
    13
    Nov 18, 2012
    United States
    Las Vegas
    I did some experimentation and found that FFEA9CE0 is the location for the syscall table used while in the home menu.

    EDIT: And while I'm at it:
    Code:
    (virt_addr, range_len, phys_addr, flags)
    0x0dd00000, 0x2300000, 0x8dd00000, 0x2ff09400
    
    Is what you'll want for looking at the home menu's .text area.

    And in addition to this, you can find these offsets from non-kernel-only definitions. In the 0x0e300000 area there's several structures which contain ELFs, the name of the loaded module rpl/rpx, and where it's loaded. For example, 0x0e382500 is the structure for men.rpx, and 0x0e382500+0x204 will have the offset which the .text is located at. At 0x0e382500+0x204 it actually has several pointers, going in this order: .syscall, .text, and I'm guessing maybe some .data locations or something.

    Other EDIT: 0x0e300000 isn't mapped while in the browser, so not 100% solid I suppose. Although if you have kernel you can just find the offset fairly easily anyhow.

    Last EDIT: So by mapping kern_read and kern_write for the menu with TCPGecko in the browser, I managed to remap the .text region as RWX. After gaining kernel read/write while in the menu, changing 0xFFEAAA10+0x2C from 0x2ff09400 to 0x2FF09C00 lets me write in the 0x0dd00000 area! I'm not sure if the RWX mappings are changed between app launches though, but this is enough to give you temporary RWX access while the game/app runs.. Actually it seems only kernel write access is needed to modify the .text region, no remapping needed.
     
    Last edited by shinyquagsire23, Aug 31, 2015
    Adr990, I pwned U!, golden45 and 4 others like this.
  12. golden45

    golden45 GBAtemp Regular

    Member
    4
    Jun 23, 2015
    France
    For sure, I used cafiine with Mario Kart to look at the link register when the game was calling the FSAddClientEx function, and it was always in this area =)
     
    CosmoCortney, I pwned U! and VinsCool like this.
  13. Lory171

    Lory171 Member

    Newcomer
    2
    Jun 20, 2015
    Italy
    the file cos.xml inside the code folder have a different max_codesize for different games, i don't know if it's related but it look like that
    Game1: <max_codesize type="hexBinary" length="4">0E000000</max_codesize>
    Game2: <max_codesize type="hexBinary" length="4">03200000</max_codesize>
     
  14. golden45

    golden45 GBAtemp Regular

    Member
    4
    Jun 23, 2015
    France
    It is related yes. With this length, the virtual address is then calculated.
    This virtual address range is filled from the start with :
    - the .syscall and .text sections of the RPX
    - functions to jump to the imported functions of the RPX.
    - elf structures for the RPLs, thoses structures are linked to each other.
    - code parts linked to the elf structures
    - zero data
    - data in tables (most likely)

    (AFAIK)
     
    I pwned U!, VinsCool and CosmoCortney like this.
  15. Onion_Knight

    Onion_Knight GBAtemp Advanced Fan

    Member
    6
    Feb 6, 2014

    If I'm wanting to run TCPGecko on the menu, I need to modify my Kernel Address table to this one correct?
     
  16. golden45

    golden45 GBAtemp Regular

    Member
    4
    Jun 23, 2015
    France
    Yes, you can also add the read/write syscall to all syscall tables directly in the kernel exploit.

    If you're on 5.3.2 :

    in loader.h:
    #define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown
    #define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games
    #define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader
    #define KERN_SYSCALL_TBL_4 0xFFEA9CE0 // works with home menu
    #define KERN_SYSCALL_TBL_5 0xFFEAA0E0 // works with browser (previously KERN_SYSCALL_TBL)

    in loader.c:
    - replace "copy_payload[0xff8/4] = KERN_SYSCALL_TBL + (0x34 * 4);" by "copy_payload[0xff8/4] = KERN_SYSCALL_TBL_5 + (0x34 * 4);"
    - add those lines after the " Map the loader and coreinit as RW before exiting" part :
    /* Add read/write syscalls to the other syscall_tables */
    kern_write(KERN_SYSCALL_TBL_1 + (0x34 * 4), KERN_CODE_READ);
    kern_write(KERN_SYSCALL_TBL_1 + (0x35 * 4), KERN_CODE_WRITE);

    kern_write(KERN_SYSCALL_TBL_2 + (0x34 * 4), KERN_CODE_READ);
    kern_write(KERN_SYSCALL_TBL_2 + (0x35 * 4), KERN_CODE_WRITE);

    kern_write(KERN_SYSCALL_TBL_3 + (0x34 * 4), KERN_CODE_READ);
    kern_write(KERN_SYSCALL_TBL_3 + (0x35 * 4), KERN_CODE_WRITE);

    kern_write(KERN_SYSCALL_TBL_4 + (0x34 * 4), KERN_CODE_READ);
    kern_write(KERN_SYSCALL_TBL_4 + (0x35 * 4), KERN_CODE_WRITE);

    Then you're free to use the syscalls everywhere :)

    edit: sorry I didn't read well the question, I let this here if you are interested
     
  17. Onion_Knight

    Onion_Knight GBAtemp Advanced Fan

    Member
    6
    Feb 6, 2014
    This is even better than the question I asked!

    Will my thread migrate than from browser, to system menu and game?

    — Posts automatically merged - Please don't double post! —

    I'll need to add this to the loader.h for the codehandler as well I assume.
     
  18. golden45

    golden45 GBAtemp Regular

    Member
    4
    Jun 23, 2015
    France
    If you modify the syscall tables in the kernel exploit, you don't need to modify them anymore. You will be able to use kern_read/kern_write of pygecko when in browser/home/games

    You mean the pygecko thread?
    If yes, the thread (pygecko server) is created when coreinit.rpl starts, which is done at the end of the loader, which is called everytime you switch between applications.
     
  19. Onion_Knight

    Onion_Knight GBAtemp Advanced Fan

    Member
    6
    Feb 6, 2014
    Your my favorite clown right now. Thanks for the quick answers. Finally bothered to fix the pygecko codehandler to keep listening after the socket closes, so now i'm interested in moving around.
     
  20. golden45

    golden45 GBAtemp Regular

    Member
    4
    Jun 23, 2015
    France
    Be aware that with pygecko, it will freeze the console if you launch a game, quit it, and then return to the browser.
    (well for me it freezes, maybe it's the modifications i made on pygecko so i'm not sure)

    To resolve the problem I had to add a "GX2WaitForVsync" in the start function of the pygecko codehandler :

    Code:
    static void start(int argc, void *argv) {
        int sockfd = -1, clientfd = -1, ret, len;
        struct sockaddr_in addr;
        struct bss_t *bss = argv;
    
        socket_lib_init();
    
        while (1) {
            addr.sin_family = AF_INET;
            addr.sin_port = 7331;
            addr.sin_addr.s_addr = 0;
    
            sockfd = ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
            CHECK_ERROR(ret == -1);
            ret = bind(sockfd, (void *)&addr, 16);
            CHECK_ERROR(ret < 0);
            ret = listen(sockfd, 1);
            CHECK_ERROR(ret < 0);
            len = 16;
            clientfd = ret = accept(sockfd, (void *)&addr, &len);
            CHECK_ERROR(ret == -1);
            socketclose(sockfd);
            sockfd = -1;
            ret = rungecko(bss, clientfd);
            CHECK_ERROR(ret < 0);
            socketclose(clientfd);
            clientfd = -1;
    
            GX2WaitForVsync();
            continue;
    error:
            if (clientfd != -1)
                socketclose(clientfd);
            if (sockfd != -1)
                socketclose(sockfd);
            bss->error = ret;
            GX2WaitForVsync();
        }
     
Quick Reply
Draft saved Draft deleted
Loading...