XenonRecomp icon indicating copy to clipboard operation
XenonRecomp copied to clipboard

Analyzer does not output toml

Open AzaleaCatgirl99 opened this issue 9 months ago • 19 comments

I tried to use the XenonAnalyze.exe to output Minecraft: Xbox 360 Edition's jump tables to a toml, but it does not seem to create any toml in the path I specified. Nothing shows up in the terminal either

AzaleaCatgirl99 avatar Mar 02 '25 02:03 AzaleaCatgirl99

Looking to start a static recomp project of Minecraft so any help would be nice

AzaleaCatgirl99 avatar Mar 02 '25 02:03 AzaleaCatgirl99

Right so apparently I was building in Release rather than Debug, and also not specifying a toml output. Now it creates the toml, but doesn't actually get the jump tables

Image

AzaleaCatgirl99 avatar Mar 02 '25 03:03 AzaleaCatgirl99

Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has.

The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253

See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.

blueskythlikesclouds avatar Mar 02 '25 04:03 blueskythlikesclouds

Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has.

The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253

See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.

i see, i'm finding some differences like for example the "computedSwitch" in Minecraft is:

Image

AleBello7276 avatar Mar 02 '25 06:03 AleBello7276

Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has.

The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253

See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.

Hello, I have found many such patterns inside of Tetris The Grand Master: Ace, but for some reason XenonAnalyse doesn't output any .toml after running for a little while. I tried it on other games and it did give out either empty or filled tmls, so this behaviour is quite intriguing.

Image

Also, is XenonRecomp supposed to Decompile the game's executable even if it doesn't happen to find any jumptables ? I made a .toml file that doesn't have much information but should still give some basic information to the tool I think

[main]
file_path = "tgma.xex"
out_directory_path = "../tgma"

skip_lr = false
skip_msr = false
ctr_as_local = false
xer_as_local = false
reserved_as_local = false
cr_as_local = false
non_argument_as_local = false
non_volatile_as_local = false

restgprlr_14_address = 0x823100F0
savegprlr_14_address = 0x823100A0
restfpr_14_address = 0x8231019C
savefpr_14_address = 0x82310150
restvmx_14_address = 0x823170F8
savevmx_14_address = 0x82316E60
restvmx_64_address = 0x8231718C
savevmx_64_address = 0x82316EF4

longjmp_address = 0x823191E0
setjmp_address = 0x82319300

invalid_instructions = [
    { data = 0x00000000, size = 4 }, # Padding
    { data = 0x8233ba2c, size = 8 }  # C Specific Frame Handler 
]

Sorry, I'm not really looking to get all the work chewed and have a step by step tutorial brought on the table to me, but I don't think I left anything out in what was written for the README

Also, if it can help, I compiled the tool with MSYS2 CLANG64 and Ninja, as a Debug project.

Sakimotor avatar Mar 02 '25 20:03 Sakimotor

Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has.

The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253

See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.

The PVZ 360 port also seems to be different than unleashed, giving an empty toml file. Building debug on CLang MSVC with Ninja.

Edit: either way i'm looking forward to any progress being made on other games, to look at how this kind of stuff can be fixed. I know its super early on in development.

Kade-github avatar Mar 03 '25 03:03 Kade-github

When attempting to run XenonAnalyze on default.xex, it complains about compression type. PS ...\XenonRecomp\build\XenonAnalyse> .\XenonAnalyse.exe ...\nfsmw\default.xex ...\mwrecomp\jumplist.toml Assertion failed: fileFormatInfo->compressionType <= XEX_COMPRESSION_BASIC, file ...\XenonRecomp\XenonUtils\xex.cpp, line 138

After decompressing the xex with xextool, process finishes without any errors; PS ...\XenonRecomp\build\XenonAnalyse> .\XenonAnalyse.exe ...\nfsmw\uncompressed.xex ...\mwrecomp\jumplist.toml PS ...\XenonRecomp\build\XenonAnalyse>

However, the toml is never written. Issue does not occur with other games such as WWE 2007.

koffiato avatar Mar 03 '25 15:03 koffiato

@koffiato I seem to have a similar issue with Outrun: Online Arcade!

The raw default.xex I extracted from the Xbox Live Arcade container using wxPirs, the result reports as:

Xex Info
  Retail
  Compressed
  Encrypted
  Title Module
  No ODD Mapping
  Uses Game Voice Channel
  Pal50 Incompatible
  Xbox360 Logo Data Present

on XexTool and when I run XenonAnalyze on it it segfaults similarly to #15, when debugging the segfault with GDB I get a:

Program received signal SIGSEGV, Segmentation fault.
0x000055555557ac39 in Xex2LoadImage(unsigned char const*, unsigned long) ()

