ghidra icon indicating copy to clipboard operation
ghidra copied to clipboard

function parameter default/fallback datatype

Open mumbel opened this issue 5 years ago • 6 comments
trafficstars

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.

  1. When adding new function arguments using the "edit function signature" window, clicking plus creates a new undefined
  2. 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 a undefined4 or undefined4 * 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)

mumbel avatar Aug 24 '20 17:08 mumbel

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()').

ghidra1 avatar Aug 24 '20 22:08 ghidra1

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.

mumbel avatar Aug 24 '20 22:08 mumbel

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.

astrelsky avatar Aug 25 '20 01:08 astrelsky

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.

ghidra1 avatar Aug 26 '20 21:08 ghidra1

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

mumbel avatar Apr 14 '22 17:04 mumbel

This is still a constant annoyance for functions that don't pick up their arguments

mumbel avatar Dec 08 '23 18:12 mumbel

@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.

ghidra1 avatar Jan 02 '24 19:01 ghidra1