Announcement

Collapse
No announcement yet.

[PPC] Need help by branching the execution to the address inside of a GPR

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • [PPC] Need help by branching the execution to the address inside of a GPR

    Hello,
    title tells it all. I've been creating a codehandler for Wii U cheat codes for quite some time now. It's entirely written in PPC and does it's job very well. The programming was no problem to me until now:
    I want to add a codetype that allows the user to execute any assembly code. The codehandler will execute it, so no certain address will be needed. The assembly code of the cheat is located 0x08 remote from the address inside of GPR6 (GPR6 always holds the address of the current/next cheat to be executed). The codetype would look like the following:
    C000NNNN 00000000
    XXXXXXXX XXXXXXXX
    XXX....


    C0 = The codetype's value
    NNNN 0 number of assembly lines (one line has 2 assembly instructions)
    XX... = asm
    last assembly instruction should be blr or something else to go back to the codehandler

    once the codehandler reads C0 as codetype it should branch the execution to r6 + 0x08.


    Would this be a good solution?
    addi r7, r6, 0x08
    mtlr r7
    blr

    The problem is that now the value of lr is overwritten. So exiting the codehandler would get the execution into an infinite loop.

    What about?

    Code:
    at the codehandler:
    mflr r31             // backup lr into r31
    addi r7, r6, 0x04    // get the location of assembly code (less 0x04) into r7
    mtlr r7              // put r7 into lr
    blr                  // branch to lr + 4
    
    at the end of the cheat code
    lis r7, 0xXXXX       // load the location of the codehandler (where the blr is located)
    ori r7, r7, 0xXXX    // "
    mtlr r7              // load this location into r7
    blr                  // branch back to the codehandler +0x04
    
    back at the codehandler
    mtlr r31             // reload r31 into lr so the program won't crash on return 0.
    Last edited by CosmoCortney; 10-04-2016, 07:22:12 AM.
    My Website
    Hacking YouTube Channel


    No requests, please

  • #2
    Usually games will use the CTR register to store the branch destination and then call bctrl.
    Also in order for this to work the area the asm cheat code is in must be marked executable. On the PS2 that would be anywhere in the EE. On the PS3 it's a bit more particular. I'm not sure how the Wii U handles it. Something to look into if it fails to work.

    Comment


    • #3
      Without recalling too much about PPC's operations and standards off the top of my head, I'd say if you want it to be robust/idiot-proof, you'll probably want to encapsulate the supplied instructions in some boilerplate code, and copy it elsewhere in memory for execution. As a for instance, if there's nothing stopping the cheat's instructions from overwriting r31 or r6, your cheat engine would be hosed, even though the cheat would be doing nothing illegal. Given the limitations of this code type—can't rely on game state, etc.—you could just declare certain registers off-limits unless they're saved somewhere, I suppose.

      Comment


      • #4
        Originally posted by CosmoCortney View Post
        mflr r31
        addi r7, r6, 0x08
        mtlr r7
        blr
        I don't know how Nintendo does it, but that's risky looking right there depending on how it's done. At the very least you should preserve the contents of the linking register on the stack for safety, or a place of your choice.
        Assuming Nintendo is using r1 as the stack like the PS3, I'd have it like this:

        addi r1,r1,0xFFF8 <---assuming the stack goes that direction unless it's 0x8.
        mflr r0 <---assuming r0 gets the special register treatment of being used as the temporary one everywhere.
        std r0,0x0(r1)
        addi r7, r6, 0x04
        mtlr r7
        blr


        back at the codehandler
        ld r0,0x0(r1)
        mtlr r0
        addi r1,r1,0x8
        blr



        Preserve it on the stack unless you have your own place you want to preserve it, unless you are very confident nothing will overwrite your register. But if you're having something special where anybody can put any ASM code, they might just overwrite r6 and r31.

        Also like dnawrkshp said, make sure you have access to places. The PS2 gave you read/write access to the entire EE memory region, but on the PS3 with PPC it gets picky on where it will let you write, where you can read, where code can be executed from, and what is doing the reading/writing.
        If I insert code into my eboot that makes it write to somewhere in that eboot range, my PS3 game will instantly stop and throw an error. If I instead use dnawrkshp's NetCheat or the PS3 debugger or anything else to write to the same exact place, it doesn't throw errors.

        Like Pyriel said, make sure to put something in place to either preserve the contents of the registers or keep those exact registers off limits for others.

        The PS3 would also have used the counter register instead like this:
        mtctr r7
        bctrl

        If you didn't want expect any further code to be written that would alter the linking register you'd be fine, but if you're letting other people write whatever they want or whatever you're doing they just might overwrite it causing what looks like a game freeze when either the code is looping in circles fine by luck or crashed in the process of looping in circles.

        But what is it that's letting people write their own code or whatever???
        I know I can do fine modifying the eboot on the PS3 with whatever space, and I remember the PS2 Codebreaker and likely other devices had a limit of lines of cheat code to execute. Are you trying to add some one time code write thing that doesn't need constant write? If you have no limit of lines they could always just use constant write code types, but there has to be a limit or you're going to get lag or run out of space somewhere.
        Last edited by bungholio; 10-09-2016, 11:45:28 AM.
        July 7, 2019

        https://www.4shared.com/s/fLf6qQ66Zee
        https://www.sendspace.com/file/jvsdbd

        Comment


        • #5
          Originally posted by dnawrkshp View Post
          Usually games will use the CTR register to store the branch destination and then call bctrl.
          Also in order for this to work the area the asm cheat code is in must be marked executable. (...)
          The new release of the codehandler will store all cheats in the executable memory range. (Someone managed to unlock write permissions to any area).

          Originally posted by Pyriel View Post
          (...) I'd say if you want it to be robust/idiot-proof, you'll probably want to encapsulate the supplied instructions in some boilerplate code, and copy it elsewhere in memory for execution.
          This was my plan (except for the copying part). When the codehandler reads C0 as first byte of a code it will jump to the boilerplate code of the actual codetype. The address of the first assembly instruction will then be the value of r6 + 0x08.

          Originally posted by Pyriel View Post
          As a for instance, if there's nothing stopping the cheat's instructions from overwriting r31 or r6, your cheat engine would be hosed, even though the cheat would be doing nothing illegal. Given the limitations of this code type—can't rely on game state, etc.—you could just declare certain registers off-limits unless they're saved somewhere, I suppose.
          For testing purposes I don't care about backing up r31 and r6 before everything works as I imagine. This will be the last part of creating this code type

          Originally posted by bungholio View Post
          I don't know how Nintendo does it, but that's risky looking right there depending on how it's done. At the very least you should preserve the contents of the linking register on the stack for safety, or a place of your choice.
          Assuming Nintendo is using r1 as the stack like the PS3, I'd have it like this:

          addi r1,r1,0xFFF8 <---assuming the stack goes that direction unless it's 0x8.
          mflr r0 <---assuming r0 gets the special register treatment of being used as the temporary one everywhere.
          std r0,0x0(r1)
          addi r7, r6, 0x04
          mtlr r7
          blr


          back at the codehandler
          ld r0,0x0(r1)
          mtlr r0
          addi r1,r1,0x8
          blr



          Preserve it on the stack unless you have your own place you want to preserve it, unless you are very confident nothing will overwrite your register. But if you're having something special where anybody can put any ASM code, they might just overwrite r6 and r31.

          Also like dnawrkshp said, make sure you have access to places. The PS2 gave you read/write access to the entire EE memory region, but on the PS3 with PPC it gets picky on where it will let you write, where you can read, where code can be executed from, and what is doing the reading/writing.
          If I insert code into my eboot that makes it write to somewhere in that eboot range, my PS3 game will instantly stop and throw an error. If I instead use dnawrkshp's NetCheat or the PS3 debugger or anything else to write to the same exact place, it doesn't throw errors.

          Like Pyriel said, make sure to put something in place to either preserve the contents of the registers or keep those exact registers off limits for others.

          The PS3 would also have used the counter register instead like this:
          mtctr r7
          bctrl

          If you didn't want expect any further code to be written that would alter the linking register you'd be fine, but if you're letting other people write whatever they want or whatever you're doing they just might overwrite it causing what looks like a game freeze when either the code is looping in circles fine by luck or crashed in the process of looping in circles.

          I know I can do fine modifying the eboot on the PS3 with whatever space, and I remember the PS2 Codebreaker and likely other devices had a limit of lines of cheat code to execute. Are you trying to add some one time code write thing that doesn't need constant write? If you have no limit of lines they could always just use constant write code types, but there has to be a limit or you're going to get lag or run out of space somewhere.
          Yes, r1 is the stack, but I can't use ld/std since the Wii U's processor is a 32bit unit. However, your ideas appear helpful, I will give it a shot soon
          And there is a limit of cheat codes. It's actually somewhere at 2000 lines. The next release will allow even more to be on at a time. And I already have created a codetype which allows you to determine the time of execution of the following codes. 0x78 corresponds to 1 second. You can find the codetype documentation here: http://cosmocortney.ddns.net/enzy/ca...es_en.php#time

          Once the branching stuff works as it should I will implement a few instructions for backing up r0, r6 and r31.

          Originally posted by bungholio View Post
          But what is it that's letting people write their own code or whatever???
          On the Wii and GCN it was only possible to execute ASM of a function that is always active or executed at a certain point of time. Not all register were available without backing the up.
          This codetype would allow the user to create any cheat code or modification that won't be possible with one of the codetypes. This way the assembly cheat coud also be deactivated without freezing the system.

          After that I will create a codetype that injects any assembly code like the Wii's C2 codetype does
          My Website
          Hacking YouTube Channel


          No requests, please

          Comment


          • #6
            It works now, thanks again

            Code:
            formatting:
            C000NNNN 60000000        // nop being added there since i'm afraid of an instruction being skipped
            XXXXXXXX XXXXXXXX
            ....
            3C40010F 60426AE0        // ever assembly code of thsi type must end with these 2 lines
            7C4903A6 4E800420
            
            NNNN = number of lines (1 line = 2 insructions)
            XXXX... = asm
            
            
            this happens when a code of the C0-type has been found:
            lis r2, 0x1001              // where to backup some registers
            ori r2, r2, 0x4fC0          // "
            stw r6, 0x00 (r2)           // backup r6
            stw r30, 0x04 (r2)          // backup r30
            stw r31, 0x08 (r2)          // backup r31
            addi r2, r6, 0x04           // put the location of asm into r2
            mtctr r2                    // put r2 into count register
            bctr                        // branch to asm cheat
            nop                         // execution will come back here. i used nop here because i'm afraid of an instruction being skipped
            lis r2, 0x1001              // from where to recover some registers
            ori r2, r2, 0x4fC0          // "
            lwz r6, 0x00 (r2)           // recover r6
            lwz r30, 0x04 (r2)          // recover r30
            lwz r31, 0x08 (r2)          // recover r31
            lhz r2, 0x02 (r6)           // load numbers of assembly lines
            mulli r2, r2, 0x08          // calculate amount of bytes
            add r6, r6, r2              // prepare r6 for next cheat
            addi r6, r6, 0x08           // "
            b 0x00000019C               // go back to the beginning of the codehandler to execute the next cheat
            
            
            end of every C0-Code:
            lis r2, 0x010F             // where to go back 
            ori r2, r2, 0x6AE0         // "
            mtctr r2                   // put this address into count register
            bctr                      // go back
            
            
            example:
            C0000003 60000000
            3C601000 90C30000
            3C40010F 60426AE0
            7C4903A6 4E800420
            
            lis r3, 0x1000
            stw r6, 0x00 (r3)
            lis r2, 0x010F
            ori r2, r2, 0x6AE0
            mtctr r2
            bctr
            The new codehandler will be made public once JGecko U has been updated
            Last edited by CosmoCortney; 10-15-2016, 12:21:00 AM.
            My Website
            Hacking YouTube Channel


            No requests, please

            Comment

            Working...
            X