cseagle / blc

Integrate Ghidra's decompiler as an Ida plugin
GNU General Public License v2.0
414 stars 48 forks source link

Add support for Xbox360 executables #2

Closed emoose closed 4 years ago

emoose commented 4 years ago

This lets blc create the right sleigh ID for Ghidra to decompile Xbox360 code (at least I think it's the right sleigh ID - zeroKilo's X360 Ghidra loader uses it, so I assume it's correct)

With this in place, it'll now decompile both Xbox360 EXEs and signed XEX files fine.

It sets this based on the ABI name being "xbox", my IDA XEX loader plugin will set it to this ABI, and it seems IDA itself also sets this ABI when loading in an Xbox360 EXE file.

There does seem to be some issues with function parameters though, instead of using param_1 inside the decompiled output it'll use the return code from __savegprlr_xx(), which is weird since that shouldn't be returning anything... (eg: https://i.imgur.com/OiSW6e8.png, the uses of iVar3 here should be using param_1 instead...)

The other parameters don't seem to be affected. Not sure if this is a Ghidra issue or maybe something to do with the integration... at least it's not too big of a problem, other than that everything else seems to work fine.

EDIT: If you want to test it out, here's a link to an old update XEX that used to be freely available on Microsoft's website: http://www.crusaders.no/~joker/old_web/lotto/default.xex You'll need my XEX loader to load it into IDA though (Windows-only atm), sadly I'm not aware of any freely available X360 EXE files you could test with.

cseagle commented 4 years ago

My guess is that Ghidra understands that iVar3 is associated with GPR3 (as is param_1) but savegprlr_28() is called before param_1 is used in the function and Ghidra thinks that savegprlr_28(), being a function, returns a new value in GPR3. Making __savegprlr_28() a void function is not enough to get Ghidra to behave properly because GPR3 is a callee saved register and Ghidra has no way to know that __savegprlr_28() doesn't touch GPR3. If it could be made to understand that fact, it might then be able to understand the iVar3 is the same as param_1

aerosoul94 commented 4 years ago

The wrong compiler spec is being used. What you want is PowerPC:BE:64:A2ALT-32addr which includes Altivec. The Xbox 360 does not support VLE. Though Ghidra is still missing support for VMX128, it should allow disassembling Altivec instructions.

You should be able to fix the savegprlr issue by setting the signature to void (void). At least, that works in Ghidra.

cseagle commented 4 years ago

I'm in the process of updating the compiler spec. The savegplr issue will take longer. blc is not currently passing function prototypes to the ghidra code, and the non-standard treatment of GPR3 will be difficult to model I think.

aerosoul94 commented 4 years ago

I don't believe it will be an issue once function signatures are implemented into blc. We can see here that the issue is resolved in Ghidra once you set the signature to void (void).

Using int (int) Using int (void) Using void (void)

It would be nice if you could hide those function calls as they are just part of the function prologue anyway, but that would probably be best left as an issue for Ghidra.