Syscalls cause freezes. Help needed

Discussion in 'Wii U - Hacking & Backup Loaders' started by CosmoCortney, Dec 30, 2016.

  1. CosmoCortney
    OP

    CosmoCortney The Hacker Furry

    Member
    1,579
    1,490
    Apr 18, 2013
    Germany
    on the cool side of the pillow
    Hello,
    in order to allow the codehandler to write values to the executable memory range I need to convert the cheat's address from effective to physical and then perform a memory copy syscall to get the value written to the executable memory.
    However, everytime I attempt to do a syscall the console freezes.

    Here's some information:
    Cheat code layout for 32-bit writes:
    00020000 LLLLLLLL
    VVVVVVVV 00000000

    LLLLLLLL
    = Address
    VVVVVVVV = Value



    syscall to convert the address inside of r3 from effective to physical:
    li r0, 0x0200
    sc

    syscall to perform a mem_copy write:
    li r0, 0x2500
    sc

    r3 contains the physical address to copy to
    r4 contains the address to copy from
    r5 contains the buffer size (0x04 for 32-bits)


    the codehandler always holds the address of the current cheat's first byte in r6
    For troubleshooting I want first to perform the effective-to-physical syscall:
    Code:
    lis r4, 0x1001 // address where to copy the data to
    
    ori r4, r4, 0x5000 // "
    lwz r5, 0x08 (r6) // load cheat value
    stw r5, 0x00 (r4) // copy cheat value to 0x10015000
    lwz r3, 0x04 (r6) // load cheat address
    li r0, 0x0200 // load effective to physical sc value
    sc // perform effective to physical. System crashes here
    nop // nop here because returning from sc can skip an instruction
    addi r6, r6, 0x10 // prepare r6 to read the next cheat
    b 0x0000019C // go back to the codetype-check
    This does not work (even I can perform a few other sc this way like fast_exit)
    So I thought the system does not know where to branch because the sc ends with blr and the lr (link register) was not set.
    blr returns to the address inside of lr + 0x04. In this case to the nop instruction

    So I tried to backup lr to r20, load the sc's address into r21, load r21 into lr and after blr reloading r20 back into lr.
    Sadly this does not work as well :(
    Code:
    mflr r20 // backup lr into r20
    lis r4, 0x1001 // address where to copy the data to
    ori r4, r4, 0x5000 // "
    lwz r5, 0x08 (r6) // load cheat value
    stw r5, 0x00 (r4) // copy cheat value to 0x10015000
    lwz r3, 0x04 (r6) // load cheat address
    li r0, 0x0200 // load effective to physical sc value
    lis r21, 0x010F // load sc's address into r21
    ori r21, 0x4000 // "
    mtlr r21 // move r21 to lr
    sc // effective to physical. System crashes here
    nop // nop here because returning from sc can skip an instruction
    mtlr r20 // put r20 back into lr so the codehandler will return properly
    addi r6, r6, 0x10
    b 0x0000019C
    Now I had a look at a .elf to see how syscalls are performed there. I recreated my syscall based on this scheme. But it froze again..:
    Code:
    mflr r0 // backup lr into r0
    mr r20, r0 // move r0 into r20
    lis r3, 0x1001 // load address to be converted into r3
    ori r3, r3, 0x5000 // "
    li r0, 0x0200 // load sc value
    sc // perform syscall
    nop
    mr r0, r20 // put r20 back into r0
    mtlr // put r0 back to lr
    
    Any idea what to do?

    @wj44 @NWPlayer123 @BullyWiiPlaza @Maschell
     
    Last edited by CosmoCortney, Dec 31, 2016
  2. NWPlayer123

    NWPlayer123 GBAtemp Addict

    Member
    2,632
    6,233
    Feb 17, 2012
    United States
    The Everfree Forest
    I'm so out of the scene, would have to see what EffectiveToPhysical is doing and what would cause it to break
     
    BullyWiiPlaza and CosmoCortney like this.
  3. HackingNewbie

    HackingNewbie GBAtemp Fan

    Member
    477
    96
    Dec 29, 2016
    United Kingdom
    Somewhere in 2008
    Is this code ASM?
     
  4. CosmoCortney
    OP

    CosmoCortney The Hacker Furry

    Member
    1,579
    1,490
    Apr 18, 2013
    Germany
    on the cool side of the pillow
    yes, the codehandler is entirely written in ASM
     
  5. HackingNewbie

    HackingNewbie GBAtemp Fan

    Member
    477
    96
    Dec 29, 2016
    United Kingdom
    Somewhere in 2008
    K, I started learning ASM just today though, so I probably can't help.. I only know python which seems to be a pretty useless language in the wii u hacking scene so good luck finding a solution
     
  6. HackingNewbie

    HackingNewbie GBAtemp Fan

    Member
    477
    96
    Dec 29, 2016
    United Kingdom
    Somewhere in 2008
    According to wiiubrew, 0x2500 isn't a syscall value in cafe OS. This might be the problem. Or maybe it's because you didn't put blr after sc like this:
    Code:
    ...
    li r0,0x0200// load effective to physical sc value
    sc // perform effective to physical. System crashes here
    blr
    
    Or maybe because of sc skipping the next instruction you might want to do this:
    Code:
    ...
    li r0,0x0200// load effective to physical sc value
    sc // perform effective to physical. System crashes here
    nop
    blr
    
    Or maybe you might want to check the code before sc. Just some ideas, my ASM understanding is quite limited so they probably won't work
     
    Last edited by HackingNewbie, Dec 31, 2016
  7. CosmoCortney
    OP

    CosmoCortney The Hacker Furry

    Member
    1,579
    1,490
    Apr 18, 2013
    Germany
    on the cool side of the pillow
    The syscall table is very incomplete. I have opened a .elf in a hex editor and there I could also find a syscall being performed with 0x2500. there's also a blr after that. but I can't use it because it would exit the codehandler and all codes after that won't be executed.
    It is normal that sc causes the next instruction to be skipped. so I put a nop after sc, so if no instruction is being skipped it will just execute an additional nop which effectively does not cause any difference.
    What I could do is checking out if the assembly code of the sc in the FF range overwrites any necessary register. But I don't know where to find it
     
  8. HackingNewbie

    HackingNewbie GBAtemp Fan

    Member
    477
    96
    Dec 29, 2016
    United Kingdom
    Somewhere in 2008
    Where to find what?
     
  9. CosmoCortney
    OP

    CosmoCortney The Hacker Furry

    Member
    1,579
    1,490
    Apr 18, 2013
    Germany
    on the cool side of the pillow
    Finding where the Wii U has the assembly code of all syscalls
     
  10. HackingNewbie

    HackingNewbie GBAtemp Fan

    Member
    477
    96
    Dec 29, 2016
    United Kingdom
    Somewhere in 2008
    And it's in the FF range (FF000000-FFFFFFFF)? I THINK that's what the FF range means, but please tell me if it means something else!
     
  11. BullyWiiPlaza

    BullyWiiPlaza Nintendo Hacking <3

    Member
    1,771
    1,440
    Aug 2, 2014
    Germany
    1. You should try calling the function address:
      Code:
      .SET SOURCE_ADDRESS, 0x10015000
      .SET EFFECTIVE_TO_PHYSICAL_ADDRESS, 0x99999999 # TODO Replace with real address
      
      lis r4, SOURCE_ADDRESS@h
      ori r4, r4, SOURCE_ADDRESS@l
      lwz r5, 0x8 (r6) # Load cheat code value
      stw r5, 0x0 (r4) # Write cheat value to source address
      lwz r3, 0x4 (r6) # Load cheat code address
      # Do the function call to OSEffectiveToPhysical
      lis r7, EFFECTIVE_TO_PHYSICAL_ADDRESS@h
      ori r7, r7, EFFECTIVE_TO_PHYSICAL_ADDRESS@l
      mtctr r7 # Move to count register
      bctr # Branch to count register
      # r3 now holds the physical address
      Warning: Spoilers inside!

    2. You can use OSEffectiveToPhysical with JGecko U to see how it calculates the address. You can replace the syscall with an add instruction then:
      Code:
      .SET SOURCE_ADDRESS, 0x10015000
      
      lis r4, SOURCE_ADDRESS@h
      ori r4, r4, SOURCE_ADDRESS@l
      lwz r5, 0x8 (r6) # Load cheat code value
      stw r5, 0x0 (r4) # Write cheat value to source address
      lwz r3, 0x4 (r6) # Load cheat code address
      addis r3, r3, 0x3000 # Add 0x30000000 (to simulate the OSEffectiveToPhysical for example, make sure to check how much to add)
      # r3 now holds the physical address
      This will work if the addresses are always in the same range and they will be for writing assembly.
     
    Last edited by BullyWiiPlaza, Dec 31, 2016
    HackingNewbie and CosmoCortney like this.
  12. CosmoCortney
    OP

    CosmoCortney The Hacker Furry

    Member
    1,579
    1,490
    Apr 18, 2013
    Germany
    on the cool side of the pillow
    i had similar thoughts as you can see above but I don't know the actual address of the subroutine is in the memory. but option 2 is good too :)
    i will give it a shot later. thanks <3
     
    BullyWiiPlaza likes this.
  13. QuarkTheAwesome

    QuarkTheAwesome Working for Hugs

    Member
    828
    2,052
    Apr 19, 2015
    Australia
    Stuck in the PowerPC
    My guess would be that calling convention is getting you stuck. The PowerPC ABI dictates that registers 0 through 13 are volatile and could change at any time when calling a subroutine; while it seems to me that your program depends on certain registers within this range (r6) being constant.
    To give an example of how this works:
    Code:
    li r4, 0x25 //r4 is inside the volatile range
    li r30, 0x15 //r30 is outside the volatile range
    
    bl some_c_function
    
    cmplwi r4, 0x25 //There's no way of knowing what would happen here
    //This is because r4 is volatile when calling subroutines and may have been changed
    
    cmplwi r30, 0x15 //We know that this will result in the eq flag being set
    //r30 is NOT volatile, so a subroutine has to put it back the way it found it
    
    Since syscalls also have to follow calling convention I'd suspect that this is what you're butting up against. I'd suggest moving everything important up to higher-numbered registers, or if your codebase is too big you could get away with moving stuff in and out of those registers when you need to call functions.
     
    CosmoCortney likes this.
  14. CosmoCortney
    OP

    CosmoCortney The Hacker Furry

    Member
    1,579
    1,490
    Apr 18, 2013
    Germany
    on the cool side of the pillow
    In the case of the codehandler the only registers you have to care about is r6 because it helds the address of the cuttent cheat's first byte. All other can be changed because they are backed up into memory and restored before returning to OS.
    So it could be true that r6 has become changed. I should try backing it up before sc and see if it works, tomorrow