Announcement

Collapse
No announcement yet.

[PPC asm] How to make branch instructions when its address & aim address change? (po)

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

  • [PPC asm] How to make branch instructions when its address & aim address change? (po)

    Hi,
    I have recently learnt how to move the value of an address into another address by inserting extra instructions into a bunch of asm codes using branch instructions. But I am totally clueless about what to do when the addresses of the pile of asm instructions where I want to insert the branch instruction change. The instruction would not be working anymore because the offset the branch instruction would have to be different each time I launch the game (F-Zero GX... a hell of pointers).
    At least the empty/unused area where I write my own asm instructions is unaffected by pointers.
    But... The aim address where I want to move the value to changes as well.
    I used a lis and a ori instruction to define the aim address in an unused register.
    My Website
    Hacking YouTube Channel


    No requests, please

  • #2
    Use compares (can't recall any PPC instructions atm), basically in your unused space where you forcibly load the values in the addresses after you load the values have a compare to the value you expect to be there if it isn't then it will skip the next set of instructions or whatever you choose to do.

    Here is a link I just found with the instruction set for PPC.
    http://pds.twi.tudelft.nl/vakken/in1...struction-set/

    If you could trace back to the original pointer then things would be easier but what exactly are you trying to do? and where? is it in game where you're racing or elsewhere? Do the addresses change from stage to stage?
    Spoiler Alert! Click to view...

    THE BAD GUY!!!!!!

    Comment


    • #3
      thanks so far.

      well, here's what I had done:

      I wanted to move the value of the vehicle's coordinate concerning to the X-axis into the address of a building's coordinate.
      so I set break on write for the vehicle's address:
      Code:
      break on write for 0x80BFE59C:
      
      CR:24000088  XER:20000000  CTR:00000000 DSIS:02400000
       DAR:80BFE59C SRR0:801E2BB4 SRR1:0000B032   LR:801E2B8C
        r0:801E2B8C   r1:801BAB88   r2:801B2320   r3:80BFE520
        r4:801BAB08   r5:801E8994   r6:E0000000   r7:00010000
        r8:80135220   r9:00000000  r10:000000B5  r11:801BAB68
       r12:801D8E18  r13:801B1820  r14:00000000  r15:00000000
       r16:00000000  r17:00000000  r18:00000000  r19:00000000
       r20:00000000  r21:00000002  r22:00000001  r23:80243360
       r24:8055FF9C  r25:80383E94  r26:80383E90  r27:00000007
       r28:80BFE520  r29:803F1620  r30:80BFE520  r31:8031FBF0
      
        f0:3EF95914   f1:41993493   f2:3E8CD987   f3:418F62C9
        f4:3AEC270E   f5:3F7FFFFF   f6:BEB8B532   f7:39405029
        f8:B5903C1F   f9:00000000  f10:BAEEC2CA  f11:BF7FFFE3
       f12:3F800000  f13:3F7FFFFE  f14:00000000  f15:00000000
       f16:00000000  f17:00000000  f18:00000000  f19:00000000
       f20:00000000  f21:00000000  f22:00000000  f23:00000000
       f24:00000000  f25:00000000  f26:00000000  f27:00000000
       f28:00000000  f29:00000000  f30:00000000  f31:3A500D01
      
      the relevant part of the trace log:
      801E2BB4:  F07E007C	psq_st	f3,124(r30),0,0
      801E2BB8:  D03E0084	stfs	f1,132(r30)
      801E2BBC:  48004901	bl	0x801e74bc
      the area of all the zeros starts at 0x80003620.
      So this is my code:


      801E2BB4 4BE20A6C b 0x80003620 // go to 0x80003620 (0x801E2BB4 is depended by pointers)
      80003620 F07E007C psq_st f3,124(r30),0,0 // original instruction that mustn't be lost
      80003624 3E80806C lis r20,0x806C // address into unused register (0x806C of 0x806CC1D0 into r20) (0x806CC1D0 is depended by pointers)
      80003628 629461D0 ori r20,r20,0x61D0 // address into unused register (0xC1D0 of 0x806CC1D0 into r20) (0x806CC1D0 is depended by pointers)
      8000362C D0740000 stfs f3,0(r20) // store float at address in r20
      80003630 481DF588 b 0x801E2BB8 // go back to the original instruction (801E2BB4 + 0x04)


      here's everything about the compare instructions: http://wiibrew.org/wiki/Assembler_Tu...l_Instructions

      Well, I understand the idea behind using a comparison-instruction. But it's a bit tricky to understand without explicit examples
      My Website
      Hacking YouTube Channel


      No requests, please

      Comment


      • #4
        I'm reading through some of that Wiki and PPC doesn't have a real simple way of pushing register data to the stack, if it did or does then you can push a bunch of registers to the stack then load the values and whatever compares you need then pop the values back from the stack and return to the original routine. I used ARM references there but it should apply here if the stack can be used, there seems to be info at the very end of the Wiki pertaining to this. Maybe someone with more PPC knowledge can chime in.
        Spoiler Alert! Click to view...

        THE BAD GUY!!!!!!

        Comment


        • #5
          Well if the registers are 64 bit, then r20 will hold 0xFFFFFFFF806C61D0. And storing to that will definitely not work.

          Anyway your question is about how branches are relative and not absolute. The solution is to use bctr instead. What you do is load the offset to your subroutine into the counter register ctr. Then use bctr to branch to the address within ctr. Then for returning you have a problem. What I always do with hooks is replace the blr at the end of the function with the branch to my subroutine (so you'd replace the blr with bctr). Then when my sub is done, I just call blr and it returns to normal. That way I don't need to worry about returning.

          I think this answers your question. But I'm here if you need more help.

          PS. I was assuming this whole time that the game's instructions change per boot and your subroutine is always where it is.
          Last edited by dnawrkshp; 02-21-2015, 02:55:45 PM.

          Comment


          • #6
            Thank you dnawrkshp
            Well, I have just got another idea, too.
            First I'd need to be using the bctr instruction to load my own address into blr. But what'S the syntax?

            Then I would be loading the address the pointer points at into an unused register and as well another value: the offset between the pointer and the aim address into another unused register. then I'd write an instruction to add the values of these register into a third unused register. the last instruction would be an stfs with the new calculated address of the third register

            i'd just need help with the syntax to load an address' value into a register..
            My Website
            Hacking YouTube Channel


            No requests, please

            Comment


            • #7
              Okay so actually for this I'd use a bctrl. Which just means that the link register (LR) will be set to the instruction after the bctrl. You can then call blr in your sub to jump back to the hooked function. Much simpler.

              So here we have the hook at 0x801E2BB0 and it loads 0x80003620 into r3, then ctr and then your sub is called with bctrl.
              It's important to know that ANY instructions overwritten with the hook should be executed at the top of your subroutine EXCEPT branches. So make sure to move this hook such that no bl or even b's are called.
              Code:
              [FONT=Consolas]address 0x801E2BB0
              
              //Using r3 might be bad, depending on the function. Best to find something that isn't used.
              lis r3, 0x8000
              ori r3, r3, 0x3620
              //Some assemblers use mtctr r3 instead
              mtspr CTR, r3
              bctrl
              
              
              address 0x800036200
              //Place overwritten instructions here
              
              //Not sure why you chose to use r20 here, but if it works then you could also use it instead of r3 for the above hook
              //Also you should clarify the pointers so that I can work that in, otherwise I have to work with this static address
              lis r20, 0x806C
              ori r20, r20, 0x61D0
              stfs f3, 0(r20)
              //Returns to the hook + 4 (the instruction after the bctrl)
              blr[/FONT]

              Comment


              • #8
                Thank you, this is awesome!
                (I was using r20 because it is unused. just said "r3" as an example).

                Well, what about
                lis r20, 0x806C
                ori r20, r20, 0x61D0
                since 0x806C61D0 is depended by a pointer? Should I then use the idea i thought about before (loading the value of the pointer's address into an unused register and add this with the offset between the address the pointer points at and the aim address (I will find with any pointer searcher))?
                My Website
                Hacking YouTube Channel


                No requests, please

                Comment


                • #9
                  Originally posted by CosmoCortney View Post
                  Thank you, this is awesome!
                  (I was using r20 because it is unused. just said "r3" as an example).

                  Well, what about
                  lis r20, 0x806C
                  ori r20, r20, 0x61D0
                  since 0x806C61D0 is depended by a pointer? Should I then use the idea i thought about before (loading the value of the pointer's address into an unused register and add this with the offset between the address the pointer points at and the aim address (I will find with any pointer searcher))?
                  The way you'd load a pointer in ASM is like so:
                  Code:
                  //No idea where the pointer is stored
                  lis r20, ??
                  lwz r20, ??(r20)
                  stfs f3, OFFSET(r20)
                  
                  //Multilevel pointer
                  lis r20, ??
                  lwz r20, ??(r20)
                  //For every sub-pointer just load with the offset
                  lwz r20, OFFSET1(r20)
                  lwz r20, OFFSET2(r20)
                  ...
                  stfs f3, OFFSET0(r20)
                  So the ?? represent the higher and lower halfs of the address and the offset is the offset from the pointer address to the place you want to store. Also this assumes that OFFSET is a 16 bit number. If it isn't, then you have to load it into a separate register and add it to r20.
                  Last edited by dnawrkshp; 02-22-2015, 02:28:17 PM.

                  Comment


                  • #10
                    It works great

                    Code:
                    pointer address: 800030cc offset: 00023aE4
                    the instruction: 
                    lis r20, 0x8000
                    ori r20,r20, 0x4010
                    mtspr CTR, r20
                    bctrl
                    
                    80004010 C03E0084	lfs	f1,132(r30) // original instruction
                    80004014 C01E009C	lfs	f0,156(r30) // original instruction
                    80004018 10621FDC	ps_madds0 f3,f2,f31,f3 // original instruction
                    8000401c EC200FFA	fmadds	f1,f0,f31,f1 // original instruction
                    lis r20, 0x801b // load pointer address
                    ori r20,r20,0x96ec // load pointer address into r20
                    lis r17, 0x0000 // load offset (0x0660) to the aim address into r17
                    ori r17, r17, 0x0660 // load offset (0x0660) to the aim address into r17
                    add r20,r20,r17  // add address with offset
                    stfs f3,0(r20) // this now writes the value of my x coordinate to the enemy's x coordinate!
                    blr
                    thank you again for the advise with the mtspr ctr instruction!
                    My Website
                    Hacking YouTube Channel


                    No requests, please

                    Comment

                    Working...
                    X