Giter Site home page Giter Site logo

ghidra-emotionengine's People

Contributors

astrelsky avatar beardypig avatar chaoticgd avatar genericmadscientist avatar gregorymorse avatar harmfulbreeze avatar jayfoxrox avatar mdecicco avatar pfedak avatar rolphwoggom avatar tellowkrinkle avatar tupelov avatar velocityra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ghidra-emotionengine's Issues

VU decompilation seems unsound

Below I will attempt to argue that the current approach to decompiling VU code is detrimental and the P-Code implementation of all VU instructions should be replaced with pcodeop stubs (maybe, see below). Overall I don't find what the decompiler emits currently to be useful, although I admit that my workflow may be different to the workflow of others. As such, I want anyone who's worked with VU code in the past to weigh in below. I want to get as many opinions as I can to get more of a representative sample.

In micro mode:

  • A common mechanism for passing data between the EE core and a VU0 microprogram is to pass the data in the vf registers (e.g. the R&C games do this). This breaks data flow analysis since the value of registers being worked with will change in a way that is not predictable from the perspective of either the code running on the EE core or the VU0 microprogram. For example, a spin loop could be constructed on the EE core that waits for data on VU0 (or vice versa) by repeatedly checking the value of a specific register. This primarily seems to be a problem with instructions that transfer data between the EE core and VU0, so I suspect replacing these with pcodeop stubs would do the trick.

  • Tangentially related: Usually when I'm reversing micromode-related code on the EE core it's more convenient to extract the relevant microprogram into a seperate file. I think this means that treating VU0 as a separate processor in Ghidra would be more convenient that setting a context register. This seems like it would be a nice feature.

In macro mode:

  • Data flow analysis here seems like a much more reasonable goal, although when I see VU code, I always just drop to reading the assembly, and I don't see how anything else is really practical. As such, the main thing the decompiler could do to help me is tell me whether VU code exists. Currently, lots of VU code seems to decompile to nothing, and instructions that decompile more correctly result in long code output that is indistinguishable to regular MIPS code output, so if every instruction generated pcodeop stubs this would be helpful. Maybe this could be done optionally via a context register. I don't like having to set lots of random context registers manually, although if it's once per file I suppose that's okay. If anyone's aware of a more appropriate configuration mechanism please tell me about it.

On a side note, a lot of the MMI instructions have a similar issue in that the p-code as written produces a lot of unnecessary branches for things like clamping. I think in this case the solution could be to replace clamp operations with pcodeop stubs as well.

I've been using a modified version of ghidra-emotionengine that removes support for micromode, and replaces the implementation of all VU instructions with pcodeop stubs (basically it reverts a bunch of stuff to how it was in PR#23). I expect this would not be a good solution for merging into master as it removes some features, although I find this quite useful. It seems to be more correct and it's certainly closer to what the original code would have looked like.

I suppose the main counterargument to all of this would be that we have the disassembly, so this is at most a minor inconvenience. This is also why it took so long to file this issue, it's not exactly a deal breaker for reversing VU code. Still, my position is that correctness should be favored in this case. I don't see the point of doing all this fancy analysis if there's no guarantee that the result of said analysis is correct.

bug in master branch

Hello everyone. Found a strange bug in the master branch. Global variables are defined incorrectly. Perhaps the addiu instruction is being handled incorrectly. In version 1.6 everything is ok. Ghidra 9.2.2, 9.2.3, 9.2.4. It seems to me that this bug appeared after commits Tupelov.
Ghidra9 2 4 _master
Ghidra9 2 4 _master

Ghidra9 2 4 _1.6
Ghidra9 2 4 _1 6

Importing a save state results with an error

Everytime I tried to import a save states, this happens:

