Announcement

Collapse
No announcement yet.

ASM code to write to memory with ps2rd

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

  • ASM code to write to memory with ps2rd

    This is just a tiny little thing I made in about 5 minutes and tested. It works perfectly. Just use it with ps2rd to write codes to memory while playing, since ps2rd doesn't have that ability yet. It's only 41 lines of code, which surprises me because I kept thinking something this simple would have been twice that size.

    Code:
    2??????? 0803c000
    200efff0 0???????
    200f0000 3c19000f
    200f0004 8f38fff4
    200f0008 8f2ffff8
    200f000c 8f2efffc
    200f0010 8f2dfff0
    200f0014 340cfeef
    400f0018 00040002
    118d000f 00000000
    200f001c 340cfedf
    200f0024 340cfebf
    200f002c 340cfe7f
    200f0034 340cfdef
    200f0038 118d0012
    200f003c 340cfddf
    200f0040 118d0017
    200f0044 340cfdbf
    200f0048 118d0018
    400f0050 00040002
    03e00008 00000000
    200f005c af0f0000
    200f0064 a70f0000
    200f006c a30f0000
    200f0070 af20fff4
    200f0074 af20fff8
    200f0078 34180001
    200f007c 03e00008
    200f0080 af38fffc
    200f0084 000e7040
    200f0088 34180001
    200f008c 3c0f0800
    200f0090 15f8fffe
    200f0094 27180001
    400f0098 00030003
    03e00008 00000000
    200f009c af2efffc
    200f00a0 030ec025
    200f00a8 af38fff4
    200f00ac 01ee7825
    200f00b4 af2ffff8
    That can be copied and pasted to every game if you want. Only the first and second lines are different from game to game.

    The first line is the address that jumps to this function. Just load the game's ELF file, invoke the analyzer, and use labelmates to find "scesifsendcmd". Whatever address its "jr ra" is is the address you should use to jump to this function. For example, it would be 20119c04 0803c000 for "Obscure: The Aftermath NTSC".

    The second line is the address of the joker/pad address. For "Obscure: The Aftermath NTSC" it would be 200efff0 00552b02.

    Buttons:
    L2 + Up = Write 4 bytes to address
    L2 + Right = Write 2 bytes to address
    L2 + Down = Write 1 byte to address
    L2 + Left = Reset Address & Value to 0, reset ORed value to 1
    R2 + Up = Shift ORed bit left 1 bit
    R2 + Right = OR the OR value to the address
    R2 + Down = OR the OR value to the value

    R2 + Up will intentionally pause the game for about 1 second. It's that way so you don't shift the bit left 50 times in an instant.

    You start by pressing L2 + Left. Once you know the address and value you want to write to the address, you use R2 + Up to shift the bit, and R2 + Right & R2 + Down to OR that bit to create the address and value you want write to that address. If you mess up, just Press L2 + Left and restart. Use ps2cc or whatever to see the memory in case you aren't sure of what you are doing. All you would need to look at are addresses 000efff4 (your address), 000efff8 (your value), and 000efffc (the value you OR to the address and value to create them).
    Attached Files
    July 7, 2019

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

  • #2
    Originally posted by bungholio View Post
    R2 + Up will intentionally pause the game for about 1 second. It's that way so you don't shift the bit left 50 times in an instant.
    Just set an isHolding boolean check.

    Comment


    • #3
      ps2rd has this several versions ago, but it was unfortunately broken by an update and never fixed...

      Nice job, though
      I may be lazy, but I can...zzzZZZzzzZZZzzzZZZ...

      Comment


      • #4
        I'll be adding it soon. Shouldn't be too difficult.

        Comment


        • #5
          Originally posted by Gtlcpimp View Post
          Just set an isHolding boolean check.
          What is a "isHolding" boolean check? I had some other too long thing that only executed something once every time I pressed a combination of buttons for changing the current dungeon level in Disgaea 1, but I doubt this "isHolding" check is as long as that. The only way I know of how to prevent the code from multiple executions is to create a pause or go for that long weird code I had for Disgaea 1.

          How do I create it, or what is it? I need an example because it's never a surprise when I miss doing something in an incredibly simpler way.



          I'm slow at doing this, but I am writing some ASM code to create watchpoints on any sw, sh, or sb commands. At this point I've got it to check addresses, see if they are a store operation, check if there are more store operations after it, check if the line before the first store operation is a jump or branch, and check if the line after the first store operation is a jump or branch assuming it only finds one store operation and there isn't a jump or branch before it already. That gives me 3 values to use, and using those I should be able to make a simple code to make the game create a custom subroutine for each store operation that will check to see what address is being written to. I'm taking the path that will probably take a lot of memory below 0x00100000, but I'm going to make the code record the location of the last store operation it created a custom subroutine for and to undo the custom subroutines it created and erase all subroutines so it can create routines for all store operations after the last one it found. I'm moving mighty slow though.
          Last edited by bungholio; 09-07-2010, 02:57:00 PM.
          July 7, 2019

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

          Comment


          • #6
            Here's an example of what I'm talking about:


            CodeDesigner v2.0 Source:
            Code:
            /*
              CodeDesigner v2.0 Source
              ReadPad() Example with isHolding check
              Created by: Gtlcpimp
            */
            
            
            address $000bfff0 // The _readPad configuration memory block
            hexcode $00100000 // Controller input address
            nop // isHolding boolean address
            
            nop // Padding to keep everything inline for ps2dis debugging
            nop // Padding to keep everything inline for ps2dis debugging
            
            address $000c0000 // Change to wherever you want
            // Or just append the _readPad function to your code
            
            
            _readPad:
            // No need to preserve registers since we are only using v0 and v1
            
            lui v1, $000c
            lw v1, $fff0(v1) // Load controller input address from config section
            
            lh v1, $0000(v1)
            addiu v0, zero, -1
            
            bne v1, v0, 7 // Check for no controller input
            nop
            lui v0, $000c
            sb zero, $fff4(v0) // Write pad button is not holding (isHolding = false)
            daddu v0, zero, zero
            daddu v1, zero, zero
            goto _readPadQuit
            
            bne v1, a0, 3
            nop
            goto _readPadHold
            
            daddu v0, zero, zero
            goto _readPadQuit
            
            _readPadHold:
            lui v0, $000c
            lb v1, $fff4(v0) // Load boolean isHolding
            bne v1, zero, 7  // See if we already are holding
            nop
            addiu v1, zero, 1
            sb v1, $fff4(v0)  // Write pad button is holding (isHolding = true)
            addiu v0, zero, 1    // Return true on button press check
            daddu v1, zero, zero // Return false on already holding
            goto _readPadQuit
            
            addiu v0, zero, 1
            addiu v1, zero, 1
            
            _readPadQuit:
            jr ra
            nop

            Hexadecimal RAW Output:
            Code:
            200BFFF0 00100000
            200BFFF4 00000000
            200BFFF8 00000000
            200BFFFC 00000000
            200C0000 3C03000C
            200C0004 8C63FFF0
            200C0008 84630000
            200C000C 2402FFFF
            200C0010 14620007
            200C0014 00000000
            200C0018 3C02000C
            200C001C A040FFF4
            200C0020 0000102D
            200C0024 0000182D
            200C0028 10000014
            200C002C 00000000
            200C0030 14640003
            200C0034 00000000
            200C0038 10000004
            200C003C 00000000
            200C0040 0000102D
            200C0044 1000000D
            200C0048 00000000
            200C004C 3C02000C
            200C0050 8043FFF4
            200C0054 14600007
            200C0058 00000000
            200C005C 24030001
            200C0060 A043FFF4
            200C0064 24020001
            200C0068 0000182D
            200C006C 10000003
            200C0070 00000000
            200C0074 24020001
            200C0078 24030001
            200C007C 03E00008
            200C0080 00000000
            Just change the controller input address in the configuration to whatever you want it to be.

            You call it with the controller button you want to know if it is being pressed or not in register a0.
            It will return the value '1' in register v0 if the button is being pressed, '0' if it is not.
            It will return the value '1' in register v1 if you are already holding the button, '0' if you are pressing it as a new button.

            It clears the isHolding when you call it and it reads NOINPUT (0xFFFF). Keep in mind it's just an example, you can implement it in your code if you wish, but it could definitely be made better. (kinda just rushed through it in a hurry)
            Last edited by Gtlcpimp; 09-07-2010, 04:51:23 PM.

            Comment


            • #7
              Every bit of that looks confusing. It looks even a bit longer than the code I made for Disgaea 1.

              I've been adding to my watchpoint code all day and came to a severe stop. I have come to realize that every jump to a custom subroutine would need to be a jump and link. If I don't, I might end up overwriting the values of registers being used and am guaranteed to screw up every game. If I JAL, I may overwrite the current return address. In order to preserve the return address, I will need to write to an extra 8 bytes meaning every spot I'll be jumping and linking to a custom subroutine will need a total of 16 bytes at the least. Then the problem occurs that many entire functions are only 8 bytes in length, like:
              jr ra
              sw v1, $008c(v0)

              If I continue with what I am doing, I'll need to make the code check specifically if there's a jump return or just a jump before the store operations. If it detects that, it will need to ignore that instance of store operation(s). That's a bad thing because then I won't be able to make watchpoints for all store operations. That ruins that.

              Any other crazy idea to fix that I have in mind would just be a some kind of crazy recompiler which would change the location of all of a game's code making watchpoints incorrect and will need lots more available memory than there is.



              I have no idea of how to fix that dilemma. I'm going to need to go with some kind of interpreter thing that takes over the entire game's code without changing any of it, and it will read the game's code and execute it normally but will do an extra exception where it will specifically check if a store operation is being executed, and if it is, it will check to ee which address is being written to and compare it with the address you are watching for and then write that address to a certain place in memory if it's writing to the address you are watching for. I don't know how to do that because I don't understand how all PS2 code works by far. All I would be doing is making sure it knows how to handle branches and jumps correctly so they don't break the game, and that alone would be kind of long. I'm only going by what Pyriel once said a while ago, but doing that would slow a game way the hell down. If it weren't for that, I'd have just done that because it would have been perfect, and that code could be changed to create breakpoints and all of that other stuff like pausing a game and somehow going through the game one line of code at a time and whatever else.


              How would someone go about making watchpoints, or anything beyond just a memory scanner?
              Last edited by bungholio; 09-07-2010, 09:55:41 PM.
              July 7, 2019

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

              Comment


              • #8
                You need to preserve your registers. If you don't preserve the return address register and you perform a jump and link it changes the return address to the address 8 bytes higher than the jump and link address.

                Code:
                /*
                  CodeDesigner v2.0 Source
                */
                
                addiu sp, sp, $FFF0  // Subtract the game's stack pointer for register preservation
                sq ra, $0000(sp)  // Store the return address on the game's stack
                
                jal $xxxxxxxx  // Jump and link to whatever we want
                nop  // The line executed right before the jump and link operation is executed
                
                lq ra, $0000(sp)  // Load the return address off the game's stack
                jr ra  // Jump to the return address
                addiu sp, sp, $0010  // Add the value we subtracted back to the game's stack pointer to keep the stack in line with the parent function
                Last edited by Gtlcpimp; 09-08-2010, 06:40:42 AM.

                Comment


                • #9
                  I fully understand that. I came to that conclusion. I keep trying to think of how to handle this "2 line long function with a jump" problem. I've got to think on this stuff a while. I always miss something simple.
                  July 7, 2019

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

                  Comment


                  • #10
                    Hehe.. This is a bit off topic but I'm just a bit curious, do you or any folks you know use my CodeDesignerv2.0? The function emulator was removed from public download (it was a piece of crap since I just sped through to make it look cool lol), but the application is actually very very useful for MIPS ASM coding =D

                    Comment


                    • #11
                      I've never heard of the tool.
                      July 7, 2019

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

                      Comment


                      • #12
                        =o It's only the best PS2 assembly tool ever! lol dunno if it's that great but it is pretty cool, I know some people use it but didn't know if many actually got into it.

                        http://www.cheaters-lounge.net/index.php?p=13

                        But back on topic, what is ps2rd?

                        Comment


                        • #13
                          Originally posted by Gtlcpimp View Post
                          But back on topic, what is ps2rd?
                          its the Project Artemis threads you see here.
                          lee4 Does Not Accept Codes Requests !
                          When lee4 asks a question it does not mean lee4 will look at your game
                          *How to create and use SegaCD codes >click here<*
                          >)

                          Comment


                          • #14
                            Ah, I get it "rd" must mean Remote Debugger, just didn't catch the new lingo. In that case as far as an actual cheat engine is concerned on that, the 1.3 engine I designed that is currently implemented into my RemotePS2 application would be very powerful upgrade for it... Hehe...

                            Comment


                            • #15
                              I feel stupid. I've finally had a minute of my life to spare to figure it out, and now I know why this ASM code isn't working. I forgot the code at 000f0014 should be:
                              lhu t5, $0000(t5)
                              Then everything else could be shifted down one line. I knew I changed the code at the last second and probably forgot to add it.
                              Last edited by bungholio; 09-14-2010, 04:14:51 PM.
                              July 7, 2019

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

                              Comment

                              Working...
                              X