ghidra icon indicating copy to clipboard operation
ghidra copied to clipboard

DecompiledFunction: Missing space between return type and function name in function signature

Open tklink opened this issue 7 months ago • 2 comments

Bug description Sometimes the text returned by getSignature doesn't contain a whitespace between the return value and the function name. For the same project this behavirour is reproducible but I haven't found any regularity so I don't know what's specific in functions where this occurs. For most functions the signature is OK.

How to reproduce The standard Python/Jython code fragment is used:

...
decompiled_function = result.getDecompiledFunction()
signature = decompiled_function.getSignature()

And while the result of getC is correct, the result of getSignature is not, see below.

Expected behavior The signature should always be syntactically correct, i.e. there has to be a whitespace between the return type and the function name.

Screenshots The decompiled code is correct in Ghidra GUI.

Image

The returned signature is not:

void __regparm3@ExFATFindNextEx@24(undefined4 param_1,byte *param_2,undefined4 *param_3,byte *param_4,int param_5,char *param_6,uint *param_7);

Please note the missing space before the first @.

Attachments None

Environment (please complete the following information):

  • OS: Windows 11 Pro (10.0.26100)
  • Java Version: 23.0.2
  • Ghidra Version: 11.3.2
  • Ghidra Origin: official GitHub zip file

Additional context None

tklink avatar Apr 24 '25 06:04 tklink

Probably because of this code in ClangTokenGroup.java:

if (lastTokenStr != null && isLetterDigitOrUnderscore(tokenStr.charAt(0)) &&
	isLetterDigitOrUnderscore(lastTokenStr.charAt(lastTokenStr.length() - 1))) {
	// avoid concatenating names together
	buffer.append(' ');
}

Meanwhile, @ is neither letter, digit nor underscore.

msm-code avatar Apr 25 '25 22:04 msm-code

It is also interesting that while strange characters (such as '@') are correctly converted to allowed C characters in the decompiled code returned by getC, they are not converted in the signature returned by getSignature so the function prototype doesn't match the function implementation. See the example:

getC

char * __regparm3 _MkExFATName_8(undefined4 param_1, ...)
{
    ....
}

getSignature

char * __regparm3 @MkExFATName@8(undefined4 param_1, ...);

tklink avatar Apr 26 '25 06:04 tklink

@tklink Can you supply the binary where this happens? Thanks!

ghidra007 avatar Aug 07 '25 15:08 ghidra007