java.lang.NullPointerException
	at PCSX2SaveStateImporter.getBuffer(PCSX2SaveStateImporter.java:51)
	at PCSX2SaveStateImporter.loadMainMemory(PCSX2SaveStateImporter.java:59)
	at PCSX2SaveStateImporter.run(PCSX2SaveStateImporter.java:36)
	at ghidra.app.script.GhidraScript.executeNormal(GhidraScript.java:379)
	at ghidra.app.script.GhidraScript.doExecute(GhidraScript.java:234)
	at ghidra.app.script.GhidraScript.execute(GhidraScript.java:212)
	at ghidra.app.plugin.core.script.RunScriptTask.run(RunScriptTask.java:47)
	at ghidra.util.task.Task.monitoredRun(Task.java:124)
	at ghidra.util.task.TaskRunner.lambda$startTaskThread$0(TaskRunner.java:104)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)

---------------------------------------------------
Build Date: 2021-Mar-25 1203 EDT
Ghidra Version: 9.2.3
Java Home: C:\Program Files\AdoptOpenJDK\jdk-11.0.11.9-hotspot
JVM Version: AdoptOpenJDK 11.0.11
OS: Windows 8.1 6.3 amd64
Workstation: Girumoa


Decompiler: Unable to initialize the DecompilerInterface: java.lang.RuntimeException: No Register Defined: s8

I'm getting following exception in decompiler (Ghirda 9.0.4):

2019-07-24 14:20:30 ERROR (DecompileProcess) Unexpected Exception: No Register Defined: s8 java.lang.RuntimeException: No Register Defined: s8
	at ghidra.app.decompiler.DecompileCallback.getRegister(DecompileCallback.java:724)
	at ghidra.app.decompiler.DecompileProcess.getRegister(DecompileProcess.java:619)
	at ghidra.app.decompiler.DecompileProcess.readResponse(DecompileProcess.java:322)
	at ghidra.app.decompiler.DecompileProcess.registerProgram(DecompileProcess.java:444)
	at ghidra.app.decompiler.DecompInterface.initializeProcess(DecompInterface.java:228)
	at ghidra.app.decompiler.DecompInterface.openProgram(DecompInterface.java:314)
	at ghidra.app.decompiler.component.Decompiler.getDecompilerInterface(Decompiler.java:79)
	at ghidra.app.decompiler.component.Decompiler.decompile(Decompiler.java:48)
	at ghidra.app.decompiler.component.DecompilerManager.decompile(DecompilerManager.java:167)
	at ghidra.app.decompiler.component.DecompileRunnable.monitoredRun(DecompileRunnable.java:108)
	at ghidra.util.task.RunManager$RunnerJob.doExecute(RunManager.java:334)
	at ghidra.util.task.RunManager$RunnerJob.run(RunManager.java:309)
	at ghidra.util.worker.AbstractWorker$JobCallback.process(AbstractWorker.java:133)
	at ghidra.util.worker.AbstractWorker$JobCallback.process(AbstractWorker.java:123)
	at generic.concurrent.ConcurrentQ$CallbackCallable.call(ConcurrentQ.java:655)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at generic.concurrent.FutureTaskMonitor.run(FutureTaskMonitor.java:70)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

Am I doing something wrong or decompilation is not supported?

ghidra 9.0.4

Any chance you can find time to make a release that works with 9.0.4? I guess it's just a version number bump but 9.0.4 refuses to install the current one.

Decompiler: Deleting integrated varnodes

I haven't had time to trace what this issue is caused by but in some cases the decompiler kills itself when trying to analyze a function with error code "Low Level Error: Deleting Integrated varnodes".

Such a case can be replicated at 2ff1a4 of Kingdom Hearts 2 Final Mix ELF: SLPM_666.75

float to integer conversion

This happens everywhere the cvt.w.S instruction is followed by the mfc1 instruction. I'm not sure, but shouldn't this be decompiled to just iVar25 = fVar38?

image

Recover global GP register writes non functioning in Ghidra 10

Game: Fatal Frame 2. More specifically the European demo with the debug functionality

OS: Arch Linux

Ghidra: 10.1.4

Issue:
In Ghidra 9 any function that uses GP register for anything reads writes etc all variables and values related will resolve name-wise and appear correct. In Ghidra 10 this will not occur and all globals will appear as random addresses unless the initial value on the GP register is manually set using set register GP(64)

