Hex-Rays' blog

Igor’s Tip of the Week #120: Set call type – Hex Rays

Written by Igor Skochinsky | Dec 22, 2022

Previously we’ve described how to use available type info to make decompilation of calls more precise when you have type information, but there may be situations where you don’t have it or the existing type info does not quite match the actual call arguments, and you still want to adjust the decompiler’s guess.

One common example is variadic functions (e.g. printf, scanf and several others from the C runtime library, as well as custom functions specific to the binary being analyzed). The decompiler knows about the standard C functions and tries to analyze the format string to guess the actually passed arguments. However, such guessing can still fail and show wrong arguments being passed.

For simple situations, adjusting variadic arguments may work, but it’s not always enough. For example, some calling conventions pass floating-point data in different registers from integers, so the decompiler needs to know which arguments are floating-point and which are not. You can, of course, change the prototype of the function to make the additional arguments explicit instead of variadic, but this affects all call sites instead of just the one you need.

Another difficulty can arise when dealing with the scanf family functions. Because the variadic arguments to such functions are usually passed by address, any variable type may be used for a specific format specifier. Consider the following example source code:

struct D
{
  int d;
  int e;
};


#include 
int main()
{
 D d;
 scanf("%d", &d.d);
}

When we decompile the compiled binary, even after creating the struct and changing the local variable type, the following output is shown:

We get &d instead of &d.d because d is situated at the very start of the structure so both expressions are equivalent on the binary level. To get the desired expression, we need to hint the decompiler that the extra argument is actually an int *. This can be done using the “Set call type…” action from the context menu on the call site:

We can explicitly specify type of the extra argument:

The decompiler takes it into account and uses the proper expression to match the new prototype:

See also: Hex-Rays interactive operation: Set call type