beardypig / ghidra-emotionengine

Ghidra Processor for the Play Station 2's Emotion Engine MIPS based CPU
Apache License 2.0
200 stars 34 forks source link

Added SaveStateImporter #22

Closed astrelsky closed 4 years ago

beardypig commented 5 years ago

Can we call it PCSX2SaveStateImporter, so we can have others later :)

astrelsky commented 5 years ago

Of course

astrelsky commented 4 years ago

I changed the names and squashed a minor bug where the read and write properties weren't set in the memory block after initialization.

chaoticgd commented 4 years ago

I can't seem to get this to work. I've tried on an existing (already analysed) file and a fresh non-analysed file. In the latter case I got the following error:

java.lang.IllegalArgumentException: Block must have a non-zero length at ghidra.program.database.mem.MemoryMapDB.checkRange(MemoryMapDB.java:1825) at ghidra.program.database.mem.MemoryMapDB.createInitializedBlock(MemoryMapDB.java:486) at ghidra.program.flatapi.FlatProgramAPI.createMemoryBlock(FlatProgramAPI.java:344) at PCSX2SaveStateImporter.loadMainMemory(PCSX2SaveStateImporter.java:87) at PCSX2SaveStateImporter.run(PCSX2SaveStateImporter.java:36)

I was using Ghidra 9.1-BETA_DEV with a savestate from the PCSX2 daily build (savestate version 00 00 0E 9A).

I might try to debug this later. I don't have time right now though.

astrelsky commented 4 years ago

That's strange I'll have to take a look later. Also there is no CRC check atm it just assumes a valid save state. I came up with the idea on a whim and wrote it on the fly as it was straightforward enough to do.

I think I just need to check if there are actually any bytes remaining before creating the section for any remaining bytes. Give it a shot again and let me know if you have the same problem or not.

Also if you have any suggestions on what to call that section other than .other it would be appreciated.

chaoticgd commented 4 years ago

I've got it working by commenting out the call to loadMainMemory. It seems like it would be easiest to just have users import eeMemory.bin manually and then use this script for the other memory blocks, at least as an option. Does that sound okay to you?

Edit: It also works fine (with loadMainMemory) on a completely new, unanalysed file. It would still be useful to make loading main memory optional for existing files.

astrelsky commented 4 years ago

I've got it working by commenting out the call to loadMainMemory. It seems like it would be easiest to just have users import eeMemory.bin manually and then use this script for the other memory blocks, at least as an option. Does that sound okay to you?

Edit: It also works fine (with loadMainMemory) on a completely new, unanalysed file. It would still be useful to make loading main memory optional for existing files.

Did the error change after pulling the changes from a couple days ago or is it the same as above? If it is the same, changing line 87 to if (block == null && bytes.length > 0) should completely fix it, but there is no reason for buf.remaining() to return zero if buf.hasRemaining() is true.

If loadMainMemory is commented out then .bss, .sbss, .data, .sdata and what is leftover (I'm assuming its the heap) is not loaded. They are choc full of information especially since null pointers become populated.

chaoticgd commented 4 years ago

I'm now getting this:

Error running script: PCSX2SaveStateImporter.java ghidra.program.model.mem.MemoryAccessException: Memory change conflicts with instruction at 00000700 ghidra.program.model.mem.MemoryAccessException: Memory change conflicts with instruction at 00000700 at ghidra.program.database.mem.MemoryMapDB.checkRangeForInstructions(MemoryMapDB.java:2138) at ghidra.program.database.mem.MemoryMapDB.checkMemoryWrite(MemoryMapDB.java:262) at ghidra.program.database.mem.MemoryBlockDB.putBytes(MemoryBlockDB.java:344) at ghidra.program.database.mem.MemoryBlockDB.putBytes(MemoryBlockDB.java:332) at PCSX2SaveStateImporter.replaceBlock(PCSX2SaveStateImporter.java:107) at PCSX2SaveStateImporter.loadMainMemory(PCSX2SaveStateImporter.java:78) at PCSX2SaveStateImporter.run(PCSX2SaveStateImporter.java:36)

I probably should've just posted this initially. I'm not sure why exactly this isn't working, so I'm sorry I can't be more help, although it evidently seems that Ghidra doesn't want to work on files that have already been analysed (there's a disassembled function at 0x700).

astrelsky commented 4 years ago

@chaoticgd give it a shot now. I wasn't checking if the memory block was executable since I had assumed if it was writable then it wasn't executable. That should fix it, unless there are instructions in a non-executable memory block, which is just outright fishy.

chaoticgd commented 4 years ago

Looks like that fixed it. It works great now.

beardypig commented 4 years ago

Looks good to me, did you wanna make any changes @astrelsky ?

astrelsky commented 4 years ago

Looks good to me, did you wanna make any changes @astrelsky ?

Not at the moment.

beardypig commented 4 years ago

thanks @astrelsky this is a cool addition :)