What it's currently showing:
Current

What it should be showing:
Should

Introducing Ghidra Emotion Engine: Reloaded!

I've created a fork of this project: Ghidra Emotion Engine: Reloaded. The first release is available here.

I believe I am in a good position to do this as I'm the third most prolific contributor to ghidra-emotionengine (according to GitHub anyway), and the first two don't seem to have the time to maintain it.

Changes (outdated)

  • Support for Ghidra 10.3.
  • The VU macro and MMI instruction implementations have been replaced with pcodeop stubs. This is a bit subjective, but I find it helps.
  • Support for disassembling VU microcode has been removed. Macro mode support is still there. If you want to reverse a VU microprogram may I suggest having a look at vutrace.
  • All the GitHub Actions workflows have been updated to work with newer versions of Ghidra, Java and Gradle.
  • 2023-02-05: A STABS symbol table analyzer is included which makes use a bundled copy of stdump to extract information about data types, functions and global variables from ELF files with a .mdebug section.

Support automated build for latest ghidra version

https://github.com/er28-0652/setup-ghidra#version supports "latest" as version.
(Edit: I tried using it, but it didn't work, see er28-0652/setup-ghidra#14)

Support for this should be added to the Actions workflow, so the nightly build is always up-to-date (avoiding some of #60, #64, #65).
This definitely makes sense for the nightly workflow, maybe not so much for publish workflow (as a sudden new release could break a final build).
For the testing workflow it depends (as frequent breakage would be more likely, but it might not be intended to have a "build broken" badge in the README).

Ghidra 9.2 support

Ghidra 9.2 released and trying to compile this results in the following error:

ghidra-emotionengine/src/main/java/ghidra/emotionengine/MipsR5900AddressAnalyzer.java:335: error: cannot find symbol
                                                          instr.getMinAddress().getAddressSpace().getBaseSpaceID(),
                                                                                                 ^
  symbol:   method getBaseSpaceID()
  location: interface AddressSpace

Strange right shift after multiplication

I came across the following code snippet (well, there was a bit more but I've trimmed it down):

li v0, 0x350
mult v1, side, v0
jr ra
addu v0, v0, v1

Ghidra incorrectly gives (iParam1 * 0x350) >> 0x20 + 0x350, where the correct result would not have the right shift.

I was able to reproduce this with a small file just containing the above four instructions, which I've given here: a-minimal-example.zip.

Mangled decompilation for pairs of ldl/ldr and sdl/sdr

image
Pairs of ldl/ldr and sdl/sdr are decompiled strangely. I may be wrong about this, but I believe that when the sdl and sdr instructions come in pairs like this and both have the same register as the first operand (and when the second operands together refer to the space that a doubleword would fit in) it is essentially just a store of a double word. I found this code in the MIPS language in the ghidra repo which seems to deal with just this: here ... and here.

This seems to rely on PAIR_INSTRUCTION_FLAG which as far as I was able to understand might be referring to a single bit in the data that encodes the instruction. I did some research and even looked through the PCSX2 source code but wasn't able to determine if such a pair instruction flag exists for R5900 instructions. Here's how it's defined in mips.sinc ... and in mips64.pspec

Is there any way to add behavior like this to ghidra-emotionengine? I am more than willing to write an analyzer or modify the language files and submit a pull request, I'd just need a few hints about what needs to be done in general as I'm still new to reverse engineering and don't fully understand things as low level as this.

EDIT:
I used the disassembly from IDA in the screenshot just because the disassembly in ghidra is cluttered with local variable names and I wanted it to be more clear what the intent of the instructions is.

The ldl/ldr/lw instructions don't seem to correspond to any of the code in the decompilation view. I'm not sure what that's about.

Ghidra 10.2.x

Don't want to be that guy but is the plugin working on latest Ghidra 10.2?

Function IDs

Function analysis being on the TODO list would imply Function IDs/FID Databases don't work with this at the moment, correct?

Undefined pcodeops

The pcodeops in the eecore.sinc aren't actually doing anything as they aren't defined in the java lib. There is information on how to do so at the bottom of mips.sinc

I will put in a PR later today after class and we can merge the work we have done.
https://github.com/astrelsky/ghidra_MIPSR5900

Incorrect handling of vu addressing

The addresses for the vu upper and lower instructions are currently hardcoded in the sleigh files. Instead a separate address space should be created with the correct word size (it isn't 1) and explicitly used for dereferencing in these instructions.

Will edit with correct terminology later.

The $gp is slightly off

In a game where $gp should be $13ec70, ghidra is assuming it is $14ec70.

The "Register Manager" has

start        end         value
0x100008     0x100008    0x13ec70  ;; this is correct
0x1000b8     0x1000b8    0x14ec70
0x1000c0     0x1000c0    0x14ec70
...

Ghidra 10.0 support

Ghidra 10 will release very soon, and it has some radical changes to the Pcode injection stuff, so bitrot in ghidra-emotionengine sets in:

Some changes which have to do with this (5 minute job of git blame; but I have no idea what I'm doing, because the Ghidra codebase is so convoluted):

Motivation

Ghidra 10 has a couple of killer features:

  • Better re-export of ELF files
  • Support for for-loop in decompiler
  • Support for new gradle versions
  • Better SLEIGH emulation interface
  • Tracing and debugging

Random number generator instructions are not injected (vrget, vrinit, vrnext, vrxor)

The instructions are declared, but don't seem to be injected:

define pcodeop VRGET;
define pcodeop VRINIT;
define pcodeop VRNEXT;

Implementations can be found in PCSX2:

(In a function which uses these instructions, the decompiler also complains about "Low-level Error: Overlapping input varnodes", and I suspect it could be related)

Incorrect disassembly for ctc2 instruction

"00 08 cf 48" disassembles to "ctc2.I t7,CMSAR0" but should disassemble to "ctc2.I t7,vi1". This makes much more sense given the code I've seen that uses it, and is how PCSX2 disassembles it.

ADDIU's immediate value isn't properly sign-extended.

In the instruction addiu v0, zero, 0xFFFF, v0 is supposed to end up with the value 0xFFFFFFFF because the literal is sign-extended to a 32-bit value. However, Ghidra says it ends up with the value 0xFFFF. This error does not happen with the version of MIPS that comes with Ghidra that I also checked this with.

EI/DI decompile improperly

The EI and DI instructions modify bit 16 of the COP0 Status register, or the master interrupt enable. However, decompilation shows them as having the effect of Status = Status & 0xFFFFFFFE in the case of DI, which is incorrect.

A cleaner solution imo would be to decompile these instructions as EI() and DI() as if they were functions or macros.

[Feature Request] Syscall support (or only arguments)

  • By "only arguments" I mean the feature of being able to at least have syscall calls in the decompiler show arguments. Ghidra doesn't let you re-define that syscall function (I assume it's a special kind of func defined somewhere), I'm not sure how to go about it from the GUI. But I assume that the extension is able to, somehow?
    I'd be useful to re-define it as syscall(void *arg1, void *arg2, void *arg3) etc to at least aid with capturing arguments passed into it.

  • By "syscall support" I mean the more fully-fledged feature of having a hardcoded list of the syscalls in the extension (ID -> syscall proto), and on each syscall instruction the right one recognized from the value loaded in v1 and communicated with the decompiler to show it as the correct function (name + signature).

Instruction Parsing Problems

It seems at least one instruction is not parsed properly by Ghidra.
I have built a .S file. When I open the resulting ELF file in Ghidra, it misidentifies some of the instructions.

The .S file:
image

Ghidra
image

NOTE: The reason the .S file looks funky is because it's auto-generated.

dsra32 Special Case

I ran across a problem (?) with the special case for dsra32. When the function in data/languages/mips.sinc (line 251) is left with empty brackets API functions such as getOperandRefType(x) will return None when it should return an appropriate value. I copied the implementation above it (the non-special case for dsra32) and functionality worked as expected, for me anyway. Also, right-clicking and selecting "Instruction Info..." shows missing Input Objects and Results Objects.

From this instruction:
Screen Shot 2021-05-03 at 12 29 34 PM

Before populating the function:
Screen Shot 2021-05-03 at 12 25 03 PM

After populating the function:
Screen Shot 2021-05-03 at 12 24 02 PM

This is the only change I made to achieve that result:
Screen Shot 2021-05-03 at 12 27 56 PM

I didn't want to make this a pull request because I don't know enough about Ghidra internals to know if this change will break something else.

Issue with 'Error in plugin event listener'

Whenever I try to open the Yu-Gi-Oh! The Duelists of the Roses Japanese ELF I get an 'Error in plugin event listener'. This happens even if I start a new project with said ELF and try to import it as a raw binary using the MIPS R5900 instruction set. Here is said ELF

`vmadd^bc^dest` not respected in decompiler output

I'm using the version from #65 with Ghidra 9.2.4 (although I don't think that's causing the issue).

C code generated for Renderware matrix multiplication:

void RwMatrixMultiply(float *param_1,float *param_2,float *param_3)

{
  float fVar1;
  float fVar2;
  float fVar3;
  float fVar4;
  float fVar5;
  float fVar6;
  float fVar7;
  float fVar8;
  float fVar9;
  float fVar10;
  float fVar11;
  float fVar12;
  float fVar13;
  float fVar14;
  float fVar15;
  float fVar16;
  float fVar17;
  float fVar18;
  float fVar19;
  float fVar20;
  float fVar21;
  float fVar22;
  float fVar23;
  float fVar24;
  float fVar25;
  float fVar26;
  float in_vf9w;
  float in_vf10w;
  float in_vf11w;
  float in_vf12w;
  
  fVar3 = *param_2;
  fVar4 = param_2[1];
  fVar5 = param_2[2];
  fVar6 = param_2[4];
  fVar7 = param_2[5];
  fVar8 = param_2[6];
  fVar9 = param_2[8];
  fVar10 = param_2[9];
  fVar11 = param_2[10];
  fVar12 = param_2[0xc];
  fVar13 = param_2[0xd];
  fVar14 = param_2[0xe];
  fVar1 = param_2[3];
  fVar15 = *param_3;
  fVar16 = param_3[1];
  fVar17 = param_3[2];
  fVar18 = param_3[4];
  fVar19 = param_3[5];
  fVar20 = param_3[6];
  fVar21 = param_3[8];
  fVar22 = param_3[9];
  fVar23 = param_3[10];
  fVar24 = param_3[0xc];
  fVar25 = param_3[0xd];
  fVar26 = param_3[0xe];
  fVar2 = param_3[3];
  *param_1 = fVar15 * fVar3 + fVar18 * fVar4 + fVar21 * fVar5;
  param_1[1] = fVar16 * fVar3 + fVar19 * fVar4 + fVar22 * fVar5;
  param_1[2] = fVar17 * fVar3 + fVar20 * fVar4 + fVar23 * fVar5;
  param_1[3] = in_vf9w;
  param_1[4] = fVar15 * fVar6 + fVar18 * fVar7 + fVar21 * fVar8;
  param_1[5] = fVar16 * fVar6 + fVar19 * fVar7 + fVar22 * fVar8;
  param_1[6] = fVar17 * fVar6 + fVar20 * fVar7 + fVar23 * fVar8;
  param_1[7] = in_vf10w;
  param_1[8] = fVar15 * fVar9 + fVar18 * fVar10 + fVar21 * fVar11;
  param_1[9] = fVar16 * fVar9 + fVar19 * fVar10 + fVar22 * fVar11;
  param_1[10] = fVar17 * fVar9 + fVar20 * fVar10 + fVar23 * fVar11;
  param_1[0xb] = in_vf11w;
  param_1[0xc] = fVar15 * fVar12 + fVar18 * fVar13 + fVar21 * fVar14 + fVar24 * 1.0;
  param_1[0xd] = fVar16 * fVar12 + fVar19 * fVar13 + fVar22 * fVar14 + fVar25 * 1.0;
  param_1[0xe] = fVar17 * fVar12 + fVar20 * fVar13 + fVar23 * fVar14 + fVar26 * 1.0;
  param_1[0xf] = in_vf12w;
  param_1[3] = (float)((uint)fVar2 & (uint)fVar1);
  return;
}

(Let's ignore the weird stuff in param_1[3] for now, and focus on in_vf*)

Relevant disassembly:

[...]
0000cfec bc 29 c1 4b  	   vmulax.xyz ACC,vf5,vf1x
0000cff0 bd 30 c1 4b  	   vmadday.   ACC,vf6,vf1y
0000cff4 4a 3a c1 4b  	   vmaddz.xyz vf9,vf7,vf1z
0000cff8 bc 29 c2 4b  	   vmulax.xyz ACC,vf5,vf2x
0000cffc bd 30 c2 4b  	   vmadday.   ACC,vf6,vf2y
0000d000 8a 3a c2 4b  	   vmaddz.xyz vf10,vf7,vf2z
0000d004 bc 29 c3 4b  	   vmulax.xyz ACC,vf5,vf3x
0000d008 bd 30 c3 4b  	   vmadday.   ACC,vf6,vf3y
0000d00c ca 3a c3 4b  	   vmaddz.xyz vf11,vf7,vf3z
0000d010 bc 29 c4 4b  	   vmulax.xyz ACC,vf5,vf4x
0000d014 bd 30 c4 4b  	   vmadday.   ACC,vf6,vf4y
0000d018 be 38 c4 4b  	   vmaddaz.   ACC,vf7,vf4z
0000d01c 0b 43 c0 4b  	   vmaddw.xyz vf12,vf8,vf0w
0000d020 24 18 64 00  	   and        v1,v1,a0
0000d024 00 00 49 f8  	   sqc2       vf9,0x0(v0)
0000d028 10 00 4a f8  	   sqc2       vf10,0x10(v0)
0000d02c 20 00 4b f8  	   sqc2       vf11,0x20(v0)
0000d030 30 00 4c f8  	   sqc2       vf12,0x30(v0)
[...]

As you can see, this writes vf9, vf10, vf11 and vf12 from vmaddz.xyz and friends, but the decompiler claims that this write never happens. Therefore it depends on in_vf*, which is incorrect.

Initially I thought P-Code was simply not implemented, but it looks like it should happen here:

instructions.put(PcodeInjectLibraryVu.VMADDBC, InjectPayloadVu::getMultiplyOperationText3);

Do I manually have to trigger P-Code injection or is there a bug?

PCSX2SaveStateImporter doesn't run in Ghidra 9.2

Attempting to run PCSX2SaveStateImporter in Ghidra 9.2.0 results in

ImportMMIORegisterLabels.java:30: error: incompatible types: java.util.List<ghidra.program.model.lang.Register> cannot be converted to ghidra.program.model.lang.Register[]
        Register[] registers = currentProgram.getLanguage().getRegisters();
                                                                        ^
PCSX2SaveStateImporter.java:100: error: initializeBlock(byte) is not public in ghidra.program.database.mem.MemoryBlockDB; cannot be accessed from outside package
                ((MemoryBlockDB) block).initializeBlock((byte) 0);
                                       ^
skipping ~/.ghidra/.ghidra_9.2_PUBLIC/Extensions/ghidra-emotionengine/ghidra_scripts/PCSX2SaveStateImporter.java
skipping ~/.ghidra/.ghidra_9.2_PUBLIC/Extensions/ghidra-emotionengine/ghidra_scripts/ImportMMIORegisterLabels.java
> Unable to locate script class: PCSX2SaveStateImporter.java

PCSX2SaveStateImporter: IllegalArgumentException: newPosition > limit

Whenever I want to load a save state (.p2s file) I'm getting the following error.
Am I using it wrong or is there a bug?

newPosition > limit: (34822610 > 33554432)
java.lang.IllegalArgumentException: newPosition > limit: (34822610 > 33554432)
	at java.base/java.nio.Buffer.createPositionException(Buffer.java:341)
	at java.base/java.nio.Buffer.position(Buffer.java:316)
	at java.base/java.nio.ByteBuffer.position(ByteBuffer.java:1516)
	at PCSX2SaveStateImporter.loadMainMemory(PCSX2SaveStateImporter.java:82)
	at PCSX2SaveStateImporter.run(PCSX2SaveStateImporter.java:36)
	at ghidra.app.script.GhidraScript.executeNormal(GhidraScript.java:397)
	at ghidra.app.script.GhidraScript.doExecute(GhidraScript.java:252)
	at ghidra.app.script.GhidraScript.execute(GhidraScript.java:230)
	at ghidra.app.plugin.core.script.RunScriptTask.run(RunScriptTask.java:47)
	at ghidra.util.task.Task.monitoredRun(Task.java:134)
	at ghidra.util.task.TaskRunner.lambda$startTaskThread$0(TaskRunner.java:106)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:833)

---------------------------------------------------
Build Date: 2023-May-10 1508 EDT
Ghidra Version: 10.3
Java Home: C:\Program Files\Java\jdk-17.0.2
JVM Version: Oracle Corporation 17.0.2
OS: Windows 11 10.0 amd64
Workstation: ***********

decompilation: pushing to the stack in function prologue is wonky

Function prologue is decompiled as

  undefined unaff_s0_qw [16];
  int iVar2;
  undefined8 in_ra;
  
  iVar2 = (int)register0x000001d0;
  _iVar2 = (void **)(longlong)(int)(undefined8 *)(iVar2 + -0x30);
  *(undefined8 *)(iVar2 + -0x10) = in_ra;
                    /* WARNING: Store size is inaccurate */
  *(undefined *)(iVar2 + -0x20) = unaff_s0_qw;

from the following dissasembly

addiu sp,sp,-0x30
sd   ra,0x20(sp)
sq   s0,0x10(sp)

The function epilogue is fine.

Relocations are broken

It appears that relocations are currently being applied incorrectly. For example, in Dark Cloud, in EscapeDungeonMode there should be a jump to SearchItemIndexNo like this:

001f3f58 50 f6 06 0c jal CDngStatusData::SearchItemIndexNo undefined SearchItemIndexNo(int param_1)

However, instead, the jump is to an invalid address like this:

001f3f58 a0 ec 0d 0c jal SUB_0037b280

If you look in Ghidra' relocation table view, you can see that this is due to a relocation at this address (which is incorrect):

001f3f58 0x4 0x2c1d 50 f6 06 0c SearchItemIndexNo__14CDngStatusDataFi

Both IDA and ps2dis do not alter the initial value and produce correct results. This can be seen in a number of other places too, but I picked one example for convenience.

Vector/matrix decompilation ergonomics

I've been looking at some functions that do relatively large amounts of vector math (~2000 total instructions, about 300 v* instructions). On my system, some of these take 50-60 seconds to decompile, and even then the output for several matrix multiplies is easier to read from the assembly since ghidra splits them into sets of 16 parallel equations.

On the timing point, I'm very eager to hear suggestions for profiling and investigating further, but in my desperate attempts to improve the situation I found that replacing the injected java VU commands with pure pcode versions (with heavy use of macros, including MAC and status logic) cut the time in half. I'm happy to make a PR with my changes, but that may not be a direction you want to move in. I can send one of the functions if that would make testing easier, but I'm not sure the best format. Just raw binary?

For the output, I'm assuming original code used some form of macros. I'd love to see blocks of the form

    lqc2 vf24, 0x0(a0)
    lqc2 vf25, 0x10(a0)
    lqc2 vf26, 0x20(a0)
    lqc2 vf27, 0x30(a0)

and

    vmulax.xyzw ACC, vf24, vf28x
    vmadday.xyzw ACC, vf25, vf28y
    vmaddaz.xyzw ACC, vf26, vf28z
    vmaddw.xyzw vf28, vf27, vf28w

condensed into some more simplified form, but I'll believe you if this just isn't feasible (or desired).

ghidra-emotionengine doesn't open! BAD MANUALS!!!

FAILURE: Build failed with an exception.

  • Where:
    Build file 'C:\Users\taras\Desktop\ghidra\EX\ghidra-emotionengine-master\build.gradle' line: 34

  • What went wrong:
    A problem occurred evaluating root project 'ghidra-emotionengine-master'.
    GHIDRA_INSTALL_DIR is not defined!

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more lag output. Run with
    --scan to get full insights.

  • Get more help at https://help.gradle.org

BUILD FAILED in 1s

"MIPS UnAlligned Instruction Fix" java.lang.NullPointerException

Attempted to disassemble Persona 3 (original), US, got this lovely error. Using the latest release w/e
https://github.com/beardypig/ghidra-emotionengine/releases/tag/v1.3.3

Analysis Task: MIPS UnAlligned Instruction Fix - 
java.lang.NullPointerException
	at ghidra.program.util.AbstractStoredProgramContext.getRegisterValue(AbstractStoredProgramContext.java:146)
	at ghidra.program.util.AbstractStoredProgramContext.getRegisterValue(AbstractStoredProgramContext.java:105)
	at ghidra.program.util.AbstractStoredProgramContext.getValue(AbstractStoredProgramContext.java:121)
	at ghidra.app.plugin.core.analysis.MipsPreAnalyzer.findPair(MipsPreAnalyzer.java:208)
	at ghidra.app.plugin.core.analysis.MipsPreAnalyzer.added(MipsPreAnalyzer.java:115)
	at ghidra.app.plugin.core.analysis.AnalysisScheduler.runAnalyzer(AnalysisScheduler.java:185)
	at ghidra.app.plugin.core.analysis.AnalysisTask.applyTo(AnalysisTask.java:39)
	at ghidra.app.plugin.core.analysis.AutoAnalysisManager$AnalysisTaskWrapper.run(AutoAnalysisManager.java:685)
	at ghidra.app.plugin.core.analysis.AutoAnalysisManager.startAnalysis(AutoAnalysisManager.java:785)
	at ghidra.app.plugin.core.analysis.AutoAnalysisManager.startAnalysis(AutoAnalysisManager.java:664)
	at ghidra.app.plugin.core.analysis.AutoAnalysisManager.startAnalysis(AutoAnalysisManager.java:629)
	at ghidra.app.plugin.core.analysis.AnalysisBackgroundCommand.applyTo(AnalysisBackgroundCommand.java:62)
	at ghidra.framework.plugintool.mgr.BackgroundCommandTask.run(BackgroundCommandTask.java:101)
	at ghidra.framework.plugintool.mgr.ToolTaskManager.run(ToolTaskManager.java:315)
	at java.base/java.lang.Thread.run(Thread.java:834)

---------------------------------------------------
Build Date: 2019-Feb-28 1236 EST
Ghidra Version: 9.0
Java Home: C:\Program Files\Java\jdk-11.0.2
JVM Version: Oracle Corporation 11.0.2
OS: Windows 10 10.0 amd64
Workstation: DESKTOP-HLKIA3M
Analysis Task: MIPS UnAlligned Instruction Fix - 
java.lang.NullPointerException

---------------------------------------------------
Build Date: 2019-Feb-28 1236 EST
Ghidra Version: 9.0
Java Home: C:\Program Files\Java\jdk-11.0.2
JVM Version: Oracle Corporation 11.0.2
OS: Windows 10 10.0 amd64
Workstation: DESKTOP-HLKIA3M
Analysis Task: MIPS UnAlligned Instruction Fix - 
java.lang.NullPointerException

---------------------------------------------------
Build Date: 2019-Feb-28 1236 EST
Ghidra Version: 9.0
Java Home: C:\Program Files\Java\jdk-11.0.2
JVM Version: Oracle Corporation 11.0.2
OS: Windows 10 10.0 amd64
Workstation: DESKTOP-HLKIA3M

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.