which looking at the sources, specifically this part, looks to me as if this is an issue with processing the compression or encryption of my Xex file.

After seeing issue #10 I tried to use XexTool to uncompress and decrypt my default.xex with the following command xextool -o decunc.xex -c b -e u default.xex.

However after running ./XenonAnalyse decunc.xex test.toml which runs for some time and looks as if it is working, my test.toml outputs empty with only comments being present (on GDB I get a [Inferior 1 (process 12767) exited normally] as if everything went well).

Just in case this is a concern, my decrypted and uncompressed binary (decunc.xex) works just fine on xenia when paired up with other game assets so the XexTool output is valid for sure.

paranoidnela avatar Mar 03 '25 22:03 paranoidnela

used .\xenonanalyse.exe E:\xenonrecomp\artifacts\dah\default.xex E:\xenonrecomp\artifacts\dah default.toml and do not get a default.toml file for destroy all humans path of the furon. had 0 problems getting the file yesterday

Edit 03/05/2025: i figured it out, it works if i dont put the output directory and just do .\xenonanalyse.exe E:\xenonrecomp\artifacts\dah\default.xex default.toml, it then spits the toml file into the xenonanalyse folder

masterspike52 avatar Mar 05 '25 01:03 masterspike52

There is a pattern that can be used for some games that is:

PPC_INST_LIS, PPC_INST_RLWINM, PPC_INST_SUBI, PPC_INST_LWZX, PPC_INST_MTSPR

OR

PPC_INST_LIS, PPC_INST_RLWINM, PPC_INST_ADDI, PPC_INST_LWZX, PPC_INST_MTSPR


I believe there is currently a parsing error when reading in the opcodes where PPC_INST_MTSPR is not being properly parsed as I know that instruction is in the binary in the order that I am passing in, but I never hit my breakpoint that says we found any of them in the binary. Commenting the PPC_INST_MTSPR out makes it catch these switch cases, but it would be ideal if PPC_INST_MTSPR could properly get parsed.

ffio1 avatar Mar 06 '25 01:03 ffio1

Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has. The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253 See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.

i see, i'm finding some differences like for example the "computedSwitch" in Minecraft is:

Image

Forgive me for asking, but how exactly did you identify this as a computeSwitch? I am new to this and trying to take a crack it it via Asura's Wrath, and I would like to know how I know what jumptables I'm looking at as I parse the instructions, please

SEGFAULT3102 avatar Mar 07 '25 03:03 SEGFAULT3102

Looking to start a static recomp project of Minecraft so any help would be nice

i was also wanting to do this, i can help with it

TheAwesome98-Real avatar Mar 07 '25 10:03 TheAwesome98-Real

Right so apparently I was building in Release rather than Debug, and also not specifying a toml output. Now it creates the toml, but doesn't actually get the jump tables

Image

I am also getting an empty TOML using the xex from The Fancy Pants Adventures with XenonAnalyze, had to change compression with xextool since the compression level was above XEX_COMPRESSION_BASIC

Fancy2209 avatar Mar 07 '25 16:03 Fancy2209

Same as @Fancy2209 with Skate 3

delebota avatar Mar 09 '25 07:03 delebota

From some reading, I believe Recompiler's analyzer is more robust than Xenon's, at least in the sense it doesn't depend on a Specific MSVC version

Fancy2209 avatar Mar 09 '25 15:03 Fancy2209

From some reading, I believe Recompiler's analyzer is more robust than Xenon's, at least in the sense it doesn't depend on a Specific MSVC version

Would there be any way to use that analyser then use the result from that in XenonRecomp?

PopTartsWasTaken avatar Mar 14 '25 18:03 PopTartsWasTaken

Sorry, the release of UnleashedRecomp has been a bit chaotic so I might not be able to give help immediately. Like I say in the README, the patterns of the jump tables might differ between games, so it's possible the existing pattern checks don't match what this game has. The patterns expected in Sonic Unleashed are here: https://github.com/hedge-dev/XenonRecomp/blob/main/XenonAnalyse/main.cpp#L253 See if you can find anything similar. It's also possible the pattern is part of the optimization process in newer Xbox 360 compiler versions which would unfortunately heavily complicate this.

i see, i'm finding some differences like for example the "computedSwitch" in Minecraft is: Image

Forgive me for asking, but how exactly did you identify this as a computeSwitch? I am new to this and trying to take a crack it it via Asura's Wrath, and I would like to know how I know what jumptables I'm looking at as I parse the instructions, please

I also dont understand how you make this detemination. Could you please explain. Also, how can you get the jump table to detect ori and subi instructions. Ive been trying for a while but with no luck.

