ghidra
ghidra copied to clipboard
function parameter default/fallback datatype
9.1.2
I have seen issues with this in two places so far that seem like a better default type could be used. I didn't see any configuration options for this sort of thing. These are probably 2 separate issues, just both come back to the undefined type.
- When adding new function arguments using the "edit function signature" window, clicking plus creates a new
undefined - Assume a function prototype is using a type pointer, and the type is deleted, the usage of this type pointer is changed to
undefined(assume analyze originally detected as aundefined4orundefined4 *in a 32-bit setup).
It seems in these cases defaulting to an undefined type of register size would be more appropriate.
(the separate issue may be in the 2nd case if the SourceType is still USER_DEFINED or ANALYSIS, maybe should be switched back to DEFAULT)
The 'undefined' type is used by the decompiler as a signaling mechanism which allow the type to float based upon its analysis. Any other type will be treated as locked-in even if it is incorrect. This is true even if it is smaller than the containing register.
The variable symbol SourceType is more a reflection of the symbols name while the signature SourceType is a collective indicator for the signature as a whole. It is unclear when it would be safe to revert the signature SourceType. Setting the SourceType back to DEFAULT on a variable would require the name to revert its default (e.g., null). I don't think reverting a variable symbol to a DEFAULT SourceType has much impact on the decompiler. It would be very simply to write a GhidraScript which would revert the current functions signature SourceType to DEFAULT (see 'Function.setSignatureSource()').
just to be clear when you said undefined you mean only undefined and not undefined2/4/8?
my issue is in these 2 cases it doesn't float the type that makes sense from analysis as it looks like its been committed as an undefined.
for example on my 1, if i find something like a memcpy and the 3rd arg didn't get picked up, if i'm not paying attention when adding the third argument it will be undefined when clicking +. The code would be memcpy(dst, src, 0x100) but the decompiler will show memcpy(dst, src, 0)
then on my example 2, I made a struct and started assigned it to a bunch of prototypes only to find after manually setting 20-30 functions, what i thought was a ->next like pointer was a different struct, so of my 20-30 prototype (not counting what got picked up by ghidra), N were wrong. So I deleted the structs to start them over to make sure I didn't confuse the two. Now the 20-30 prototypes were undefined and the decompiler became full of (char) / _0_1 / SUB41() / CONCAT. with undefined4 at least the decompiler won't be thrashing on downcasts and upcasts.
It would be helpful if the sized undefines would float yet keep the set size. It would prevent potential 32 bit pointers from being extended to 64 bits.
The decompiler treats all undefined types (including those that are sized) as a means of allowing the datatype to float for that variable. The associated storage dictates the size constraint which may impact the ability to float the datatype. Example: an undefined2 on a variable which corresponds to a 32-bit pointer will likely remain as undefined2 since the storage is insufficient for a 32-bit pointer.
A non-DEFAULT function signature source will lock-in the number of parameters, storage locations, any associated non-undefined datatypes and any non-default names. A parameter with invalid storage will be ignored. The return will float both storage and datatype if undefined. A DEFAULT signature source will ignore of this and float the entire signature.
This is still breaking for me
- I have a FUN_AAAAAAAA() that the caller function recognized has 5 params passed in
- I go into FUN_AAAAAAAA and see
undefined * FUN_AAAAAAAA(void) - I edit function signature and click
+5 times - I click OK
- The function now has references to the 5 params as
CONCAT31(in_register_XXXXXXXX, param_Y)
They do not float as you suggest, they are 1 byte. why is an argument not defaulted to the register size if the undefined argument doesn't float? So this is either broken because they don't float as you're saying or the undefined is commited when I click OK and undefined is a terrible default and the code would be cleaner as undefinedN (N==register size).
Not sure why decompiler doesn't detect, but if the decompiler were to detect, in the other cases I'm looking at they would be undefined4
This is still a constant annoyance for functions that don't pick up their arguments
@mumbel This may also be affected by the Signature SourceType which gets set to USER when you modify via the Function Editor. It appears types are locked when this souce type is not DEFAULT. You can add this field to the Function display within the listing. Unfortunetly, the ability to directly maniulate this setting via the GUI is not provided. You could experiment with a script which forces it back to DEFAULT for a selected Function.