This error is not very common but may appear in some situations.
Such errors happen when there is a function call in the code, but the decompiler fails to convert it to a high-level function call, e.g.:
- the target function’s prototype is wrong;
- the decompiler failed to figure out the function arguments: how many of them, or how exactly they’re being passed to the callee;
- the usage of the stack by the call does not make sense.
Let’s look at some examples where it happens and how to fix it.
Wrong function info
The first action on seeing the error should be to inspect the address mentioned and the surrounding code. For example, here’s the snippet around the address in the first screenshot:
.text:0804D5CD push [ebp+var_10] .text:0804D5D0 push offset sub_804D6E8 .text:0804D5D5 push [ebp+var_28] .text:0804D5D8 push offset sub_804CF24 ; oset .text:0804D5DD call sub_8058FF0 .text:0804D5E2 mov edx, [ebp+var_14] .text:0804D5E5 or dword ptr [edx+28h], 10h .text:0804D5E9 mov eax, [ebp+var_18] .text:0804D5EC add esp, 10h .text:0804D5EF test eax, eax .text:0804D5F1 jz loc_804D1D3 .text:0804D5F7 sub esp, 0Ch .text:0804D5FA push [ebp+var_18] .text:0804D5FD call sub_8055A0C
At the first glance, there doesn’t seem to be anything unusual: four arguments are pushed on the stack before calling the function sub_8058FF0. However, if we go inside the function and try to decompile it, we get another error:
Also, the header of the function looks strange:
.text:08058FF0 ; =============== S U B R O U T I N E ======================================= .text:08058FF0 .text:08058FF0 ; Attributes: bp-based frame .text:08058FF0 .text:08058FF0 ; int __cdecl sub_8058FF0(sigset_t oset) .text:08058FF0 sub_8058FF0 proc near ; CODE XREF: sub_804CF6C+671↑p .text:08058FF0 ; sub_804F798+126↑p ... .text:08058FF0 .text:08058FF0 var_48 = dword ptr -48h .text:08058FF0 oset = sigset_t ptr -38h
I.e. the function was detected not to take four arguments, but one structure by value. While this can indeed happen in some cases, the argument is in a wrong location: the local variables area (note the negative offset).
Fixing the function itself is a topic for another post, but a quick fix for the original issue would be to delete the current prototype and let the decompiler fall back to guessing the arguments. For this, put the cursor on the function name or its first line, then press Y (edit type), Del, Enter. This will clear the wrong prototype and decompilation should succeed, showing the four arguments we’ve seen in the disassembly:
Sometimes the decompiler’s guessing of the prototype still fails, so try to specify one based on the actual arguments being passed to the call (look at the assembly around the call). In some cases this may require the
__usercall calling convention.
Instead of the direct function address, indirect calls use a register or a memory location which holds the destination address to perform the call. For example, on x86 it may look like one of the following:
call eax call dword ptr [edx+14h] call [ebp+arg_0] call g_myfuncptr
In rare cases, the decompiler may fail to detect the actual arguments being passed to the call, especially if optimizer interleaves arguments passed to different calls. In that case, you can give it a hint by adding a cross-reference to the actual function being called (if you know it), or a function of the matching type, for example using the Set callee address feature. You should also check that the stack pointer is properly balanced before and after each call for stack-using calling conventions.