Organizationguy avatar Apr 02 '25 20:04 Organizationguy

There is a pattern that can be used for some games that is:

PPC_INST_LIS, PPC_INST_RLWINM, PPC_INST_SUBI, PPC_INST_LWZX, PPC_INST_MTSPR

OR

PPC_INST_LIS, PPC_INST_RLWINM, PPC_INST_ADDI, PPC_INST_LWZX, PPC_INST_MTSPR

I believe there is currently a parsing error when reading in the opcodes where PPC_INST_MTSPR is not being properly parsed as I know that instruction is in the binary in the order that I am passing in, but I never hit my breakpoint that says we found any of them in the binary. Commenting the PPC_INST_MTSPR out makes it catch these switch cases, but it would be ideal if PPC_INST_MTSPR could properly get parsed.

(Sorry if this is reviving an old issue but seems to be still referenced) It looks like those using Ghidra will see the opcodes without simplified mnemonics - meaning that if you're using another tool such as IDA, you may see the opcodes in their simplified form instead. For instance, two of them I've come across for Dance Central:

In Ghidra: Image

In IDA Pro: Image

In this example, IDA shows the instructions slwi and mtctr, however Ghidra shows rlwinm and mtspr respectively. It appears that XenonAnalyse will parse the opcodes using their simplified forms, so swapping those out from original to simplified should help pick up the jump tables properly once identified. (There are other differences too as to how IDA and Ghidra parse out other instructions, but this should at least explain simplified ones.)

For those interested, doing a quick search on "ppc simplified mnemonics" should bring up a document that explains all of the variations you may come across.

capnkenny avatar Aug 01 '25 12:08 capnkenny

Forgive me for asking, but how exactly did you identify this as a computeSwitch? I am new to this and trying to take a crack it it via Asura's Wrath, and I would like to know how I know what jumptables I'm looking at as I parse the instructions, please

Not sure how everyone else is doing it but sharing my method in case someone has a better one:

Context: C++ code has often switch/case code flows, to the way those are translated to machine code depends on the compiler/version/options. So you need to adjust XenonAnalyse to match what your xex is using.

Step 0: Extract default.xex from your iso with XGDTool, decrypt and unpack the xex with xextool. Make sure you have the xex plugin installed in Ghidra (https://github.com/zeroKilo/XEXLoaderWV), load the xex and analyze it.

Step 1: When analysis is finished, go to Search menu and pick "Decompiled text..." then search text "switch(" without quotes but with open parenthesis. Inspect all the instances one by one until you find all the different patterns below.

Pattern 1: Value for mtspr loaded from memory => Absolute lwzx r0, r12 mtspr CTR, r0

Pattern 2: Value loaded and then rlwin before added => Computed lbzx r0, r12, r10 rlwinm r0, r0, 0x2, 0x0, 0x1d ... add r12, r12, r0 mtspr CTR, r12

Pattern 3: Byte loaded and added as is => offsetSwitch lbzx r0, r12 ... add r12, r12, r0 mtspr CTR, r12

Pattern 4: Half loaded and added as is => wordOffsetSwitch lhzx r0, r12 ... add r12, r12, r0 mtspr CTR, r12

Step 2: When you found the code patterns, you need to edit the switch tables of main.cpp for XenonAnalyse. Things to keep in mind if you use Ghidra to pick the right op code.

  • Ghidra shows subi but you should use addi. Example: 39 8c b0 0c subi r12, r12, 0x4ff4 Since the first two bytes are 39 8c, use PPC_INST_ADDI in the search pattern

  • Ghidra shows ori but you should use nop. Example: 60 00 00 00 ori r0, r0, 0x0 Since the code is the same as nop, use PPC_INST_NOP in the search pattern

  • Ghidra shows mtspr CTR, r12 but you should use PPC_INST_MTCTR in the search pattern

Step 3: Fix ReadTable function in main.cpp of XenonAnalyse to match the pattern offsets you found.

ppc::Disassemble(code + 4, table.base + 0x10, insn); base = insn.operands[1] << 16;

ppc::Disassemble(code + 5, table.base + 0x14, insn); base += insn.operands[2];

For example SWITCH_SHORTOFFSET got the value loaded in R12 from the original pattern from the 4th and 5th code lines in the pattern. Which might be something like this in the xex lis r12, -0x7dd4 addi r12, r12, 0x3870

Step 4: If any of your tables does has anything between the very first lis and addi, make sure you edit the computation of pOffset in ReadTable to match your pattern.

Nitch2024 avatar Sep 20 '25 01:09 Nitch2024