ghidra icon indicating copy to clipboard operation
ghidra copied to clipboard

Decompiler: variable-size array on stack yields invalid decompilation results

Open pieceofsummer opened this issue 5 years ago • 3 comments

Describe the bug Variable-size array introduces junk assignment instructions in the code; functions taking it as an argument are called with incorrect number of arguments (and it is impossible to remove extra arg by providing signature override).

To Reproduce Steps to reproduce the behavior:

  1. Create a test program:
void memcopy(char *dst, const char *src, int len) {
    for (int i = 0; i < len; i++)
        dst[i] = src[i];
}

int test(const char *value, int len) {
    char buffer[len];
    memcopy(buffer, value, len);
    return 0;
}

int main(int argc, const char * argv[]) {
    test("Hello World!", 12);
    return 0;
}
  1. Compile: gcc test.cpp -o test -fno-stack-protector -O1
  2. Import and decompile.
  3. Navigate to test function.

Expected behavior No junk assignment lines, and memcopy is called with 3 arguments

Screenshots Screenshot 2019-12-15 at 21 33 31

NOPing stack decrement instruction fixes number of arguments passed to memcopy: Screenshot 2019-12-15 at 21 37 52

Environment (please complete the following information):

  • OS: macOS 10.15.2
  • Java Version: 12.0.1
  • Ghidra Version: 9.1

Additional context Example program above is built on Linux, but clang on macOS produces similar result.

pieceofsummer avatar Dec 15 '19 19:12 pieceofsummer

After some poking around, it turns out assigning register value for length argument works in some cases.

For example, setting ESI = 12 at the function start works, even though it is immediately undefined after PUSH EBP: Screenshot 2019-12-16 at 03 02 44

On the contrary, setting it only for the relevant instructions doesn't seem to have any effect: Screenshot 2019-12-16 at 03 03 51

Seems like I'm having troubles understanding how register values work. Is this the expected behavior?

Also, anything more complex than just SUB RSP,RAX doesn't seem to work at all, e.g.

MOV        RDI,RSP
SUB        RDI,RAX
MOV        RSP,RDI

pieceofsummer avatar Dec 16 '19 01:12 pieceofsummer

This also seems to influence Rust decompiling, where a "and rsp, X" is used to align the stack. Patch out the and rsp, X gives the correct result. I will do more debug and source reading to see why this happens..

Escapingbug avatar May 07 '21 08:05 Escapingbug

Related to #6002, which seems to report the same error, though the function arguments are correct in the example in issue #6002.

LukeSerne avatar May 29 '25 10:05 LukeSerne