NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
52.29k stars 5.92k forks source link

ARM:LE:32:v4t/GBA: "return in_lr;" #7248

Closed H-A-M-G-E-R closed 4 hours ago

H-A-M-G-E-R commented 20 hours ago

When Ghidra 11.2.1 decompiles a function to:

undefined4 func(void) {
    undefined4 in_lr;

    ...
    return in_lr;
}

while the assembly looks like this:

push       {lr}
...
pop        {r0}
bx         r0
-- Flow Override: RETURN (TERMINATOR)

the expected behavior should look like this:

void func(void) {
    ...
    return;
}
astrelsky commented 18 hours ago

This is most likely a bug in whatever compiler spec you are using, or you are using the wrong compiler spec.

DualTachyon commented 17 hours ago

If the function doesn't return a value, then change the type of return to "void". Ghidra makes guesses at function signatures, it doesn't always get them right and it is the user's job to fix the signatures and then commit them.

H-A-M-G-E-R commented 14 hours ago

The compiler that's commonly used in GBA games is agbcc: https://github.com/pret/agbcc, and the code provided above is what agbcc generates, so it's Ghidra's bug, not agbcc's bug. bx r0 returns void while bx r1 returns the value in r0.

DualTachyon commented 8 hours ago

There is no bug if you change the type of return to void. The code that Ghidra generated is correct for the disassembly provided. You may not like, but it is correct and like mentioned in other issues, Ghidra can't easily tell what the original did. You can fix it by changing the return type, but if you don't want to, that is your loss.

Ghidra doesn't know about agbcc, nor is it supposed to. Most other ARM compilers don't generate such weird code patterns, so the issue isn't ghidra.

You were given a way to fix it, so use it.

ryanmkurtz commented 4 hours ago

@H-A-M-G-E-R it is not realistic to expect Ghidra to get everything 100% correct. That is why Ghidra and tools like Ghidra are interactive...there is an expectation that the reverse engineer needs to tweak things here and there. If you are finding things wrong all over the place, you will most likely need to take advantage of the fact that Ghidra is an open source reverse engineering framework, and implement your own support for agbcc, including a compiler spec like @astrelsky mentioned. The Ghidra team currently has no plans to provide specific support for this compiler. If you feel like improved agbcc support can help the greater community, i recommend you develop your own Ghidra Extension to enabled improved support.