Latest available version: IDA and decompilers v8.4.240320 see all releases
Hex-Rays logo State-of-the-art binary code analysis tools
email icon

When you need to change the prototype of a function in the decompiler, the standard way is to use the “Set item type…” action (shortcut Y).

One case where you may need to do it is to add or remove arguments. Especially in embedded code or when decompiling variadic functions, the decompiler may deduce the argument list wrongly. A good test for bogus arguments is to check whether they’re referenced in the function’s body. For this, use “Jump to xref” (shortcut X) on the argument:

If there are no references to an argument, it’s likely that it (and probably the following ones) are fake. You can remove them by editing the prototype, but there is an easier way: “Remove function argument” action (shortcut ShiftDel).

Deleting return value

In the absence of reliable information to the contrary, the decompiler assumes that a function returns something and produces the pseudocode accordingly, which can lead to unoptimized or awkward output. For example, consider this small function from an ARM firmware:

_BYTE *sub_25C4()
{
  char CPSR; // r1
  _BYTE *result; // r0

  CPSR = __get_CPSR();
  __get_CPSR();
  __disable_irq();
  result = &byte_10001E5C;
  if ( !byte_10001E5C )
  {
    unk_100014CC = (CPSR & 1) == 0;
    byte_10001E5C = 1;
  }
  return result;
}

Because an intermediate address is stored in the register R0 (the standard return value register on ARM), and decompiler assumes that the function returns a value, which leads to awkward-looking code.  Since here it seems to be an incorrect assumption, we can remove the return value in the same fashion as the arguments:

The pseudocode gets updated with the new assumption and the return statement is gone:

void __fastcall sub_25C4()
{
  char CPSR; // r1

  CPSR = __get_CPSR();
  __get_CPSR();
  __disable_irq();
  if ( !byte_10001E5C )
  {
    unk_100014CC = (CPSR & 1) == 0;
    byte_10001E5C = 1;
  }
}

In addition to removing return value using the context action on it, you can use a shortcut which works anywhere in the function: CtrlShiftR. It can also be use to re-introduce a return value to a void function.

If you prefer a different shortcut, look for AddRemoveReturn in the shortcut editor:

See also:

Igor’s tip of the week #42: Renaming and retyping in the decompiler